-
Notifications
You must be signed in to change notification settings - Fork 1.8k
fix(server): align ProtocolError re-throw with spec error classification #1769
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 1 commit
49ab9e2
e6b8a57
3f29f35
66d6ea6
6268292
2502215
4633cb1
ad60a64
3ab699d
ffc96dd
54ef5ea
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 |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| --- | ||
| '@modelcontextprotocol/server': minor | ||
| --- | ||
|
|
||
| Re-throw all `ProtocolError` instances from `tools/call` handler as JSON-RPC errors instead of wrapping them in `isError: true` results. | ||
|
|
||
| **Breaking change:** Output validation failures (missing or schema-mismatched `structuredContent`) now surface as JSON-RPC `InternalError` rejections instead of `{ isError: true }` results. Input validation failures continue to return `{ isError: true }` per the MCP spec's tool-execution-error classification. | ||
|
|
||
| This also means tool handlers that deliberately `throw new ProtocolError(...)` will now propagate that as a JSON-RPC error, matching the python-sdk behavior. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -206,8 +206,8 @@ export class McpServer { | |
| await this.validateToolOutput(tool, result, request.params.name); | ||
| return result; | ||
| } catch (error) { | ||
|
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. This broadened catch now re-throws Options:
Also: the null-check at L328-330 ( |
||
| if (error instanceof ProtocolError && error.code === ProtocolErrorCode.UrlElicitationRequired) { | ||
| throw error; // Return the error to the caller without wrapping in CallToolResult | ||
| if (error instanceof ProtocolError) { | ||
| throw error; | ||
| } | ||
|
claude[bot] marked this conversation as resolved.
|
||
| return this.createToolError(error instanceof Error ? error.message : String(error)); | ||
| } | ||
|
claude[bot] marked this conversation as resolved.
|
||
|
|
@@ -251,10 +251,9 @@ export class McpServer { | |
|
|
||
| const parseResult = await validateStandardSchema(tool.inputSchema, args ?? {}); | ||
| if (!parseResult.success) { | ||
| throw new ProtocolError( | ||
| ProtocolErrorCode.InvalidParams, | ||
| `Input validation error: Invalid arguments for tool ${toolName}: ${parseResult.error}` | ||
| ); | ||
| // Per spec, input validation failures are tool-execution errors (isError: true), | ||
| // not protocol errors — throw plain Error so the catch wraps it as a tool result. | ||
| throw new Error(`Input validation error: Invalid arguments for tool ${toolName}: ${parseResult.error}`); | ||
| } | ||
|
|
||
| return parseResult.data as unknown as Args; | ||
|
|
@@ -279,7 +278,7 @@ export class McpServer { | |
|
|
||
| if (!result.structuredContent) { | ||
| throw new ProtocolError( | ||
| ProtocolErrorCode.InvalidParams, | ||
| ProtocolErrorCode.InternalError, | ||
| `Output validation error: Tool ${toolName} has an output schema but no structured content was provided` | ||
| ); | ||
| } | ||
|
|
@@ -288,7 +287,7 @@ export class McpServer { | |
| const parseResult = await validateStandardSchema(tool.outputSchema, result.structuredContent); | ||
| if (!parseResult.success) { | ||
| throw new ProtocolError( | ||
| ProtocolErrorCode.InvalidParams, | ||
| ProtocolErrorCode.InternalError, | ||
| `Output validation error: Invalid structured content for tool ${toolName}: ${parseResult.error}` | ||
| ); | ||
| } | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.