modelcontextprotocol / modelcontextprotocol/typescript-sdk
SEP-1303: Input validation errors should return Tool Execution Errors, not Protocol Errors
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 13.4k
- Forks
- 2.2k
- Avg merge
- 3d 15h
- Merged PRs (30d)
- 4
Description
Summary
SDK v1.29.0 still throws McpError(ErrorCode.InvalidParams, ...) when tool input validation fails, which conflicts with SEP-1303 (merged into spec 2025-11-25).
Per the 2025-11-25 changelog:
Clarify that input validation errors should be returned as Tool Execution Errors rather than Protocol Errors to enable model self-correction (SEP-1303).
Current SDK behavior prevents the agent model from seeing the error message and self-correcting.
Current Behavior
packages/sdk/src/server/mcp.ts (compiled: dist/esm/server/mcp.js:174-180):
const parseResult = await safeParseAsync(schemaToParse, args);
if (!parseResult.success) {
const error = 'error' in parseResult ? parseResult.error : 'Unknown error';
const errorMessage = getParseErrorMessage(error);
throw new McpError(
ErrorCode.InvalidParams,
`Input validation error: Invalid arguments for tool ${toolName}: ${errorMessage}`
);
}
Result to the client: JSON-RPC error -32602 InvalidParams (Protocol Error).
Expected Behavior (SEP-1303)
Return a successful CallToolResult with isError: true and the validation message in content:
{
"result": {
"content": [
{
"type": "text",
"text": "Input validation error for tool X: <Zod message>"
}
],
"isError": true
}
}
This lets the model see the error and retry with corrected arguments — exactly the motivation behind SEP-1303.
Scope
Only input validation should switch. Keep Protocol Errors for:
- Unknown tool (
-32602) — already correct, and SDK 2.0.0-alpha.1 reinforced this for unknown tools - Disabled tool — correct
- Structural JSON-RPC errors — correct
Impact
Any server built on this SDK is non-compliant with spec 2025-11-25 for this specific clause. MCPWebStore (Trusteed) hit this during a 2025-11-25 alignment audit — no workaround exists short of patching the SDK or wrapping every registerTool call with permissive input schemas and manual Zod validation inside the handler.
Suggested Fix
Transform the throw into a structured CallToolResult:
if (!parseResult.success) {
const errorMessage = getParseErrorMessage(
'error' in parseResult ? parseResult.error : 'Unknown error'
);
return {
content: [{
type: 'text',
text: `Input validation error for tool ${toolName}: ${errorMessage}`
}],
isError: true,
};
}
Same for the symmetric output validation check at line ~201 — though SEP-1303 language targets input validation primarily; output validation may warrant a separate decision.
References
- Spec 2025-11-25 changelog (minor change #5): https://modelcontextprotocol.io/specification/2025-11-25/changelog
- SEP-1303 discussion: https://github.com/modelcontextprotocol/modelcontextprotocol/issues/1303
- SDK source (v1.29.0):
src/server/mcp.ts(tool handler path inCallToolRequestSchema)
Happy to open a PR if maintainers confirm the direction.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in packages/sdk/src/server/mcp.ts at the CallToolRequestSchema tool handler path and inspect the input and symmetric output validation checks. Compare the current McpError handling with the expected CallToolResult shape and the scope for unknown-tool and structural errors. Done means input validation reaches the client as content with isError: true while the listed protocol errors remain unchanged.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 64/100