Skip to main content
Glama

add_media

Store files in the media library and append them to posts, in one call.

Exactly one source: file, url / urls, upload, or media_ids / media_urls (already in the library, from list_media).

attach_to_post_ids lists every post it goes on; nothing already there is removed (attach_media sets the exact list). The result names the posts that got it (attached), those that did not and why (notAttached), and those that still cannot publish (publishBlockers). A file is never read into the call as base64.

PNG, JPEG, GIF, WebP, AVIF images up to 10 MB (converted to the platform's format at publish, so never re-export one); MP4, MOV, WebM video and PDF up to 1 GB by upload, 100 MB by url or file.

Shorts, Reels, TikToks and stories are vertical (9:16) video, made vertical from the start: a landscape video shrunk onto a blurred or padded vertical frame reads as a repost, so make a vertical cut instead. On YouTube only a vertical or square video of three minutes or less is a Short.

Args: file: A file the user attached to a ChatGPT conversation. ChatGPT fills it in and Antwork downloads it; it is never synthesized. ChatGPT's mobile apps send no usable file, which the result says. url: Public HTTPS URL of the file (e.g. an AI-generated image already hosted), or a Google Drive, Docs, Slides, Dropbox or OneDrive share link as the user copied it. Antwork downloads it. urls: Up to 10 such links in one call, e.g. a carousel's slides, in order; results has one entry per link. If any fails, none is attached (stored ones are in results). upload: A file in a shell or code-execution sandbox: {} returns a one-time uploadUrl (10 minutes), and curl -sS -X PUT --data-binary @<path> '<uploadUrl>' stores and attaches it; that response is the result. mime_type and byte_size are optional. media_ids: Library media ids to add to the posts. media_urls: Library media URLs to add to the posts. attach_to_post_ids: Every post to add the media to. workspace_id: Workspace ID or name. Optional if the user has only one. fit: "crop" (centre) or "pad" (blurred background): each image on attach_to_post_ids whose aspect ratio the post's platform refuses is replaced by a copy at the nearest ratio it takes (the original stays in the library; fitted lists the copies). Images only. With no source, it fits the posts' current media.

Tool call template

This tool declares no required parameters. Add optional parameters from the input schema as needed.

{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "arguments": {},
    "name": "add_media"
  }
}

Input Schema

NameRequiredDescriptionDefault
fitNo
urlNo
fileNo
urlsNo
uploadNo
contextNoThe user's underlying goal for this call, in one sentence without personal details. Used for product analytics only.
llm_modelNoThe model identifier of the calling assistant, or "unknown". Used for product analytics only.
media_idsNo
media_urlsNo
workspace_idNo
conversation_idNoPass the exact conversation_id from the server's previous response, unchanged. The server provides it on the first call — never invent one, and do not issue parallel tool calls until you have it. Keep passing the same conversation_id for the rest of the conversation, including after later user messages or on a different task; do not reset it when the user starts a new request.
attach_to_post_idsNo

Output Schema

NameRequiredDescriptionDefault
_mcp_instructionsNoServer-issued metadata for this conversation.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed2 schema fields changed
    • addedInput schema / properties / fit
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "title": "Fit"
      +}
    • addedInput schema / properties / urls
      Added value: +{
      +  "anyOf": [
      +    {
      +      "items": {
      +        "type": "string"
      +      },
      +      "type": "array"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "title": "Urls"
      +}
  2. Changed1 schema field changed
    • changedInput schema / required
      Previous value: -[
      -  "context",
      -  "llm_model"
      -]New value: +[]
  3. First observed

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations (readOnlyHint=false, destructiveHint=false) are matched, not contradicted, and the description adds substantial behavior beyond them: nothing already attached is removed, the result splits into attached/notAttached/publishBlockers, urls is all-or-nothing, the upload flow returns a 10-minute one-time URL with the exact curl command, and files are never inlined as base64.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Well front-loaded: the one-source rule and the attach semantics precede the format limits and the vertical-video advice. It is long for a tool description, and the Shorts/Reels/9:16 paragraph and the 'never re-export one' aside are advisory padding that could be tightened without losing call correctness.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 12-parameter, nested-object, open-world tool this is thorough: source exclusivity, size/format limits, the two-step upload flow, result key names, and the fit-copy side effect are all covered. An output schema exists, so the description does not need to enumerate return values and appropriately does not.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is only 25% across 12 parameters, so the description carries the burden and does: it defines file, url, urls, upload, media_ids, media_urls, attach_to_post_ids, workspace_id and fit with concrete meaning and limits (10 links max, 10 MB images, 1 GB upload vs 100 MB url/file, crop vs pad and how fitted copies behave). Only the analytics parameters are left to the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb+resource+scope: 'Store files in the media library and append them to posts, in one call.' It immediately separates itself from sibling attach_media by noting that this tool adds to the existing list while attach_media sets the exact list.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

States the hard selection rule up front ('Exactly one source') and enumerates the mutually exclusive options. It also gives conditional guidance for each source (file from a ChatGPT conversation, url for hosted/Drive links, urls for carousels, upload for sandboxes) and names the sibling alternative for replacement semantics.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.