wp_upload_media: upload Base64 media
Uploads an image sent directly as a base64 payload. The more flexible of the two upload tools, because it has no network constraints.
Arguments
| Argument | Required | Meaning |
|---|---|---|
filename |
Yes | The filename, including extension |
base64 |
Yes | The image data |
post_id |
No | Attach the upload to a post |
description |
No | The attachment description |
dry_run |
No | Report without uploading |
Permissions
Allow content writes open, and the upload_files capability.
Scopes: mcp:read, mcp:write, wp:content:read, wp:content:write.
The payload
Accepts a plain base64 string, or a data URI of the form data:image/png;base64,… — the prefix is stripped automatically, so a client can send whichever it has.
Maximum decoded size is 10 MB. Base64 inflates by roughly a third, so a 10 MB image arrives as about 13 MB of payload.
The extension in filename is load-bearing
Validation happens twice, and the first check is on the filename:
- The extension must be
jpg,jpeg,png,gif,webporavif. Anything else is refused withpom_ai_mcp_media_extension_deniedbefore the file is even examined. - The actual contents are then inspected after the bytes are written to disk. A mismatch is refused with
pom_ai_mcp_media_mime_denied.
So a PNG named photo.txt fails the first check, and a PDF named photo.png fails the second. Both are deliberate.
Give the filename the extension that matches the real data.
Use the dry run
dry_run returns the sanitised filename and the decoded byte count without uploading:
Use a dry run and tell me the filename and size you would create.
This is the most useful dry run in the media group. It decodes the payload, so it catches a truncated or malformed base64 string as a size that looks wrong — before the upload fails for a reason that is harder to read.
Filenames are sanitised
filename is passed through WordPress's filename sanitiser, so spaces and unusual characters are normalised. The stored name may differ from what you sent; the response tells you what was created.
WordPress also deduplicates: uploading photo.jpg twice produces photo.jpg and photo-1.jpg rather than an overwrite.
When to prefer this over the URL tool
Always, unless you specifically have a public URL and no bytes:
- the image was generated by the assistant;
- the source URL redirects, which
wp_upload_media_from_urlwill not follow; - the source is behind authentication;
- the source is on a private network, which the URL tool refuses.
What it returns
The created attachment in the standard shape: id, title, url, mime_type, alt, caption, description and date.
Keep the id. Setting alt text, assigning a featured image and placing the image all refer to it.
What it does not do
- It does not set alt text. Uploading creates an attachment with empty alt text. Set it with
wp_update_media. - It does not assign a featured image.
post_idattaches the upload to a post in the library sense, which is not the same as making it the featured image. Seewp_set_featured_image. - It does not resize. WordPress generates its registered sizes from what you send, so a small original stays small.
Using it well
Upload this image as "workshop-interior.jpg", then show me the attachment ID and URL.
Then, as separate steps:
Set the alt text to "…".
Set it as the featured image for post 412.
Common problems
| Symptom | Cause |
|---|---|
| The write is refused | Content write gate closed |
pom_ai_mcp_forbidden |
The acting user lacks upload_files |
pom_ai_mcp_invalid_media |
The payload is empty, not valid base64, or over 10 MB decoded |
pom_ai_mcp_media_extension_denied |
The filename extension is not an accepted image type |
pom_ai_mcp_media_mime_denied |
The file contents are not an accepted image type |
pom_ai_mcp_temp_file_failed |
The server could not write a temporary file |
| The image is too small on the page | The source resolution; nothing here upscales |