Repository navigation
Return invalid params for unknown requested tools #3697
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -75,6 +75,7 @@ | |
| ResourceError, | ||
| ResourceNotFoundError, | ||
| ToolError, | ||
| ToolNotFoundError, | ||
| UnexpectedResourceError, | ||
| UnexpectedToolError, | ||
| ) | ||
|
|
@@ -443,6 +444,8 @@ async def _handle_call_tool( | |
| except MCPError: | ||
| raise | ||
| except Exception as exc: | ||
| if isinstance(exc, ToolNotFoundError) and exc.name == params.name: | ||
| raise MCPError(code=INVALID_PARAMS, message=str(exc)) from exc | ||
|
Comment on lines
+447
to
+448
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 nit (optional): AGENTS.md says any change to a released v2 API's observable behaviour is an explicit maintainer design decision that should generally be avoided: server.py now answers a Why this was flaggedNothing fails at runtime in the SDK itself. The rule guards 2.x compatibility: existing clients and hosts that handled unknown-tool misses by inspecting Verification: AGENTS.md (base commit) "Branching Model": "v2 is released; its public API is a compatibility contract for the 2.x line. Removals, renames, or any change to an existing API's signature or observable behaviour ... is a design decision a maintainer makes explicitly, and should generally be avoided." |
||
| if isinstance(exc, ToolError) and not isinstance(exc, UnexpectedToolError): | ||
| if isinstance(exc.__cause__, ValidationError): | ||
| # Field names only: the rejected values are the caller's data. | ||
|
|
@@ -536,7 +539,8 @@ async def call_tool( | |
| """Call a tool by name with arguments. | ||
|
|
||
| Raises: | ||
| ToolError: If the tool is unknown, the arguments fail validation, or the | ||
| ToolNotFoundError: If the tool is unknown. This is a subclass of `ToolError`. | ||
| ToolError: If the arguments fail validation, or the | ||
| tool (or a resolver) raises `ToolError` or `ResourceError`. | ||
| UnexpectedToolError: If the tool (or a resolver) raises anything else, or | ||
| its return value fails output conversion. `__cause__` is the original | ||
|
|
||
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.
P2: This overstates the result path: a tool that raises
MCPErroris re-raised, soClient.call_tool()raises instead of returningis_error=True. Limit this to ordinary tool errors or call out theMCPErrorexception.Prompt for AI agents