Skip to main content
Glama
Upload-Post

Upload-Post

Official

Upload video

upload_video

Publish a video to multiple social platforms with per-platform settings and return a request ID for status tracking.

Instructions

Publish a video to one or more platforms. Use videoPathOrUrl only for public/signed HTTPS URLs, or for absolute local paths when the MCP server runs on the same machine as the file. videoBase64 is only for clients that can provide raw bytes directly and is capped by UPLOAD_POST_MAX_INLINE_MB (default 100). Returns a request_id you can poll with get_status. Supports per-platform overrides (tiktokPrivacyLevel, youtubePrivacyStatus, youtubePlaylistId, youtubeThumbnailUrl, youtubeTags, facebookPageId, instagramMediaType, etc.). 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
userYesProfile name (Upload-Post user).
titleNoCaption / title.
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, e.g. ['instagram']. Never pass a single string.
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`.
videoBase64NoVideo bytes as base64 (or a data: URI). Provide this OR videoPathOrUrl. The server writes it to a temp file, uploads, then deletes it. Capped by UPLOAD_POST_MAX_INLINE_MB (default 100); over HTTP the whole request is also capped by UPLOAD_POST_MCP_MAX_BODY_MB (default 10), so use videoPathOrUrl for anything larger.
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.
videoFilenameNoOptional filename (e.g. 'clip.mp4') used only to pick the temp file extension when videoBase64 is given. Defaults to .mp4.
videoPathOrUrlNoPublic/signed HTTPS URL of the video (a staged `media_url` from complete_media_upload also works). Absolute local paths are supported only for local/self-hosted MCP clients sharing the same filesystem. Never pass `/mnt/data`, sandbox, or other mounted attachment paths: the server cannot read them.
maxPostsPerSlotNo
platformOptionsNoPlatform-specific overrides as a flat object (camelCase keys), e.g. { tiktokPrivacyLevel: 'PUBLIC_TO_EVERYONE', youtubePrivacyStatus: 'public', youtubePlaylistId: 'PLxxxxxxxxxxxx', facebookPageId: '123' }. `youtubePlaylistId` may also be an array or a comma-separated list of playlist IDs to add the uploaded video to. The `tiktokMusic*`, `tiktokLocation*`, and `tiktokCoverImageUrl` keys depend on the TikTok connection's `capabilities` (see list_users); discover valid values with tiktok_music_trending and tiktok_location_search. tiktokPostMode=MEDIA_UPLOAD and tiktokUploadToDraft=true are the same draft/inbox flag for every TikTok account.

Output Schema

NameRequiredDescriptionDefault
resultNo

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed7 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."
    • changedInput schema / properties / platforms / description
      Previous value: -"Required array of platform identifiers, e.g. ['instagram']. Never pass a single string. 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, e.g. ['instagram']. Never pass a single string."
    • 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",
      -  "youtube",
      -  "linkedin",
      -  "facebook",
      -  "pinterest",
      -  "threads",
      -  "reddit",
      -  "bluesky",
      -  "x",
      -  "google_business",
      -  "discord",
      -  "telegram",
      -  "mastodon",
      -  "wordpress"
      -]New value: +[
      +  "tiktok",
      +  "instagram",
      +  "youtube",
      +  "linkedin",
      +  "facebook",
      +  "pinterest",
      +  "threads",
      +  "bluesky",
      +  "x",
      +  "google_business",
      +  "discord",
      +  "telegram",
      +  "mastodon",
      +  "wordpress"
      +]
    • changedInput schema / properties / videoBase64 / description
      Previous value: -"Video bytes as base64 (or a data: URI). Provide this OR videoPathOrUrl. The server writes it to a temp file, uploads, then deletes it. Capped by UPLOAD_POST_MAX_INLINE_MB (default 100)."New value: +"Video bytes as base64 (or a data: URI). Provide this OR videoPathOrUrl. The server writes it to a temp file, uploads, then deletes it. Capped by UPLOAD_POST_MAX_INLINE_MB (default 100); over HTTP the whole request is also capped by UPLOAD_POST_MCP_MAX_BODY_MB (default 10), so use videoPathOrUrl for anything larger."
  2. Changed22 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: -"Platform-specific overrides as a flat object (camelCase keys), e.g. { tiktokPrivacyLevel: 'PUBLIC_TO_EVERYONE', youtubePrivacyStatus: 'public', youtubePlaylistId: 'PLxxxxxxxxxxxx', facebookPageId: '123' }. `youtubePlaylistId` may also be an array or a comma-separated list of playlist IDs to add the uploaded video to."New value: +"Platform-specific overrides as a flat object (camelCase keys), e.g. { tiktokPrivacyLevel: 'PUBLIC_TO_EVERYONE', youtubePrivacyStatus: 'public', youtubePlaylistId: 'PLxxxxxxxxxxxx', facebookPageId: '123' }. `youtubePlaylistId` may also be an array or a comma-separated list of playlist IDs to add the uploaded video to. The `tiktokMusic*`, `tiktokLocation*`, and `tiktokCoverImageUrl` keys depend on the TikTok connection's `capabilities` (see list_users); discover valid values with tiktok_music_trending and tiktok_location_search. tiktokPostMode=MEDIA_UPLOAD and tiktokUploadToDraft=true are the same draft/inbox flag for every TikTok account."
    • 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 / tiktokCoverImageUrl
      Added value: +{
      +  "description": "Custom cover image URL. Takes priority over tiktokCoverTimestamp. Needs the `cover_image` capability (see tiktokMusicId).",
      +  "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 video 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 / tiktokMusicEnd
      Added value: +{
      +  "description": "End offset of the music track, in milliseconds.",
      +  "minimum": 0,
      +  "type": "integer"
      +}
    • addedInput schema / properties / platformOptions / properties / tiktokMusicId
      Added value: +{
      +  "description": "Commercial Music Library track to add to the video — pass a track `id` from tiktok_music_trending (the `id` field, not `commercial_music_id`). 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 — reconnect the TikTok account to enable it.",
      +  "type": "string"
      +}
    • addedInput schema / properties / platformOptions / properties / tiktokMusicStart
      Added value: +{
      +  "description": "Start offset of the music track, in milliseconds.",
      +  "minimum": 0,
      +  "type": "integer"
      +}
    • addedInput schema / properties / platformOptions / properties / tiktokMusicVolume
      Added value: +{
      +  "description": "Volume of the added music track, 0-100. Defaults to 50 when music is set.",
      +  "maximum": 100,
      +  "minimum": 0,
      +  "type": "integer"
      +}
    • addedInput schema / properties / platformOptions / properties / tiktokOriginalSoundVolume
      Added value: +{
      +  "description": "Volume of the video's own audio when music is added, 0-100. Defaults to 50 so the original audio is not muted.",
      +  "maximum": 100,
      +  "minimum": 0,
      +  "type": "integer"
      +}
    • changedInput schema / properties / platformOptions / properties / tiktokPostMode / description
      Previous value: -"TikTok post mode. DIRECT_POST publishes straight to the account. MEDIA_UPLOAD (Draft) sends the video to the user's TikTok inbox/drafts to publish from the app — RECOMMENDED for TikTok, as publishing natively from the app tends to get more organic reach. Note: in Draft mode TikTok ignores the title/caption and other metadata sent via API; the user adds them in the app before publishing. Defaults to DIRECT_POST."New value: +"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 video to drafts/inbox. DIRECT_POST publishes now."
    • changedInput schema / properties / platformOptions / properties / tiktokPrivacyLevel / description
      Previous value: -"TikTok privacy value, e.g. PUBLIC_TO_EVERYONE, MUTUAL_FOLLOW_FRIENDS, FOLLOWER_OF_CREATOR, SELF_ONLY."New value: +"TikTok privacy value: PUBLIC_TO_EVERYONE, MUTUAL_FOLLOW_FRIENDS, FOLLOWER_OF_CREATOR, SELF_ONLY. TikTok decides per account which of these are available (a private account has no PUBLIC_TO_EVERYONE); asking for another one fails with error_code tiktok_privacy_unavailable listing the allowed ones. Omit it to keep the account's own default."
    • 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"
      +}
    • changedInput schema / properties / platforms / description
      Previous value: -"Required array of platform identifiers, e.g. ['instagram']. Never pass a single string."New value: +"Required array of platform identifiers, e.g. ['instagram']. Never pass a single string. 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."
    • changedInput schema / properties / videoPathOrUrl / description
      Previous value: -"Public/signed HTTPS URL of the video. Absolute local paths are supported only for local/self-hosted MCP clients sharing the same filesystem. Do not pass ChatGPT `/mnt/data` or sandbox paths; use open_upload_studio instead."New value: +"Public/signed HTTPS URL of the video (a staged `media_url` from complete_media_upload also works). Absolute local paths are supported only for local/self-hosted MCP clients sharing the same filesystem. Never pass `/mnt/data`, sandbox, or other mounted attachment paths: the server cannot read them."
    • 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",
      -  "youtube",
      -  "linkedin",
      -  "facebook",
      -  "pinterest",
      -  "threads",
      -  "bluesky",
      -  "x",
      -  "google_business",
      -  "discord",
      -  "telegram"
      -]New value: +[
      +  "tiktok",
      +  "instagram",
      +  "youtube",
      +  "linkedin",
      +  "facebook",
      +  "pinterest",
      +  "threads",
      +  "reddit",
      +  "bluesky",
      +  "x",
      +  "google_business",
      +  "discord",
      +  "telegram",
      +  "mastodon",
      +  "wordpress"
      +]
  5. First observedv0.4.0

TDQS

A4.8/5.0
Behavior5/5

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

Annotations declare non-read-only and open-world, and the description goes substantially beyond them: nothing is published without confirmed, the first call is a dry-run preview, staged media is deleted after 24 hours, hosted servers cannot read /mnt/data or sandbox paths, and per-field capability warnings appear in the response. These are the operational traps an agent would otherwise hit.

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?

Purpose and source-mode limits lead, then the approval protocol, so it is well front-loaded. It is on the long side and the staged-upload walkthrough could be tightened, but every sentence carries operational information rather than repetition.

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 15-parameter publishing tool with nested platformOptions and an open-world annotation, the description covers the source-of-bytes decision, the approval gate, the async request_id handoff, and the capability caveats. Because an output schema exists, it does not need to enumerate return fields, and it still mentions request_id only as a pointer to get_status.

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 93%, so 3 is the baseline, but the description adds real constraints the schema alone does not emphasize: local paths only work on a colocated server, base64 is bounded by both UPLOAD_POST_MAX_INLINE_MB and the HTTP body cap, and per-platform overrides take precedence over the shared title/description. It does not attempt to explain the long platformOptions key space, which is correctly 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 statement ('Publish a video to one or more platforms') and immediately signals multi-platform scope. An agent can tell this apart from upload_photos, upload_text, and upload_document without opening any 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 routes between the two source modes (videoPathOrUrl for public/signed HTTPS or colocated absolute paths; videoBase64 only for raw-byte clients with the size cap) and gives a numbered fallback procedure (create_media_upload -> PUT -> complete_media_upload, or ask the user, or dashboard). It also states exactly when to send confirmed:true versus the preview call.

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