Tool input schema appears in annotations instead of inputSchema in tools/list response
Describe the bug When registering a tool with a valid JSON Schema using the documented SDK pattern, the tools/list response puts the schema in annotations instead of inputSchema. This breaks compatibility with the MCP Inspector and other clients that expect the schema in inputSchema.
To Reproduce Steps to reproduce the behavior:
- import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js'; import express from 'express';
const server = new McpServer({ name: 'test', version: '1.0.0' });
server.tool('sf_connect', 'Connect to Salesforce', { type: "object", properties: { username: { type: 'string', description: "Salesforce username" }, password: { type: 'string', description: "Salesforce password" } }, required: ["username", "password"] }, async ({ username, password }) => ({ status: 'ok', username }));
const app = express(); app.use(express.json()); app.post('/mcp', async (req, res) => { const transport = new StreamableHTTPServerTransport({}); await server.connect(transport); await transport.handleRequest(req, res, req.body); }); app.listen(3000, () => console.log('Listening on 3000'));
Start the server above.
Send an initialize request:
curl -X POST http://localhost:3000/mcp
-H "Content-Type: application/json"
-H "Accept: application/json, text/event-stream"
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"1.0","capabilities":{},"clientInfo":{"name":"curl","version":"1.0"}}}'
Send a tools/list request:
curl -X POST http://localhost:3000/mcp
-H "Content-Type: application/json"
-H "Accept: application/json, text/event-stream"
-d '{"jsonrpc":"2.0","id":2,"method":"tools/list"}'
Actual Response: { "result": { "tools": [ { "name": "sf_connect", "description": "Connect to Salesforce", "inputSchema": { "type": "object" }, "annotations": { "type": "object", "properties": { "username": { "type": "string", "description": "Salesforce username" }, "password": { "type": "string", "description": "Salesforce password" } }, "required": ["username", "password"] } } ] }, "jsonrpc": "2.0", "id": 2 }
Expected behavior { "result": { "tools": [ { "name": "sf_connect", "description": "Connect to Salesforce", "inputSchema": { "type": "object", "properties": { "username": { "type": "string", "description": "Salesforce username" }, "password": { "type": "string", "description": "Salesforce password" } }, "required": ["username", "password"] } } ] }, "jsonrpc": "2.0", "id": 2 }
Logs If applicable, add logs to help explain your problem.
Additional context Node.js: v20.0.0 (also tested with v23.11.0) @modelcontextprotocol/sdk: 1.12.0 (also tested with 1.11.5) OS: macOS (please specify your version)
No custom protocol handlers or legacy code. Clean install, minimal code, and correct tool registration. This breaks Inspector and other MCP clients that expect the schema in inputSchema.