From a201b1f11389891cc5dbf6d92bb02b89d2412d42 Mon Sep 17 00:00:00 2001 From: Akshay Dodeja Date: Sat, 17 Oct 2026 01:30:51 -0700 Subject: [PATCH] fix(ci): compare advertised MCP tools with the feature map --- packages/mcp/scripts/protocol-smoke.mjs | 18 ++++++++++++------ packages/mcp/src/protocol-compat.test.ts | 13 +++++++++++-- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/packages/mcp/scripts/protocol-smoke.mjs b/packages/mcp/scripts/protocol-smoke.mjs index 61f424507..d768f14fd 100644 --- a/packages/mcp/scripts/protocol-smoke.mjs +++ b/packages/mcp/scripts/protocol-smoke.mjs @@ -3,8 +3,17 @@ import { StreamableHTTPClientTransport, } from '@modelcontextprotocol/client'; import { createMcpHandler } from '@modelcontextprotocol/server'; +import { readFileSync } from 'node:fs'; import { createTerminal49McpServer } from '../dist/server.js'; +const featureMap = JSON.parse( + readFileSync( + new URL('../../../skills/agent-trust/feature-map.json', import.meta.url), + 'utf8', + ), +); +const expectedToolNames = featureMap.mcpTools.map((tool) => tool.name).sort(); + const protocolVersion = process.env.MCP_PROTOCOL_VERSION; if (!protocolVersion) { throw new Error('MCP_PROTOCOL_VERSION is required'); @@ -67,13 +76,10 @@ try { } const { tools } = await client.listTools(); - if ( - tools.length !== 14 || - !tools.some((tool) => tool.name === 'search_docs') || - !tools.some((tool) => tool.name === 'whoami') - ) { + const toolNames = tools.map((tool) => tool.name).sort(); + if (JSON.stringify(toolNames) !== JSON.stringify(expectedToolNames)) { throw new Error( - `Expected 14 tools including search_docs and whoami over ${protocolVersion}, received ${tools.length}`, + `MCP tools/list differs from skills/agent-trust/feature-map.json over ${protocolVersion}. Expected ${JSON.stringify(expectedToolNames)}, received ${JSON.stringify(toolNames)}`, ); } diff --git a/packages/mcp/src/protocol-compat.test.ts b/packages/mcp/src/protocol-compat.test.ts index d13b3a669..0fc56e245 100644 --- a/packages/mcp/src/protocol-compat.test.ts +++ b/packages/mcp/src/protocol-compat.test.ts @@ -53,6 +53,15 @@ const MCP_DOCS = readFileSync( 'utf8', ); +const MCP_TOOL_NAMES: string[] = JSON.parse( + readFileSync( + new URL('../../../skills/agent-trust/feature-map.json', import.meta.url), + 'utf8', + ), +) + .mcpTools.map((tool: { name: string }) => tool.name) + .sort(); + function documentedToolSection(toolName: string): string { const marker = `### \`${toolName}\``; const start = MCP_DOCS.indexOf(marker); @@ -174,7 +183,7 @@ describe('MCP protocol compatibility', () => { ]), ); - expect(tools).toHaveLength(14); + expect(tools.map((tool) => tool.name).sort()).toEqual(MCP_TOOL_NAMES); for (const tool of tools) { expect(tool.name.length, tool.name).toBeLessThanOrEqual(64); expect(tool.inputSchema.properties, tool.name).not.toHaveProperty( @@ -306,7 +315,7 @@ describe('MCP protocol compatibility', () => { client.listResourceTemplates(), ]); - expect(tools).toHaveLength(14); + expect(tools.map((tool) => tool.name).sort()).toEqual(MCP_TOOL_NAMES); expect(prompts).toHaveLength(3); expect(resources).toHaveLength(3); expect(resourceTemplates).toHaveLength(1);