Repository navigation
Presigned single-use links for downloads and draft uploads; base64 is best effort - #26
Merged
Merged
Conversation
markmnl
force-pushed
the
files-extension
branch
from
October 22, 2026 05:46
298874c to
397dcb7
Compare
markmnl
force-pushed
the
presigned-urls
branch
2 times, most recently
from
October 22, 2026 06:17
c25f41b to
197032d
Compare
markmnl
force-pushed
the
files-extension
branch
from
October 22, 2026 06:17
397dcb7 to
09b708c
Compare
Owner
Author
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.
Stacked on #25, which is stacked on #24. This PR's base is #25's branch.
Presigned links
get_attachment_download_urland the draft upload URL both needed the connection's bearer token. Hosts that cannot attach it to their own HTTP requests had to fall back to base64 through the model.get_attachment_download_urltakespresigned: trueand addspresigned: {url, method, expires_at, size, sha256, curl}. The server streams the attachment once to compute its sha256.get_attachment_upload_urlwith{id, filename, size, sha256, content_type?}. It returns{draft_id, filename, url, method: "PUT", expires_at, size, sha256, curl}. It refuses sent messages, other people's drafts, and names already taken. The OAuth scope is read+write./mcp/links/{token}: an HMAC-signed capability for one transfer, valid for 5 minutes, bound to the message or draft, file name, size and sha256.streamIntoDraft), so the size and digest checks are identical.409before any byte is sent; a large one is cut off.404with a message saying so. AGENTS.md's "keep credentials out of links" rule now names this one exception.data_base64 wording
The
data_base64andsha256descriptions, the instructions, the tool guidance and thesend_fileprompt now say three things. Base64 passes through the model, so it is best effort and suited to small files (verified exact up to 16 KB). Always pass sha256. For anything larger, preferpath, a presigned link, or the file-uploads extension. Text names only the routes the running server registered, soFileRoutesgainedpresignedandextension.Tests
test/links.test.ts(11 tests). It runs the returnedcurlcommands for real, over HTTPS through a TLS proxy (CURL_CA_BUNDLEpoints at a throwaway openssl certificate). Covered:send_draftnpm run typecheck && npm run build && npm test: 308 passed.🤖 Generated with Claude Code