perf(server): stop shipping full MCP tool results in thread payloads - #5482
Merged
Conversation
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.
MCP tool calls were exempt from activity payload slimming:
projectActivityPayloadearly-returns onitemType === "mcp_tool_call", so the full tool result rides along in every snapshot and live event. On MCP-heavy threads this dominates the wire — one imported thread ships 3.2 MB gzipped, with two-thirds of its post-slimming bytes being unslimmed MCP payloads (worst single call: a GitHubfetch_prresult at 1 MB).The exemption existed because both clients render
payload.data.itemin the expanded work-log row. The fix keeps exactly the fields that row renders (tool,server,status,arguments,appContext,error,durationMs, plustoolName/inputfor the Claude-adapter shape) and summarizes the result to one 84-char line, same as regular tool output. Full payloads stay in SQLite, so an on-demand detail endpoint can be added later without data loss.Measured against a real db seeded with six representative threads (2,991 MCP activities): 12.2 MB of MCP payload JSON drops to 546 KB (95.6% reduction). Both provider payload shapes (Codex
data.item, Claude/OpenCodedata.result) verified against real rows.Note: this trades away in-app access to full historical MCP results (they were previously visible in the expanded row). Per the pagination investigation, that's an accepted temporary loss; the data remains in persistence.
Change made by Claude Fable 5 via Claude Code.
Note
Medium Risk
Changes the shape and fidelity of MCP activity data on thread snapshots and live events (lossy summaries), but scope is limited to projection with strong test coverage and no persistence changes.
Overview
MCP tool calls are no longer exempt from activity payload slimming in
projectActivityPayload. Instead of passingmcp_tool_callthrough unchanged, the server now runsprojectMcpToolCallData, which keeps only fields the expanded work-log row uses (tool,server,status,arguments,appContext,error,durationMs, plus Claude-styletoolName/input) and replaces full tool results with a one-line summary via the samesummarizeToolTextOutputhelper used for other tools.Codex-shaped payloads (
data.item.result) and Claude/OpenCode-shaped payloads (data.resultblocks) are both handled; internal metadata like_metaand largestructuredContentare dropped. Changed file paths can still be collected into afilesarray. Full MCP results remain in persistence—only snapshot/live thread transports shrink.Tests now assert large MCP fixtures compress dramatically and that web/mobile derived views stay aligned except for the intentional loss of full historical MCP result text in the expanded row.
Reviewed by Cursor Bugbot for commit 22f7a58. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Stop shipping full MCP tool results in thread payloads
projectMcpToolCallDatain ActivityPayloadProjection.ts to slim MCP tool-call payloads: only whitelisted fields (tool,server,arguments, etc.) are kept, andresultcontent is replaced with a short text summary.toolName/input/result) MCP data formats.filesarray on the slimmed payload.itemType === "mcp_tool_call"previously passed through unchanged; they now return a slimmed data object, which reduces payload size significantly (tests assert < 500 bytes).Macroscope summarized 22f7a58.