fix(jetsocat): always send JSON-RPC message on MCP proxy backend disconnect#1737
fix(jetsocat): always send JSON-RPC message on MCP proxy backend disconnect#1737Benoît Cortier (CBenoit) merged 4 commits intomasterfrom
Conversation
The --log-term flag was routing log output through stdout, polluting the MCP stdio JSON-RPC channel and any other stdout-based protocol. Fixed to use stderr, which is the correct descriptor for diagnostic output.
…onnect When the backend MCP process disconnects, the proxy now always sends a protocol-level message to the client before exiting, instead of silently closing the stdio channel: - SendError::Fatal (write to broken backend): JSON-RPC error response (-32099) with the pending request id. - ReadError::Fatal with a pending request: JSON-RPC error response (-32099) so the client can correlate it with the outstanding request. - ReadError::Fatal with no pending request: a \\$/proxy/serverDisconnected\ notification so the client is informed even without an active request.
There was a problem hiding this comment.
Pull request overview
This PR fixes jetsocat’s MCP proxy behavior so clients always receive a protocol-level JSON-RPC frame (error response or notification) when the backend disconnects, and ensures --log-term output no longer corrupts the stdio JSON-RPC stream by moving logs to stderr.
Changes:
- Route
--log-termlogging to stderr (and update related CLI docs/tests). - Track a pending JSON-RPC request id in
mcp-proxyto synthesize either an error response (-32099) or a$/proxy/serverDisconnectednotification on fatal backend disconnect. - Replace the testsuite MCP server shutdown helper with
tokio_util::sync::CancellationTokenand adjust MCP proxy tests accordingly.
Reviewed changes
Copilot reviewed 6 out of 7 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
crates/mcp-proxy/src/lib.rs |
Adds pending-request tracking and always generates a JSON-RPC message on fatal backend disconnect. |
jetsocat/src/mcp.rs |
Ensures fatal read/write errors flush the synthesized JSON-RPC message to the client before exiting. |
jetsocat/src/main.rs |
Moves --log-term output to stderr and updates flag description. |
testsuite/tests/cli/jetsocat.rs |
Updates assertions to expect logs on stderr and strengthens MCP proxy disconnect test expectations. |
testsuite/src/mcp_server.rs |
Replaces custom shutdown signal with CancellationToken and updates server loop cancellation. |
testsuite/Cargo.toml |
Adds tokio-util dependency for CancellationToken. |
Cargo.lock |
Locks new dependency. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 6 out of 7 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Vladyslav Nikonov (vnikonov-devolutions)
left a comment
There was a problem hiding this comment.
LGTM!
Fixes two bugs in the jetsocat MCP proxy that could cause silent failures when the backend MCP process disconnected.
--log-termwriting to stdout: log output was mixed into the MCP stdio JSON-RPC channel, corrupting the protocol stream for any client using--log-term.Silent close on backend disconnect: when the backend broke, the proxy would close the stdio channel without sending any protocol-level message, leaving the client with a raw broken-pipe or EOF error it couldn't meaningfully handle. The proxy now always sends a message:
-32099) correlated to the pending request id.$/proxy/serverDisconnectednotification so the client is still informed.Also replaces the
McpShutdownSignaltest helper (which usednotify_one()and could silently leave a waiter alive) withCancellationTokenfromtokio-util, fixing the root cause of the flakymcp_proxy_terminated_on_broken_pipeCI test.