Skip to content

fix(mcp): exit the MCP bridge once its client is gone - #282

Merged
schiste merged 1 commit into
mainfrom
agent/exit-the-mcp-bridge-when-its-client-goes
Oct 24, 2026
Merged

schiste merged 1 commit into
mainfrom
agent/exit-the-mcp-bridge-when-its-client-goes

Conversation

@schiste

@schiste schiste commented Oct 24, 2026

Copy link
Copy Markdown
Member

Summary

Exit the MCP bridge when its client goes away; restore traffic lights inside the tab bar

Problem: the bridge noticed a departed client only when a later write to
stdout failed, or after stdin EOF once the app closed the socket. A
client that stopped reading, or died while its pipes stayed open,
left the bridge running and connected to Chau7 indefinitely.

Decision: a watcher thread checks every 2 s whether stdout's reader hung
up (poll POLLHUP/POLLERR) or the bridge was reparented to launchd (its
parent died), and exits in either case. An idle client that keeps its
pipes open keeps its bridge.

Rationale: the bridge must not outlive its client, but Codex's app
server keeps loaded threads' MCP servers idle on purpose; exiting on
idleness would break the next tool call of a resumed thread.

Changes

Checklist

  • pnpm quality:prepush passes, or pnpm quality:prepush:full for high-impact changes
  • cargo test --workspace passes in apps/chau7-next (if macOS app changes)
  • swift test --package-path apps/chau7-ios/Chau7Core passes (if Swift changes)
  • New tests added for new behavior
  • Documentation updated (README, CHANGELOG.md if user-facing)

Test plan

new unit test for the decision and an integration test that
runs the real binary against a server that never closes, closes the
client's stdout with stdin still open, and requires the bridge to exit
(it does in about 2 s; previously it never exited). Clippy and fmt
clean.

Commits:

  • 8f0ac82 fix(mcp): exit the MCP bridge once its client is gone

Opened by aethyme broker push as a draft.

Problem: the bridge noticed a departed client only when a later write to
stdout failed, or after stdin EOF once the app closed the socket. A
client that stopped reading, or died while its pipes stayed open,
left the bridge running and connected to Chau7 indefinitely.

Decision: a watcher thread checks every 2 s whether stdout's reader hung
up (poll POLLHUP/POLLERR) or the bridge was reparented to launchd (its
parent died), and exits in either case. An idle client that keeps its
pipes open keeps its bridge.

Rationale: the bridge must not outlive its client, but Codex's app
server keeps loaded threads' MCP servers idle on purpose; exiting on
idleness would break the next tool call of a resumed thread.

Validation: new unit test for the decision and an integration test that
runs the real binary against a server that never closes, closes the
client's stdout with stdin still open, and requires the bridge to exit
(it does in about 2 s; previously it never exited). Clippy and fmt
clean.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@schiste
schiste marked this pull request as ready for review October 24, 2026 07:34
@schiste
schiste merged commit 7dc3a32 into main Oct 24, 2026
4 checks passed
@schiste
schiste deleted the agent/exit-the-mcp-bridge-when-its-client-goes branch October 24, 2026 07:41
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.

1 participant