Skip to main content
Glama
Upload-Post

Upload-Post

Official

Upload photos / carousel

upload_photos

Publishes one or more photos as single posts or carousels to multiple social platforms, with per-platform captions and a required preview confirmation before anything is sent.

Instructions

Publish one or more photos (single image or carousel; items are published in array order). Each item in photosPathsOrUrls must be a public/signed HTTPS URL (a staged media_url from complete_media_upload works), or an absolute local path only when the MCP server runs on the same machine as the file. One call can carry a different caption per platform: title is the default and platformOptions.facebookTitle, platformOptions.instagramTitle, platformOptions.linkedinTitle, platformOptions.xTitle, … override it for that platform. A hosted MCP server cannot read files on the user's machine or chat attachments (/mnt/data, sandbox paths). To publish a local file: (1) if this client can run HTTP requests itself (for example a coding agent with a shell), stage it with create_media_upload (returns upload_id + upload_url), PUT the raw file bytes to upload_url with the same Content-Type, call complete_media_upload and pass the returned media_url as the media URL; (2) otherwise ask the user for a public HTTPS URL of the file, or tell them to publish it from the dashboard at https://app.upload-post.com. Staged media is deleted after 24 hours. Needs the user's approval: call it first without confirmed to get a preview (nothing is sent), show the user exactly what will go out, and repeat the call with confirmed: true only after they approve.

Input Schema

NameRequiredDescriptionDefault
userYes
titleNo
altTextNo
timezoneNoIANA timezone for scheduled date, e.g. 'Europe/Madrid'.
confirmedNoSet to true only after the user has seen the preview this tool returns without it and approved it. Without it nothing is sent.
platformsYesRequired array of platform identifiers.
addToQueueNoInsert into the user's posting queue instead of publishing now.
asyncUploadNoReturn immediately with request_id (default true).
descriptionNoDescription for the platforms that take one, unless a per-platform override is set. TikTok ignores it: set `platformOptions.tiktokDescription` for the TikTok description; the TikTok title comes from `platformOptions.tiktokTitle`, or `title`.
firstCommentNoComment auto-posted under the post right after publishing. Supported on every platform that has comments, TikTok included. Use `platformOptions.<platform>FirstComment` to override it for one platform. X: links can be removed from X posts and first comments, depending on the account, so a 'link in the first comment' may go out without the URL; check `warnings` in get_status after publishing.
scheduledDateNoISO 8601 date for scheduled publishing, e.g. '2026-12-25T10:00:00Z'. Omit for immediate post.
maxPostsPerSlotNo
platformOptionsNoFlat platform-specific override object with camelCase keys. Per-platform text overrides (instagramTitle, xFirstComment, …) are also accepted. Keys the upload-post SDK does not support are silently ignored upstream.
photosPathsOrUrlsYesPhoto URLs (or same-machine local paths), in carousel order. Never `/mnt/data` or sandbox attachment paths.

Output Schema

NameRequiredDescriptionDefault
resultNo

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed10 schema fields changedv0.17.2
    • addedInput schema / properties / confirmed
      Added value: +{
      +  "description": "Set to true only after the user has seen the preview this tool returns without it and approved it. Without it nothing is sent.",
      +  "type": "boolean"
      +}
    • addedInput schema / properties / description / description
      Added value: +"Description for the platforms that take one, unless a per-platform override is set. TikTok ignores it: set `platformOptions.tiktokDescription` for the TikTok description; the TikTok title comes from `platformOptions.tiktokTitle`, or `title`."
    • changedInput schema / properties / firstComment / description
      Previous value: -"Comment auto-posted under the post right after publishing. Supported on every platform that has comments, TikTok included. Use `platformOptions.<platform>FirstComment` to override it for one platform."New value: +"Comment auto-posted under the post right after publishing. Supported on every platform that has comments, TikTok included. Use `platformOptions.<platform>FirstComment` to override it for one platform. X: links can be removed from X posts and first comments, depending on the account, so a 'link in the first comment' may go out without the URL; check `warnings` in get_status after publishing."
    • addedInput schema / properties / photosPathsOrUrls / description
      Added value: +"Photo URLs (or same-machine local paths), in carousel order. Never `/mnt/data` or sandbox attachment paths."
    • changedInput schema / properties / platformOptions / description
      Previous value: -"Flat platform-specific override object with camelCase keys. Per-platform text overrides (instagramTitle, xFirstComment, …) are also accepted. Keys the upload-post SDK does not support are silently ignored upstream. Reddit posting is currently unavailable (error_code=reddit_unavailable) until the Reddit app is restored. Do not use reddit as a publish target."New value: +"Flat platform-specific override object with camelCase keys. Per-platform text overrides (instagramTitle, xFirstComment, …) are also accepted. Keys the upload-post SDK does not support are silently ignored upstream."
    • changedInput schema / properties / platformOptions / properties / redditFlairId / description
      Previous value: -"Reddit posting is currently unavailable (error_code=reddit_unavailable) until the Reddit app is restored. Do not use reddit as a publish target."New value: +"Reddit only."
    • changedInput schema / properties / platformOptions / properties / redditSubreddit / description
      Previous value: -"Reddit posting is currently unavailable (error_code=reddit_unavailable) until the Reddit app is restored. Do not use reddit as a publish target."New value: +"Reddit only."
    • changedInput schema / properties / platforms / description
      Previous value: -"Required array of platform identifiers. Reddit posting is currently unavailable (error_code=reddit_unavailable) until the Reddit app is restored. Do not use reddit as a publish target."New value: +"Required array of platform identifiers."
    • changedInput schema / properties / platforms / items / description
      Previous value: -"Target social platform. Reddit posting is currently unavailable (error_code=reddit_unavailable) until the Reddit app is restored. Do not use reddit as a publish target."New value: +"Target social platform."
    • changedInput schema / properties / platforms / items / enum
      Previous value: -[
      -  "tiktok",
      -  "instagram",
      -  "linkedin",
      -  "facebook",
      -  "pinterest",
      -  "threads",
      -  "reddit",
      -  "bluesky",
      -  "x",
      -  "google_business",
      -  "discord",
      -  "telegram",
      -  "mastodon",
      -  "lemmy",
      -  "wordpress"
      -]New value: +[
      +  "tiktok",
      +  "instagram",
      +  "linkedin",
      +  "facebook",
      +  "pinterest",
      +  "threads",
      +  "bluesky",
      +  "x",
      +  "google_business",
      +  "discord",
      +  "telegram",
      +  "mastodon",
      +  "lemmy",
      +  "wordpress"
      +]
  2. Changed20 schema fields changedv0.11.1
    • removedInput schema / $schema
      Removed value: -"http://json-schema.org/draft-07/schema#"
    • addedInput schema / properties / firstComment / description
      Added value: +"Comment auto-posted under the post right after publishing. Supported on every platform that has comments, TikTok included. Use `platformOptions.<platform>FirstComment` to override it for one platform."
    • changedInput schema / properties / platformOptions / description
      Previous value: -"Flat platform-specific override object with camelCase keys. Per-platform text overrides (instagramTitle, xFirstComment, …) are also accepted. Keys the upload-post SDK does not support are silently ignored upstream."New value: +"Flat platform-specific override object with camelCase keys. Per-platform text overrides (instagramTitle, xFirstComment, …) are also accepted. Keys the upload-post SDK does not support are silently ignored upstream. Reddit posting is currently unavailable (error_code=reddit_unavailable) until the Reddit app is restored. Do not use reddit as a publish target."
    • changedInput schema / properties / platformOptions / properties / redditFlairId / description
      Previous value: -"Reddit flair template ID."New value: +"Reddit posting is currently unavailable (error_code=reddit_unavailable) until the Reddit app is restored. Do not use reddit as a publish target."
    • changedInput schema / properties / platformOptions / properties / redditSubreddit / description
      Previous value: -"Subreddit name, without r/."New value: +"Reddit posting is currently unavailable (error_code=reddit_unavailable) until the Reddit app is restored. Do not use reddit as a publish target."
    • addedInput schema / properties / platformOptions / properties / replyToId
      Added value: +{
      +  "description": "Publish as a reply to an existing post (X: tweet ID; Bluesky: post URL or AT-URI). On X's Pay-Per-Use tier a reply to an author the account has not engaged with is rejected with 403.",
      +  "type": "string"
      +}
    • addedInput schema / properties / platformOptions / properties / tiktokFirstComment
      Added value: +{
      +  "description": "First comment posted under the TikTok post, overriding the shared `firstComment` for TikTok only. Requires the 'comments' capability on the profile's TikTok account (see the `capabilities` array in list_users).",
      +  "type": "string"
      +}
    • addedInput schema / properties / platformOptions / properties / tiktokIsAiGenerated
      Added value: +{
      +  "description": "Disclose the photo post as AI-generated content.",
      +  "type": "boolean"
      +}
    • addedInput schema / properties / platformOptions / properties / tiktokLocationId
      Added value: +{
      +  "description": "Location to tag — pass a `location_id` from tiktok_location_search. Must be sent together with tiktokLocationName. Needs the `location` capability (see tiktokMusicId).",
      +  "type": "string"
      +}
    • addedInput schema / properties / platformOptions / properties / tiktokLocationName
      Added value: +{
      +  "description": "Name of the tagged location, from tiktok_location_search. TikTok requires it whenever tiktokLocationId is set.",
      +  "type": "string"
      +}
    • addedInput schema / properties / platformOptions / properties / tiktokMusicId
      Added value: +{
      +  "description": "Commercial Music Library track to add to the photo post — pass a track `id` from tiktok_music_trending or tiktok_music_search (the `id` field, not `commercial_music_id`). TikTok's photo posts take the id alone: there is no volume or trim. Available on connections that declare the `music` capability (see `capabilities` on the TikTok account in list_users); otherwise the field is ignored, the post still publishes and the response includes a per-field warning.",
      +  "type": "string"
      +}
    • changedInput schema / properties / platformOptions / properties / tiktokPhotoCoverIndex / description
      Previous value: -"Index of the cover photo, 0-based."New value: +"Index of the cover photo, 0-based. Sent as `photo_cover_index`; picks the cover of a TikTok photo post."
    • addedInput schema / properties / platformOptions / properties / tiktokPhotoCoverIndex / minimum
      Added value: +0
    • addedInput schema / properties / platformOptions / properties / tiktokPostMode
      Added value: +{
      +  "description": "Send to TikTok drafts/inbox. Same flag for every TikTok account; do not pick a different field for Business. MEDIA_UPLOAD (or tiktokUploadToDraft=true) sends the post to drafts/inbox. DIRECT_POST publishes now.",
      +  "enum": [
      +    "DIRECT_POST",
      +    "MEDIA_UPLOAD"
      +  ],
      +  "type": "string"
      +}
    • addedInput schema / properties / platformOptions / properties / tiktokPrivacyLevel
      Added value: +{
      +  "description": "TikTok privacy value: PUBLIC_TO_EVERYONE, MUTUAL_FOLLOW_FRIENDS, FOLLOWER_OF_CREATOR, SELF_ONLY. TikTok requires one on photo posts (defaults to PUBLIC_TO_EVERYONE) and decides per account which values are available.",
      +  "type": "string"
      +}
    • addedInput schema / properties / platformOptions / properties / tiktokUploadToDraft
      Added value: +{
      +  "description": "Send to TikTok drafts/inbox. Same flag for every TikTok account; do not pick a different field for Business. Set true, or tiktokPostMode=MEDIA_UPLOAD.",
      +  "type": "boolean"
      +}
    • addedInput schema / properties / platformOptions / properties / xReplyToId
      Added value: +{
      +  "description": "Alias of replyToId, scoped to X: the tweet ID to reply to.",
      +  "type": "string"
      +}
    • addedInput schema / properties / platforms / description
      Added value: +"Required array of platform identifiers. Reddit posting is currently unavailable (error_code=reddit_unavailable) until the Reddit app is restored. Do not use reddit as a publish target."
    • addedInput schema / properties / platforms / items / description
      Added value: +"Target social platform. Reddit posting is currently unavailable (error_code=reddit_unavailable) until the Reddit app is restored. Do not use reddit as a publish target."
    • removedOutput schema / $schema
      Removed value: -"http://json-schema.org/draft-07/schema#"
  3. Changed6 schema fields changedv0.7.0
    • removedInput schema / properties / autogenerate
      Removed value: -{
      -  "description": "If true, AI generates native per-platform title/description from the media and fills any field left empty.",
      -  "type": "boolean"
      -}
    • removedInput schema / properties / autogenerateDescription
      Removed value: -{
      -  "description": "Generate only the description with AI.",
      -  "type": "boolean"
      -}
    • removedInput schema / properties / autogenerateLanguage
      Removed value: -{
      -  "description": "Force the AI output language (ISO code); omit to auto-detect from the media.",
      -  "type": "string"
      -}
    • removedInput schema / properties / autogenerateTitle
      Removed value: -{
      -  "description": "Generate only the title with AI.",
      -  "type": "boolean"
      -}
    • addedInput schema / properties / platformOptions / properties / gbpMediaCategory
      Added value: +{
      +  "description": "Google Business gallery category for the uploaded photo. Only used with gbpPostType. Defaults to ADDITIONAL.",
      +  "enum": [
      +    "COVER",
      +    "PROFILE",
      +    "LOGO",
      +    "EXTERIOR",
      +    "INTERIOR",
      +    "PRODUCT",
      +    "AT_WORK",
      +    "FOOD_AND_DRINK",
      +    "MENU",
      +    "COMMON_AREA",
      +    "ROOMS",
      +    "TEAMS",
      +    "ADDITIONAL"
      +  ],
      +  "type": "string"
      +}
    • addedInput schema / properties / platformOptions / properties / gbpPostType
      Added value: +{
      +  "description": "Publish into the Google Business location's photo gallery instead of creating a Local Post. Omitting it keeps the Local Post behaviour.",
      +  "enum": [
      +    "MEDIA",
      +    "PHOTO",
      +    "GALLERY"
      +  ],
      +  "type": "string"
      +}
  4. Changed1 schema field changedv0.5.0
    • changedInput schema / properties / platforms / items / enum
      Previous value: -[
      -  "tiktok",
      -  "instagram",
      -  "linkedin",
      -  "facebook",
      -  "pinterest",
      -  "threads",
      -  "reddit",
      -  "bluesky",
      -  "x",
      -  "google_business",
      -  "discord",
      -  "telegram"
      -]New value: +[
      +  "tiktok",
      +  "instagram",
      +  "linkedin",
      +  "facebook",
      +  "pinterest",
      +  "threads",
      +  "reddit",
      +  "bluesky",
      +  "x",
      +  "google_business",
      +  "discord",
      +  "telegram",
      +  "mastodon",
      +  "lemmy",
      +  "wordpress"
      +]
  5. First observedv0.4.0

