Skip to content

fix(jetsocat): always send JSON-RPC message on MCP proxy backend disconnect#1737

Merged
Benoît Cortier (CBenoit) merged 4 commits intomasterfrom
test/fix-flacky-test
Apr 2, 2026
Merged

fix(jetsocat): always send JSON-RPC message on MCP proxy backend disconnect#1737
Benoît Cortier (CBenoit) merged 4 commits intomasterfrom
test/fix-flacky-test

Conversation

@CBenoit
Copy link
Copy Markdown
Member

@CBenoit Benoît Cortier (CBenoit) commented Apr 2, 2026

Fixes two bugs in the jetsocat MCP proxy that could cause silent failures when the backend MCP process disconnected.

--log-term writing 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:

  • If a request was in-flight: a JSON-RPC error response (-32099) correlated to the pending request id.
  • If no request was pending: a $/proxy/serverDisconnected notification so the client is still informed.

Also replaces the McpShutdownSignal test helper (which used notify_one() and could silently leave a waiter alive) with CancellationToken from tokio-util, fixing the root cause of the flaky mcp_proxy_terminated_on_broken_pipe CI test.

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.
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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-term logging to stderr (and update related CLI docs/tests).
  • Track a pending JSON-RPC request id in mcp-proxy to synthesize either an error response (-32099) or a $/proxy/serverDisconnected notification on fatal backend disconnect.
  • Replace the testsuite MCP server shutdown helper with tokio_util::sync::CancellationToken and 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.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@CBenoit Benoît Cortier (CBenoit) merged commit e4052b2 into master Apr 2, 2026
45 checks passed
@CBenoit Benoît Cortier (CBenoit) deleted the test/fix-flacky-test branch April 2, 2026 08:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants