Просмотр исходного кода

test(repository-plugin): cover MCP activation cleanup

Tianyi Cui 1 месяц назад
Родитель
Сommit
e91ff6d499

+ 54 - 0
packages/self-modification/repository-plugin/tests/repository-plugin.spec.ts

@@ -261,6 +261,60 @@ describe('prepared repository plugin Loader composition', () => {
     await ctx.fiber.dispose()
   })
 
+  it('mounts and removes tools discovered from a repository MCP server', async () => {
+    const root = await temporaryDirectory('mcp-loader-success')
+    const server = join(root, 'mcp-server.mjs')
+    await writeFile(server, [
+      "import { createInterface } from 'node:readline'",
+      'const lines = createInterface({ input: process.stdin })',
+      'for await (const line of lines) {',
+      '  const request = JSON.parse(line)',
+      "  if (!('id' in request)) continue",
+      '  let result',
+      "  if (request.method === 'initialize') {",
+      '    result = {',
+      '      protocolVersion: request.params.protocolVersion,',
+      '      capabilities: { tools: {} },',
+      "      serverInfo: { name: 'repository-fixture', version: '0.0.0' },",
+      '    }',
+      "  } else if (request.method === 'tools/list') {",
+      '    result = {',
+      '      tools: [{',
+      "        name: 'proof',",
+      "        description: 'Repository MCP proof.',",
+      "        inputSchema: { type: 'object', properties: {} },",
+      '      }],',
+      '    }',
+      '  } else {',
+      '    result = {}',
+      '  }',
+      "  process.stdout.write(`${JSON.stringify({ jsonrpc: '2.0', id: request.id, result })}\\n`)",
+      '}',
+      '',
+    ].join('\n'))
+    await writeFile(join(root, '.mcp.json'), JSON.stringify({
+      mcpServers: { online: { command: process.execPath, args: [server] } },
+    }))
+    const directory = await writePlugin(root, 'mcp-loader-success-fixture', { mcpServers: '../.mcp.json' })
+    await RepositoryPlugin.prepareDshPlugin(directory)
+
+    const ctx = new Context()
+    ctx.baseUrl = pathToFileURL(directory).href + '/'
+    await ctx.plugin(Loader)
+    await ctx.plugin(SystemPrompt)
+    await ctx.plugin(ToolRegistry)
+    await ctx.plugin(RepositoryPlugin)
+    const id = await ctx.loader.create({
+      name: pathToFileURL(join(directory, RepositoryPlugin.PREPARED_ENTRY_FILENAME)).href,
+    })
+    await ctx.loader.await()
+    expect(ctx.tools.get('mcp__online__proof')).toBeDefined()
+
+    await ctx.loader.remove(id)
+    expect(ctx.tools.get('mcp__online__proof')).toBeUndefined()
+    await ctx.fiber.dispose()
+  })
+
   it('fails an MCP repository plugin load when its declared server cannot connect', async () => {
     const root = await temporaryDirectory('mcp-loader')
     await writeFile(join(root, '.mcp.json'), JSON.stringify({