TDQS

A4.7/5.0
Behavior5/5

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

Goes well past the annotations (readOnly=false, destructive=false, openWorld=true) by disclosing the two-phase preview/confirm gate ('nothing is sent' without `confirmed`), the 24-hour TTL on staged media, the local-file access limitation for hosted servers, and the per-platform caption override mechanics. These are real behavioral traits an agent would otherwise have to discover by failing.

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?

Front-loaded with the core capability and media-source rule before the staging workflow, and every paragraph carries actionable information. The staging walkthrough is the longest block; it is justified but could be tightened into a pointer to create_media_upload/complete_media_upload.

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

Completeness4/5

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

Covers the hard parts — media sourcing, ordering, approval gating, 24h cleanup — and an output schema exists so return values needn't be described. It omits any mention of scheduling, queue insertion, or async behavior even though the schema exposes `scheduledDate`, `addToQueue`, and `asyncUpload`, which is the main remaining gap.

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

Parameters4/5

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

Schema coverage is a moderate 71%, and the description adds genuine meaning beyond it: that `photosPathsOrUrls` is ordered for carousels and rejects sandbox paths, that `title` is a default with `platformOptions.<platform>Title` overrides, and how `confirmed` interacts with the preview. It doesn't touch the many platform-specific options (scheduling, queueing, TikTok music/location), leaving those 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?

States a specific verb and resource ('Publish one or more photos') plus scope ('single image or carousel; items are published in array order'). The resource name alone separates it from the sibling upload_video / upload_text / upload_document tools, so an agent can route correctly without opening a schema.

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?

Explicitly states when the tool works (public/signed HTTPS URLs, or same-machine absolute paths) and when it cannot (hosted server cannot read the user's disk, `/mnt/data`, sandbox attachments), then prescribes the exact alternatives: stage via create_media_upload → complete_media_upload, or ask the user for a public URL, or send them to the dashboard. It also spells out the approval protocol — call without `confirmed` first, show the preview, then repeat with `confirmed: true`.

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