Skip to content

feat: Image & video uploads for MCP and CLI (Blossom protocol)#433

Merged
tlongwell-block merged 2 commits intomainfrom
feat/mcp-cli-image-upload
Apr 30, 2026
Merged

feat: Image & video uploads for MCP and CLI (Blossom protocol)#433
tlongwell-block merged 2 commits intomainfrom
feat/mcp-cli-image-upload

Conversation

@tlongwell-block
Copy link
Copy Markdown
Collaborator

Summary

Adds file upload support to both sprout-mcp and sprout-cli, implementing the Blossom protocol for media uploads with NIP-92 imeta tag construction.

What's New

sprout-mcp — new upload_file tool + file_paths on send_message

  • upload_file tool — standalone upload that returns a BlobDescriptor (URL, hash, dimensions, blurhash, etc.)
  • file_paths parameter on send_message — upload-and-attach in one step; files are uploaded, imeta tags added, and markdown image/video links appended to the message content
  • Works across all message kinds: stream messages, forum posts, and forum comments

sprout-cliupload-file command + --file flag on send-message

  • sprout-cli upload-file --file <path> — uploads a file and prints the BlobDescriptor JSON
  • sprout-cli send-message --file <path> [--file <path2>] — attach one or more files to a message

Core upload pipeline (upload.rs)

validate path → read bytes → MIME detect (magic bytes) → size check → SHA-256 → sign kind:24242 → base64url encode → PUT /media/upload → parse BlobDescriptor

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, server tags
Timeouts: 120s for images, 600s for video (overrides the shared client's 10s default)

Files Changed

File Change
crates/sprout-mcp/src/upload.rs New — core upload pipeline + build_imeta_tag helper + unit tests
crates/sprout-mcp/src/server.rs upload_file tool handler, file_paths on SendMessageParams, upload wiring
crates/sprout-mcp/src/relay_client.rs Public accessors: http_client(), keys(), api_token(), server_domain()
crates/sprout-mcp/src/toolsets.rs Move upload_file from deferred → active (media toolset)
crates/sprout-mcp/src/lib.rs pub mod upload
crates/sprout-mcp/Cargo.toml Add sha2, hex, base64, infer
crates/sprout-cli/src/client.rs upload_file() method + BlobDescriptor + build_imeta_tag
crates/sprout-cli/src/commands/messages.rs Wire --file uploads into cmd_send_message
crates/sprout-cli/src/main.rs UploadFile command + --file arg on SendMessage
crates/sprout-cli/Cargo.toml Add hex, infer, url

Testing

  • Unit tests for build_imeta_tag (image, video, minimal descriptors)
  • MIME allowlist assertions
  • Size limit assertions
  • CLI command inventory test updated (54 → 55)
  • Toolset count tests updated (48 → 49 tools, 3 → 2 deferred, 8 → 9 toolsets)
  • All Rust checks pass: cargo fmt, cargo clippy, cargo test

Design Decisions

  • Magic-byte MIME detection (infer crate) rather than trusting file extensions — prevents spoofing
  • Pre-read size rejection before std::fs::read() to avoid buffering 600 MB into RAM
  • Per-request timeout override on the upload PUT — the shared client's 10s timeout is too short for large files
  • nostr::util::hex reused where possible to minimize new dependencies
  • server_domain() uses url::Url::parse() to correctly include non-default ports in BUD-11 server tags

…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
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).
@tlongwell-block tlongwell-block force-pushed the feat/mcp-cli-image-upload branch from 0256307 to cae075e Compare April 30, 2026 18:16
@tlongwell-block tlongwell-block merged commit f23560d into main Apr 30, 2026
13 checks passed
@tlongwell-block tlongwell-block deleted the feat/mcp-cli-image-upload branch April 30, 2026 18:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant