fix(server): validate low-level tool inputs - #2634
Conversation
@modelcontextprotocol/client
@modelcontextprotocol/codemod
@modelcontextprotocol/core
@modelcontextprotocol/server
@modelcontextprotocol/server-legacy
@modelcontextprotocol/express
@modelcontextprotocol/fastify
@modelcontextprotocol/hono
@modelcontextprotocol/node
commit: |
pacocartones
left a comment
There was a problem hiding this comment.
Verify pass on the current head — no blocking findings.
I reproduced the issue independently against the published @modelcontextprotocol/sdk@1.30.0: the low-level Server runs a tools/call handler with arguments that violate the tool's declared inputSchema (e.g. code: 12345 against {code: string, required}) with no protocol error, while McpServer rejects the identical call with -32602: Input validation error: Invalid arguments for tool …. This PR closes exactly that gap.
Checked against the code rather than the description:
- Schemas are captured from the validated
tools/listresult (validateResultbefore_rememberToolInputSchemas), so an invalidtools/liststill fails wire validation — the seam does not trust an unvalidated handler response. - The rejection surface mirrors the high-level path (
isError: true+Input validation error: Invalid arguments for tool ${toolName}: …), so clients see one consistent error shape. - Servers without a declared schema are untouched (
_toolInputValidatorsonly populated from declared schemas; thecatcharound a malformed schema preserves prior behavior). - The
highLevelServersguard against double validation is the right call:McpServervalidates via Standard Schema, which may intentionally differ from the advertised JSON Schema (coercion).
Non-blocking notes:
- The validator runs against the schema recorded at the last
tools/list; if a server changes schemas between requests the map is refreshed on each list, so this is fine — worth a line in the docs for readers, though. - The
ServerOptions.jsonSchemaValidatordocstring was updated to mention tool inputs, butdocs/advanced/may still describe it as elicitation-only; a one-line docs sync would avoid confusion.
The CI surface (build, client/server conformance, tests) is green on the current head.
|
Thanks for the careful verification. I checked the current head The schema map is refreshed from each validated |
🦋 Changeset detectedLatest commit: e5571a6 The changes in this PR will be included in the next version bump. This PR includes changesets to release 6 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Fixes #2628
Summary
Verification
Passed:
The repository-wide pnpm test:all run was blocked by two existing examples/shared tests because the local environment could not load the better-sqlite3 native binding. The server, client, core, and middleware test suites completed successfully.