Media

Understand which media operations are discoverable through MCP and how to handle multipart uploads.

Media resources cover uploaded images and files used by companies, blog posts, and job board presentation. Use the staged upload tools for real files so binary data never has to fit inside execute source code.

Discover media metadata operations

javascript
async () => Object.keys(spec.paths).filter((path) =>
path.startsWith('/media') || path.includes('/logo')
)

Upload a real file without inlining it in execute

  1. Call create_media_upload_intent with the filename, MIME type, exact byte length, purpose, and optional resource fields.
  2. POST the original file bytes directly to the returned uploadUrl. The direct-upload response contains a storageId.
  3. Call complete_media_upload_intent with the intent ID and that storageId.

Completion compares the declared byte length and MIME type with storage-owned metadata before processing. A mismatch fails the upload. The resulting response is the normal media object whose id can be assigned to coverMediaId, ogImageMediaId, or another media-reference field.

The upload URL is a short-lived bearer capability: protect it like a credential. The intent completion is bound to the account and MCP actor that created it. Do not put the file bytes, base64, or a caller-supplied Content-Type header in an execute call.

Keep small FormData uploads working

execute can still upload bytes that are already small enough to be present inside the invocation by passing FormData to cavuno.request:

javascript
async () => {
const bytes = Uint8Array.of(1, 2, 3); // A tiny probe only.
const form = new FormData();
form.append('file', new Blob([bytes], { type: 'image/png' }), 'cover.png');
form.append('purpose', 'blog_image');
return cavuno.request({
method: 'POST',
path: '/media/upload',
body: form,
});
}

Do not set Content-Type; cavuno.request encodes the form and supplies the multipart boundary. Use this path only when the bytes already fit naturally in the invocation. Do not compress a real cover to make it fit.

After an upload, retrieve the affected company or blog post and confirm that its public media URL resolves. Blog post writes attach the returned media ID with coverMediaId or ogImageMediaId, not the signed URL.