mcp-prime-resource.test.mjs
113 lines 4.4 KB
Raw
sha256:65ccb454656ea5acdea0a10e559b78bcde1eb6ff753ecc2911bc99d1c3d7cadd feat(calendar): enforce agent context tiers in retrieval AP… Human minor ⚠ breaking 1 day ago
1 /**
2 * MCP bootstrap resource knowtation://prime (self-hosted) and knowtation://hosted/prime (hosted).
3 */
4 import { describe, it } from 'node:test';
5 import assert from 'node:assert/strict';
6 import path from 'path';
7 import { fileURLToPath } from 'url';
8 import { Client } from '@modelcontextprotocol/sdk/client/index.js';
9 import { InMemoryTransport } from '@modelcontextprotocol/sdk/inMemory.js';
10
11 const __dirname = path.dirname(fileURLToPath(import.meta.url));
12 const fixtureVault = path.join(__dirname, 'fixtures', 'vault-fs');
13 process.env.KNOWTATION_VAULT_PATH = fixtureVault;
14
15 const { createKnowtationMcpServer } = await import('../mcp/create-server.mjs');
16 const { createHostedMcpServer } = await import('../hub/gateway/mcp-hosted-server.mjs');
17
18 const CANISTER_URL = 'http://canister.prime.test:4322';
19 const BRIDGE_URL = 'http://bridge.prime.test:4321';
20
21 describe('MCP prime resource', () => {
22 it('self-hosted readResource knowtation://prime returns schema and token_layers', async () => {
23 process.env.KNOWTATION_VAULT_PATH = fixtureVault;
24 const mcpServer = createKnowtationMcpServer();
25 const client = new Client({ name: 'prime-local', version: '0.0.1' });
26 const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();
27 await mcpServer.connect(serverTransport);
28 await client.connect(clientTransport);
29 try {
30 const read = await client.readResource({ uri: 'knowtation://prime' });
31 assert.equal(read.contents.length, 1);
32 assert.equal(read.contents[0].mimeType, 'application/json');
33 const j = JSON.parse(read.contents[0].text);
34 assert.equal(j.schema, 'knowtation.prime/v1');
35 assert.equal(j.surface, 'self-hosted');
36 assert.equal(j.prime_uri, 'knowtation://prime');
37 assert.ok(j.config && typeof j.config === 'object');
38 assert.ok(Array.isArray(j.suggested_next_resources));
39 assert.ok(j.token_layers?.vault_retrieval);
40 assert.ok(j.token_layers?.terminal_tooling);
41 } finally {
42 await client.close();
43 }
44 });
45
46 it('hosted readResource knowtation://hosted/prime lists prompts for role', async () => {
47 const origFetch = globalThis.fetch;
48 globalThis.fetch = async () => ({
49 ok: true,
50 status: 200,
51 json: async () => ({}),
52 text: async () => '{}',
53 });
54 const mcpServer = createHostedMcpServer({
55 userId: 'actor-1',
56 canisterUserId: 'can-1',
57 vaultId: 'v1',
58 role: 'viewer',
59 token: 'tok',
60 canisterUrl: CANISTER_URL,
61 bridgeUrl: BRIDGE_URL,
62 });
63 const client = new Client({ name: 'prime-hosted', version: '0.0.1' });
64 const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();
65 await mcpServer.connect(serverTransport);
66 await client.connect(clientTransport);
67 try {
68 const read = await client.readResource({ uri: 'knowtation://hosted/prime' });
69 const j = JSON.parse(read.contents[0].text);
70 assert.equal(j.schema, 'knowtation.prime/v1');
71 assert.equal(j.surface, 'hosted');
72 assert.equal(j.session.vaultId, 'v1');
73 assert.equal(j.session.role, 'viewer');
74 assert.ok(Array.isArray(j.mcp_prompts_registered_for_role));
75 assert.ok(j.mcp_prompts_registered_for_role.includes('temporal-summary'));
76 assert.ok(!j.mcp_prompts_registered_for_role.includes('write-from-capture'));
77 } finally {
78 await client.close();
79 globalThis.fetch = origFetch;
80 }
81 });
82
83 it('hosted prime includes write-from-capture for editor', async () => {
84 const origFetch = globalThis.fetch;
85 globalThis.fetch = async () => ({
86 ok: true,
87 status: 200,
88 json: async () => ({}),
89 text: async () => '{}',
90 });
91 const mcpServer = createHostedMcpServer({
92 userId: 'a',
93 canisterUserId: 'c',
94 vaultId: 'v',
95 role: 'editor',
96 token: 't',
97 canisterUrl: CANISTER_URL,
98 bridgeUrl: BRIDGE_URL,
99 });
100 const client = new Client({ name: 'prime-ed', version: '0.0.1' });
101 const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();
102 await mcpServer.connect(serverTransport);
103 await client.connect(clientTransport);
104 try {
105 const read = await client.readResource({ uri: 'knowtation://hosted/prime' });
106 const j = JSON.parse(read.contents[0].text);
107 assert.ok(j.mcp_prompts_registered_for_role.includes('write-from-capture'));
108 } finally {
109 await client.close();
110 globalThis.fetch = origFetch;
111 }
112 });
113 });
File History 2 commits
sha256:65ccb454656ea5acdea0a10e559b78bcde1eb6ff753ecc2911bc99d1c3d7cadd feat(calendar): enforce agent context tiers in retrieval AP… Human minor 1 day ago
sha256:9103f98c89257ed2b01c237cea895dabb3e85ea337dccb1161c175e4422355b6 docs: accept Calendar Events v0 spec with Phase 0 security … Human 1 day ago