Repository navigation
Carry upstream's T3 attachment toolkit over the file bridge - #294
Merged
Merged
Conversation
t3_thread_send_attachments, t3_attachment_prepare_upload, and t3_attachment_discard come from upstream verbatim except the upload step: with no MCP HTTP origin to POST to, prepare_upload takes the absolute workspace path of the file and stores it through upstream's upload validation and store in process, so bytes never pass through the bridge's bounded request files. Uploads forwarded from a linked workspace are refused; sends reach only threads in this workspace, as upstream's tools take no environmentId. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Owner
Author
|
Merged coder-only (#293) into this branch. Reviewed the path-staging delta: absolute path, regular file, size must equal |
This was referenced Oct 31, 2026
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.
Restores upstream's T3 attachment toolkit (
t3_thread_send_attachments,t3_attachment_prepare_upload,t3_attachment_discard) on the workspace file bridge, so an agent can hand images and files to another thread, for example a screenshot for a delegated task. This also re-enables pending uploads int3_thread_launch/create_threadsinitial messages, which already accepted them through upstream's project toolkit.Carried 1:1 from upstream (80a2351)
apps/server/src/mcp/toolkits/attachment/handlers.tsandtools.ts: the discard and send tools,resolveAttachmentReferences(resending an attachment the target thread already owns needs no upload), upload-owner tracking and TTL, and every name and schema except the upload step below.T3ToolBridge.tsthe same way upstream'sMcpHttpServer.layerAttachmentToolkitregisters them; the bridge's--listand--schemacome from the tool definitions, so the bridge instructions text needed no change.core.test.tsattachment cases (resolves reused attachment references…,only the caller that prepared a pending upload can discard it) now run inattachment/handlers.test.tsagainst the toolkit directly, because the fork has noMcpServer.Fork deltas (marked
Coder:, listed in coder-only.md seams)t3_attachment_prepare_uploadtakes apathbesideupload. Upstream returns a URL for the agent to POST to on "this MCP server's HTTP origin", and the helper has no listener (boundary 6). The handler now:issueAttachmentUploadUrl;pathis an absolute path to a regular file of exactlyupload.sizeBytes;validateAttachmentUploadTokenand streams the file throughstoreAttachmentUpload, which is the same validation and store path as upstream's upload route.The agent and helper share the workspace filesystem, so the bytes never go through the bridge's 256 KiB request or response files. Upstream's byte limits still apply:
PROVIDER_SEND_TURN_MAX_IMAGE_BYTES/PROVIDER_SEND_TURN_MAX_FILE_BYTESin theuploadschema, the exact-size store, and image signature checks when the attachment is claimed.The result is
{ attachmentId }, with no URL, because the upload is already stored. The tool description changes to match.An upload forwarded through the gateway hub (
client.linked) is refused: itspathwould name a file in the other workspace.Cross-workspace behaviour
Upstream's attachment tools take no
environmentId, soMcpToolAccessnever routes them to a linked environment. AthreadIdin a linked workspace therefore answers upstream'sthread_not_found. A prepare call forwarded through the hub getsinvalid_requestwith a message to upload from a thread in that workspace. No new transfer path is added.Upstream sync
coder-only had not moved when this was pushed (base 52c7e7a).
git diff 80a2351fcb 15fe283272is empty for the carried files and the code they call (toolkits/attachment/,AttachmentUpload.ts,McpToolAccess.ts,ThreadMessageIntake.ts,AttachmentClaims.ts,contracts/assets.ts), so merging the 15fe283 sync needs no bring-up here.Verification
sh, and a fake provider:--listand--schemashow the tools.prepare_uploadfrom a workspace PNG path, thent3_thread_send_attachmentsto a second thread: the target message has one claimedthread-…image whose bytes on disk match the file.thread_not_found), and a hub-forwarded prepare.pnpm test:server: 3559 passed, 2 failed, both known ClaudeSkills plugin-order test fails on macOS (/var symlink) #235 (ClaudeSkills, GitVcsDriverCore on macOS).pnpm test:providers,pnpm test:contracts,pnpm test:knip,node scripts/seams-check.mjs,vp fmt --checkon changed files, andpnpm buildall pass.🤖 Generated with Claude Code