fix: daemon IPC drops large payloads and callTool uses wrong timeout#222
Open
kengerlwl wants to merge 1 commit intophilschmid:mainfrom
Open
fix: daemon IPC drops large payloads and callTool uses wrong timeout#222kengerlwl wants to merge 1 commit intophilschmid:mainfrom
kengerlwl wants to merge 1 commit intophilschmid:mainfrom
Conversation
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.
Problem
Two bugs in daemon mode that surface when MCP tools return large responses (e.g. browser automation snapshots of complex pages like GitHub):
1. Large socket payloads are silently truncated
socket.write()in Bun's Unix socket may not send all data at once when the payload exceeds the socket buffer size (~8KB). The original code does a singlesocket.write()and assumes it completes, but for large tool responses only the first chunk arrives at the client.The client then tries to
JSON.parse()the partial data and fails with "Invalid response from daemon", or hangs forever waiting for a newline delimiter that never arrives.2. callTool requests use the 5s IPC timeout
sendRequest()has a hardcoded 5-second timeout designed for fast IPC fallback (ping, listTools). ButcallToolalso goes throughsendRequest(), so any tool execution taking >5s (e.g. browser navigation waiting for page load) times out with "Daemon request timeout" and falls back to a direct connection — defeating the purpose of the daemon.Fix
daemon.ts: Write response payload in a loop to handle partial writes, then
flush()andend()the socket connection.daemon-client.ts:
timeoutMsparameter tosendRequest()(default 5s for quick IPC)callToolpassesgetTimeoutMs()(respectsMCP_TIMEOUTenv var, default 30 min)settledflagTesting
Verified end-to-end with BrowserMCP (
@browsermcp/mcp) which returns ~8-30KB accessibility snapshots:browser_snapshoton GitHub.com: was hanging forever, now returns in ~2sbrowser_navigate: was timing out at 5s, now completes normallyping/listTools: still fast (<100ms), unaffected by the change