feat: Image & video uploads for MCP and CLI (Blossom protocol)#433
Merged
tlongwell-block merged 2 commits intomainfrom Apr 30, 2026
Merged
feat: Image & video uploads for MCP and CLI (Blossom protocol)#433tlongwell-block merged 2 commits intomainfrom
tlongwell-block merged 2 commits intomainfrom
Conversation
…ool\n\n- Add upload.rs with core Blossom upload pipeline (hash, auth, upload)\n- Wire upload_file MCP tool and file_paths on send_message\n- Fix server_domain port handling, pre-read size check, upload timeout\n- Extract SendMessageParams to satisfy clippy too_many_arguments\n- Update Cargo.toml
c6609cc to
127829e
Compare
When no explicit mcp_toolsets is configured for a managed agent, set SPROUT_TOOLSETS=default,media instead of removing the env var. This gives all desktop-spawned agents access to the upload_file tool without requiring manual configuration. Agents with an explicit toolset override are unaffected (the if-let branch is unchanged).
0256307 to
cae075e
Compare
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.
Summary
Adds file upload support to both
sprout-mcpandsprout-cli, implementing the Blossom protocol for media uploads with NIP-92imetatag construction.What's New
sprout-mcp— newupload_filetool +file_pathsonsend_messageupload_filetool — standalone upload that returns aBlobDescriptor(URL, hash, dimensions, blurhash, etc.)file_pathsparameter onsend_message— upload-and-attach in one step; files are uploaded,imetatags added, and markdown image/video links appended to the message contentsprout-cli—upload-filecommand +--fileflag onsend-messagesprout-cli upload-file --file <path>— uploads a file and prints theBlobDescriptorJSONsprout-cli send-message --file <path> [--file <path2>]— attach one or more files to a messageCore upload pipeline (
upload.rs)Supported types: JPEG, PNG, GIF, WebP, MP4
Size limits: 50 MB images, 500 MB video
Auth: Blossom kind:24242 event with
t:upload,x:<sha256>,expiration,servertagsTimeouts: 120s for images, 600s for video (overrides the shared client's 10s default)
Files Changed
crates/sprout-mcp/src/upload.rsbuild_imeta_taghelper + unit testscrates/sprout-mcp/src/server.rsupload_filetool handler,file_pathsonSendMessageParams, upload wiringcrates/sprout-mcp/src/relay_client.rshttp_client(),keys(),api_token(),server_domain()crates/sprout-mcp/src/toolsets.rsupload_filefrom deferred → active (media toolset)crates/sprout-mcp/src/lib.rspub mod uploadcrates/sprout-mcp/Cargo.tomlsha2,hex,base64,infercrates/sprout-cli/src/client.rsupload_file()method +BlobDescriptor+build_imeta_tagcrates/sprout-cli/src/commands/messages.rs--fileuploads intocmd_send_messagecrates/sprout-cli/src/main.rsUploadFilecommand +--filearg onSendMessagecrates/sprout-cli/Cargo.tomlhex,infer,urlTesting
build_imeta_tag(image, video, minimal descriptors)cargo fmt,cargo clippy,cargo testDesign Decisions
infercrate) rather than trusting file extensions — prevents spoofingstd::fs::read()to avoid buffering 600 MB into RAMnostr::util::hexreused where possible to minimize new dependenciesserver_domain()usesurl::Url::parse()to correctly include non-default ports in BUD-11 server tags