Skip to main content
Glama
Upload-Post

Upload-Post

Official

Upload video

upload_video

Publish a video to one or more social platforms (TikTok, Instagram, YouTube, etc.) with captions, scheduling, and per-platform options. Returns a request_id for status polling.

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.). Reddit posting is currently unavailable (error_code=reddit_unavailable) until the Reddit app is restored. Do not use reddit as a publish target. 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.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
userYesProfile name (Upload-Post user).
titleNoCaption / title.
timezoneNoIANA timezone for scheduled date, e.g. 'Europe/Madrid'.
platformsYesRequired 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.
addToQueueNoInsert into the user's posting queue instead of publishing now.
asyncUploadNoReturn immediately with request_id (default true).
descriptionNo
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).
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.
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

TableJSON Schema
NameRequiredDescriptionDefault
resultNo

Schema Changelog

Changes observed during successful MCP inspections.

  1. 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#"
  2. 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"
      +}
  3. 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"
      +]
  4. First observedv0.4.0

TDQS

A4.6/5.0
Behavior5/5

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

Beyond annotations (readOnlyHint=false, openWorldHint=true), the description discloses the asynchronous return (request_id to poll with get_status), the reddit_unavailable error, the 24-hour deletion of staged media, and the limitation of hosted servers regarding local file access. This is rich behavioral context that annotations alone do not provide.

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?

The description is long but well-structured, starting with the core purpose, then input options, then caveats, and a numbered staging workflow. Each sentence provides necessary information and the length is justified by the tool's complexity. It is front-loaded with the primary action.

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 tool with 14 parameters and a nested platformOptions object, the description covers the essential flows: how to provide the video, how to handle local files, the return mechanism, and the reddit restriction. The output schema exists, so return values are already documented. Nothing an agent needs to call it correctly is missing.

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 description coverage is 86%, so the schema carries most parameter documentation. The description adds meaningful value for the two main input methods (videoPathOrUrl and videoBase64) with constraints and use cases, and explains the staging workflow. It does not repeat all parameter details, but the added context is substantial beyond 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?

The description opens with a specific verb+resource: 'Publish a video to one or more platforms.' This clearly distinguishes it from sibling tools like upload_photos and upload_text, and the mention of per-platform overrides adds clarity. No ambiguity about what the tool does.

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

Usage Guidelines4/5

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

It gives concrete conditions for choosing videoPathOrUrl vs videoBase64, explains the staging workflow for local files, and explicitly warns not to use reddit as a target. It doesn't explicitly compare with other upload tools, but the purpose is self-evident and the guidance is actionable.

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