Repository navigation
Conversation
The servlet transports returned error bodies that did not conform to the
MCP JSON-RPC response format: they omitted the required "jsonrpc" field,
used "jsonRpcError" instead of "error", and did not include the request ID
even where it was available.
These malformed responses resulted from serializing McpError directly
rather than constructing a JSONRPCResponse error envelope. Because
McpError extends RuntimeException, this also caused information disclosure:
Jackson included exception internals such as stack traces in the response.
Before (wrong; illustrative response with an abbreviated stack trace):
```json
{
"jsonRpcError": {
"code": -123,
"message": "foo"
},
"message": "foo",
"localizedMessage": "foo",
"cause": null,
"suppressed": [],
"stackTrace": [
{
"className": "io.modelcontextprotocol.spec.McpError$Builder",
"methodName": "build",
"fileName": "McpError.java",
"lineNumber": 81,
"nativeMethod": false
}
]
}
```
After (correct; no request ID is available in this example):
```json
{
"jsonrpc": "2.0",
"error": {
"code": -123,
"message": "foo"
}
}
```
Write typed JSONRPCResponse envelopes across the SSE, streamable, and
stateless servlet transports. Allow error responses without an ID while
continuing to require IDs on successful responses, and propagate request
IDs where already parsed. Preserve the public McpError response writer
as a wrapper that unwraps the protocol error.
Add regression coverage for HTTP error envelopes, request IDs, and
exclusion of exception properties, including causes and suppressed
exceptions. Update tests that expected a top-level exception message.
Contributor
|
This PR has been closed automatically. This repo only keeps pull requests open when they come from a maintainer, or from a contributor a maintainer has assigned to the linked issue, and you aren't currently assigned to #955. You're welcome to keep pushing commits here (just avoid force-pushing, since GitHub can't reopen a rewritten branch), but that on its own won't get the PR reviewed or the issue assigned. There's no need to open a new PR either way. See CONTRIBUTING.md for the full policy. Maintainers: reopen, remove |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The servlet transports returned error bodies that did not conform to the MCP JSON-RPC response format: they omitted the required "jsonrpc" field, used "jsonRpcError" instead of "error", and did not include the request ID even where it was available.
These malformed responses resulted from serializing McpError directly rather than constructing a JSONRPCResponse error envelope. Because McpError extends RuntimeException, this also caused information disclosure: Jackson included exception internals such as stack traces in the response.
Before (wrong; illustrative response with an abbreviated stack trace):
{ "jsonRpcError": { "code": -123, "message": "foo" }, "message": "foo", "localizedMessage": "foo", "cause": null, "suppressed": [], "stackTrace": [ { "className": "io.modelcontextprotocol.spec.McpError$Builder", "methodName": "build", "fileName": "McpError.java", "lineNumber": 81, "nativeMethod": false } ] }After (correct; no request ID is available in this example):
{ "jsonrpc": "2.0", "error": { "code": -123, "message": "foo" } }Write typed JSONRPCResponse envelopes across the SSE, streamable, and stateless servlet transports. Allow error responses without an ID while continuing to require IDs on successful responses, and propagate request IDs where already parsed. Preserve the public McpError response writer as a wrapper that unwraps the protocol error.
Add regression coverage for HTTP error envelopes, request IDs, and exclusion of exception properties, including causes and suppressed exceptions. Update tests that expected a top-level exception message.
Fixes #955