modelcontextprotocol / modelcontextprotocol/typescript-sdk

SEP-1303: Input validation errors should return Tool Execution Errors, not Protocol Errors

Open
#1,956 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

potentially close
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

Happy to open a PR if maintainers confirm the direction.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.