Skip to content

feat(mcp): add content_upload_media tool for image uploads - #314

Open
hectorcanaimero wants to merge 1 commit into
CoreBunch:mainfrom
hectorcanaimero:feat/mcp-upload-media
Open

feat(mcp): add content_upload_media tool for image uploads#314
hectorcanaimero wants to merge 1 commit into
CoreBunch:mainfrom
hectorcanaimero:feat/mcp-upload-media

Conversation

@hectorcanaimero

Copy link
Copy Markdown

What

Adds content_upload_media, a server-resolved MCP tool that uploads an image into the Media library and returns its id + publicPath.

Why

The MCP surface could list and assign media but never create it — an external agent building a page had no way to get an image into the library. This closes that gap.

How

  • Bytes arrive inline (base64, data: URI prefix tolerated) or via an https sourceUrl the host downloads.
  • The sourceUrl branch is SSRF-guarded exactly like the plugin network layer: https-only, DNS-resolved, every resolved address checked against the shared isBlockedAddress blocklist, redirects followed manually and re-validated per hop, and the download size-capped while streaming. Loopback / private / link-local (incl. 169.254.169.254) targets are refused.
  • Reuses the existing acceptUploadedMedia core — magic-byte MIME sniffing, SVG sanitisation, storage dispatch, responsive variants. No new byte-handling path is introduced.
  • Hoists the 50MB ceiling to MAX_MEDIA_BYTES in the upload core so the HTTP media route and the tool share one source of truth.
  • Gated by ai.tools.write + media.write, following the site_publish server-tool precedent.

Impact

  • Connectors/agents: can now upload images (JPEG/PNG/GIF/WebP/SVG) headlessly, without an open editor.
  • No schema changes, no migrations, no changes to existing tool behaviour. content_list_media's description was corrected (it claimed uploads were impossible).

Verification

  • bun test server/ai/mcp/tools/uploadMediaTool.test.ts server/ai/mcp/registry.test.ts — 11/11 pass, including SSRF-blocklist rejection cases (127.0.0.1, 169.254.169.254, 10.x, ::1), non-https rejection, source XOR, and non-image rejection.
  • Typecheck clean on the touched files.
  • bun run build / bun run lint left to CI (dev toolchain not available in the author's environment).

Docs updated: docs/features/mcp-connectors.md.

Adds a server-resolved MCP tool that uploads an image into the Media
library, closing the gap where connectors could list and assign media
but never create it. Bytes arrive inline (base64) or via an https
sourceUrl the host downloads under the plugin network layer's SSRF
blocklist (https-only, DNS-resolved, per-hop redirect revalidation,
size-capped). Reuses the shared acceptUploadedMedia core for magic-byte
sniffing, SVG sanitisation, storage dispatch, and responsive variants.

Hoists the 50MB limit to MAX_MEDIA_BYTES in the upload core so the HTTP
route and the tool share one source of truth.
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.

2 participants