mcp-prime-resource.test.mjs
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