Symptom
The stock showcase boot banner advertises "MCP server — connect a coding agent: Endpoint …/api/v1/mcp", yet both /mcp and /mcp/skill answer 501 "MCP server is not available".
- Observed: banner promises the MCP surface;
/mcp and /mcp/skill both 501.
- Expected: the MCP surface the banner promises (keyed
initialize/tools/list, /mcp/skill 200).
Root cause
serve.ts auto-adds mcp to requires when the MCP server is enabled (packages/cli/src/commands/serve.ts:884), and CAPABILITY_PROVIDERS.mcp declares nameMatch: ['mcp-server', 'MCPServerPlugin', 'mcp'] (serve.ts:427). hasPluginMatching (serve.ts:2327) does substring matching over loaded plugin names:
const hasPluginMatching = (fragments) =>
plugins.some((p) => {
const n = String(p?.name ?? '');
const c = String(p?.constructor?.name ?? '');
return fragments.some((f) => n.includes(f) || c.includes(f));
});
The showcase loads com.objectstack.connector.mcp — the outbound MCP client connector — whose name contains the substring mcp. So the resolver concludes the mcp capability is already provided and never loads MCPServerPlugin.
Proven: removing only ConnectorMcpPlugin from a scratch copy makes [MCP] Plugin initialized appear and /mcp/skill answer 200; @objectstack/mcp was resolvable from the CLI the whole time.
The general hazard is a substring match between a provider plugin name and a consumer plugin name: a consumer whose name contains the provider's fragment satisfies the provider's nameMatch, suppressing the real provider. Still present on origin/main (serve.ts:427 and the .includes(f) in hasPluginMatching at 2327-2332).
Reproduction
Boot the stock showcase; curl the advertised endpoint:
curl http://<host>/api/v1/mcp/skill
Expected the MCP surface the banner promises. Actual 501 "MCP server is not available".
Source
Extracted from the QA run #7627 (framework 92f26f7, console 6314e87f).
Symptom
The stock showcase boot banner advertises "MCP server — connect a coding agent: Endpoint …/api/v1/mcp", yet both
/mcpand/mcp/skillanswer 501 "MCP server is not available"./mcpand/mcp/skillboth 501.initialize/tools/list,/mcp/skill200).Root cause
serve.tsauto-addsmcptorequireswhen the MCP server is enabled (packages/cli/src/commands/serve.ts:884), andCAPABILITY_PROVIDERS.mcpdeclaresnameMatch: ['mcp-server', 'MCPServerPlugin', 'mcp'](serve.ts:427).hasPluginMatching(serve.ts:2327) does substring matching over loaded plugin names:The showcase loads
com.objectstack.connector.mcp— the outbound MCP client connector — whose name contains the substringmcp. So the resolver concludes themcpcapability is already provided and never loadsMCPServerPlugin.Proven: removing only
ConnectorMcpPluginfrom a scratch copy makes[MCP] Plugin initializedappear and/mcp/skillanswer 200;@objectstack/mcpwas resolvable from the CLI the whole time.The general hazard is a substring match between a provider plugin name and a consumer plugin name: a consumer whose name contains the provider's fragment satisfies the provider's
nameMatch, suppressing the real provider. Still present onorigin/main(serve.ts:427and the.includes(f)inhasPluginMatchingat 2327-2332).Reproduction
Boot the stock showcase;
curlthe advertised endpoint:Expected the MCP surface the banner promises. Actual 501 "MCP server is not available".
Source
Extracted from the QA run #7627 (framework 92f26f7, console 6314e87f).