mcp-hosted-transcribe.test.mjs
115 lines 3.6 KB
Raw
sha256:65ccb454656ea5acdea0a10e559b78bcde1eb6ff753ecc2911bc99d1c3d7cadd feat(calendar): enforce agent context tiers in retrieval AP… Human minor ⚠ breaking 1 day ago
1 /**
2 * Hosted MCP transcribe tool: POST multipart to bridge /api/v1/import with source_type audio or video.
3 */
4
5 import { describe, it, beforeEach, afterEach } from 'node:test';
6 import assert from 'node:assert/strict';
7 import { Client } from '@modelcontextprotocol/sdk/client/index.js';
8 import { InMemoryTransport } from '@modelcontextprotocol/sdk/inMemory.js';
9 import { createHostedMcpServer } from '../hub/gateway/mcp-hosted-server.mjs';
10
11 const BRIDGE_URL = 'http://bridge.test:4321';
12 const CANISTER_URL = 'http://canister.test:4322';
13
14 function makeCtx(overrides = {}) {
15 return {
16 userId: 'u-1',
17 vaultId: 'v-1',
18 role: 'editor',
19 token: 'tok-test',
20 canisterUrl: CANISTER_URL,
21 bridgeUrl: BRIDGE_URL,
22 ...overrides,
23 };
24 }
25
26 function installFetchMock(json = { imported: [{ path: 'inbox/x.md' }], count: 1 }) {
27 const calls = [];
28 const origFetch = globalThis.fetch;
29 globalThis.fetch = async (url, init) => {
30 calls.push({ url: String(url), init });
31 return {
32 ok: true,
33 status: 200,
34 headers: { get: () => 'application/json' },
35 text: async () => JSON.stringify(json),
36 json: async () => json,
37 };
38 };
39 return {
40 calls,
41 restore() {
42 globalThis.fetch = origFetch;
43 },
44 };
45 }
46
47 async function connectPair(ctx) {
48 const mcpServer = createHostedMcpServer(ctx ?? makeCtx());
49 const client = new Client({ name: 'transcribe-test', version: '0.0.1' });
50 const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();
51 await mcpServer.connect(serverTransport);
52 await client.connect(clientTransport);
53 return { client, mcpServer };
54 }
55
56 describe('hosted MCP transcribe — bridge multipart', () => {
57 let mock;
58 let client;
59
60 beforeEach(() => {
61 mock = installFetchMock();
62 });
63
64 afterEach(async () => {
65 mock.restore();
66 try {
67 await client?.close();
68 } catch (_) {}
69 });
70
71 it('sends POST to {bridgeUrl}/api/v1/import with Authorization, X-Vault-Id, and source_type audio', async () => {
72 ({ client } = await connectPair());
73 const payload = Buffer.from('fake-audio', 'utf8').toString('base64');
74 await client.callTool({
75 name: 'transcribe',
76 arguments: { source_type: 'audio', file_base64: payload, filename: 'clip.m4a' },
77 });
78
79 assert.equal(mock.calls.length, 1);
80 assert.equal(mock.calls[0].url, `${BRIDGE_URL}/api/v1/import`);
81 assert.equal(mock.calls[0].init.method, 'POST');
82 const h = mock.calls[0].init.headers;
83 assert.equal(h['Authorization'], 'Bearer tok-test');
84 assert.equal(h['X-Vault-Id'], 'v-1');
85 const body = mock.calls[0].init.body;
86 assert.ok(body instanceof FormData);
87 assert.equal(body.get('source_type'), 'audio');
88 assert.ok(body.get('file'));
89 });
90
91 it('FormData uses source_type video when requested', async () => {
92 ({ client } = await connectPair(makeCtx({ role: 'admin' })));
93 const payload = Buffer.from('x', 'utf8').toString('base64');
94 await client.callTool({
95 name: 'transcribe',
96 arguments: { source_type: 'video', file_base64: payload, filename: 'clip.mp4', project: 'demo' },
97 });
98 const body = mock.calls[0].init.body;
99 assert.equal(body.get('source_type'), 'video');
100 assert.equal(body.get('project'), 'demo');
101 });
102
103 it('transcribe tool is not registered for viewer', async () => {
104 ({ client } = await connectPair(makeCtx({ role: 'viewer' })));
105 const res = await client.callTool({
106 name: 'transcribe',
107 arguments: {
108 source_type: 'audio',
109 file_base64: Buffer.from('x').toString('base64'),
110 filename: 'a.m4a',
111 },
112 });
113 assert.ok(res.isError);
114 });
115 });
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