Fix tools-name-format for spec Tool Names SHOULD rules on 2025-11-25+ (#380)

* fix(tools-list): align tools-name-format with 2025-11-25 spec prose

Enforce dated spec Tool Names SHOULD rules (128 max, no slash), WARNING
severity, 2025-11-25+ gate, negative fixture, and core-spec specReferences.

Fixes #379

* test(tools-list): cast Connection.request mock for tsgo typecheck

* test(tools-list): pin WARNING to offending tool name in negative test

* test(tools-list): rename negative fixture to invalid-tool-names

Document SEP-986 markdown vs integrated spec divergence in fixture header.

* chore: trim explanatory comments to the essentials

Keep the rule statement and the note that the dated spec (not the SEP-986
markdown) is authoritative; drop the process narration.

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: triage <paulc@anthropic.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Paul Carleton <paulcarletonjr@gmail.com>
This commit is contained in:
dylan 2026-09-06 13:05:26 -07:00 • committed by GitHub
commit 0d824aebd8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -0,0 +1,68 @@
#!/usr/bin/env node
/**
* Negative fixture for the tools-name-format check: advertises tool names that
* violate the 2025-11-25 Tool Names rules (spec #tool-names) by bypassing the
* SDK's registerTool validation, so the check can be shown to emit WARNING.
*/
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
import { ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
import express from 'express';
function createServer() {
const server = new Server(
{ name: 'invalid-tool-names', version: '1.0.0' },
{ capabilities: { tools: {} } }
);
server.setRequestHandler(ListToolsRequestSchema, async () => ({
tools: [
{
name: 'bad tool name',
description: 'Deliberately invalid tool name for conformance testing',
inputSchema: { type: 'object' }
},
{
name: 'valid_tool',
description: 'A conformant tool name',
inputSchema: { type: 'object' }
}
]
}));
return server;
}
const app = express();
app.use(express.json());
app.post('/mcp', async (req, res) => {
try {
const server = createServer();
const transport = new StreamableHTTPServerTransport({
sessionIdGenerator: undefined
});
await server.connect(transport);
await transport.handleRequest(req, res, req.body);
} catch (error) {
if (!res.headersSent) {
res.status(500).json({
jsonrpc: '2.0',
error: {
code: -32603,
message: `Internal error: ${error instanceof Error ? error.message : String(error)}`
},
id: null
});
}
}
});
const PORT = parseInt(process.env.PORT || '3009', 10);
app.listen(PORT, '127.0.0.1', () => {
console.log(
`Invalid tool names negative test server running on http://localhost:${PORT}/mcp`
);
});