- 
                Notifications
    You must be signed in to change notification settings 
- Fork 1.4k
Fix: Non-existent tool, disabled tool and inputSchema validation return MCP protocol level instead of CallToolResult with isError: true #1044
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…rn CallToolResult instead of a protocol-level error
| A screenshot of running the "everything server" (https://github.com/modelcontextprotocol/example-remote-server) and doing a test against it.   Edit: The everything server seems to achieve the same end effect, but by going a different route. It itself uses the  It is then caught by the  typescript-sdk/src/shared/protocol.ts Line 394 in 5a8fb39 
 TL;DR the everything server likely needs an issue fix on its own since it's not using  | 
| Cc @pcarleton Was thinking - the conformance suite you raised few weeks back would immediately catch exactly things like this and this issue underwrites the need for such a suite even more. | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for this, makes sense to me - just think we should also move the output validation into the code block (+ tests covering that) into the try-catch block while we're at it for SDK consistency.
…urned or structuredContent validation error
…th MCP spec (#354) Update server-side tool error handling to return `CallToolResult` with `isError: true` instead of throwing protocol-level exceptions, conforming with MCP specification ## Motivation and Context [The MCP specification states](https://modelcontextprotocol.io/specification/2025-06-18/schema#calltoolresult): > Any errors that originate from the tool SHOULD be reported inside the result object, with isError set to true, not as an MCP protocol-level error response. Otherwise, the LLM would not be able to see that an error occurred and self-correct. This PR updates the kotlin sdk to match this behavior ## How Has This Been Tested? All tests pass successfully with the new behavior ## Breaking Changes None ## Types of changes - [x] Bug fix (non-breaking change which fixes an issue) - [ ] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to change) - [ ] Documentation update ## Checklist - [x] I have read the [MCP Documentation](https://modelcontextprotocol.io) - [x] My code follows the repository's style guidelines - [x] New and existing tests pass locally - [x] I have added appropriate error handling - [x] I have added or updated documentation as needed ## Additional context The TypeScript SDK was recently updated [#1044](modelcontextprotocol/typescript-sdk#1044) to conform with the MCP specification regarding tool error handling. That’s why we got exceptions in the integration tests
…col#1044 pattern Change strict validation errors to return CallToolResult with isError: true instead of throwing protocol-level errors, aligning with the pattern established in PR modelcontextprotocol#1044 (commit 7387c44) where all validation errors return error responses rather than throwing. This ensures consistent error handling across all validation scenarios and enables LLMs to see validation errors and attempt self-correction, as specified in the MCP protocol specification. Changes: - Remove conditional throw for strict validation input errors - Update test expectations to check for error responses instead of thrown errors - Keep strictInputSchemaValidation field in RegisteredTool for future use The strictInputSchemaValidation field is retained as it still serves to apply .strict() to the Zod schema, rejecting unknown parameters. The difference is now the rejection returns an error response visible to LLMs rather than a protocol-level error. Changes linted and tested. <em>🤖 Created with Claude Code via Airchat</em>
Currently, a few scenarios return a MCP protocol level error as opposed to a CallToolResult with isError: true. This leads to MCP hosts (e.g. Claude and others) not being able to read the error message and attempt self-correct.
Affected scenarios:
Motivation and Context
MCP hosts should be able to attempt self-correct after getting a validation error, or calling a non-existent or disabled tool.
Specification non-conformance
The spec confirms that a CallToolResult should be returned:
https://modelcontextprotocol.io/specification/2025-06-18/schema#calltoolresult
(thanks @cliffhall for finding the right spot in the spec)
Examples of other SDKs not having this issue and following spec
Python SDK is an example that returns a CallToolResult for these scenarios. Code for inputSchema validation returning CallToolResult (isError: true) can be observed at:
https://github.com/modelcontextprotocol/python-sdk/blob/main/src%2Fmcp%2Fserver%2Flowlevel%2Fserver.py#L499
https://github.com/modelcontextprotocol/python-sdk/blob/6c26d087df3406c7da1f85b8ae3c3caeabf7b002/src/mcp/server/lowlevel/server.py#L440
How Has This Been Tested?
Tested the modified server. Unit tests applied/modified to that effect.
Breaking Changes
None. It's fixing a current bug.
Types of changes
Checklist