Skip to content

Comments

fix: throw ProtocolError as JSON-RPC error for tool not found#1567

Open
stakeswky wants to merge 1 commit intomodelcontextprotocol:mainfrom
stakeswky:fix/tool-not-found-jsonrpc-error
Open

fix: throw ProtocolError as JSON-RPC error for tool not found#1567
stakeswky wants to merge 1 commit intomodelcontextprotocol:mainfrom
stakeswky:fix/tool-not-found-jsonrpc-error

Conversation

@stakeswky
Copy link

Summary

Fix tool not found errors to return JSON-RPC Error instead of JSON-RPC Result with isError: true, per MCP specification.

Problem

When a client calls a nonexistent tool, the current implementation returns:

{
  "jsonrpc": "2.0",
  "id": "3",
  "result": {
    "content": [
      {
        "type": "text",
        "text": "MCP error -32602: Tool nonexistent_tool not found"
      }
    ],
    "isError": true
  }
}

But the MCP specification requires:

{
  "jsonrpc": "2.0",
  "id": 3,
  "error": {
    "code": -32602,
    "message": "Unknown tool: nonexistent_tool"
  }
}

Root Cause

The tools/call handler's catch block only re-threw UrlElicitationRequired errors. All other ProtocolError instances (including tool not found, tool disabled, invalid params, etc.) were caught and wrapped in a CallToolResult with isError: true.

Fix

Changed the catch block to re-throw all ProtocolError instances, not just UrlElicitationRequired. This ensures protocol-level errors are returned as JSON-RPC errors per the spec.

Tests

Updated the existing test for nonexistent tools to expect a thrown error instead of a CallToolResult with isError: true.

Fixes #1510

Per MCP spec, calling a nonexistent tool should return a JSON-RPC Error
(code -32602), not a JSON-RPC Result with isError: true.

Previously, only UrlElicitationRequired errors were re-thrown; all other
ProtocolErrors (including tool/disabled checks) were swallowed and wrapped
in a CallToolResult. Now all ProtocolErrors propagate as JSON-RPC errors,
which is the correct behavior per the specification.

Fixes modelcontextprotocol#1510
@stakeswky stakeswky requested a review from a team as a code owner February 22, 2026 08:13
@changeset-bot
Copy link

changeset-bot bot commented Feb 22, 2026

⚠️ No Changeset found

Latest commit: 65f5f72

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@pkg-pr-new
Copy link

pkg-pr-new bot commented Feb 22, 2026

Open in StackBlitz

@modelcontextprotocol/client

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/client@1567

@modelcontextprotocol/server

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/server@1567

@modelcontextprotocol/express

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/express@1567

@modelcontextprotocol/hono

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/hono@1567

@modelcontextprotocol/node

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/node@1567

commit: 65f5f72

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Calling a nonexistent tool should trigger a JSON-RPC Error

1 participant