Skip to main content
Glama

post_publish

Destructive

Publish a post to specified social media profiles. Supports text content, media attachments, scheduling, drafts, threads (X and Threads only), and platform-specific customization via the 'platforms' parameter.

Input Schema

NameRequiredDescriptionDefault
draftNoIf true, creates a draft post that won't publish automatically
mediaNoOptional array of media URLs or local file paths (images or videos). File paths can be absolute (/path/to/file.jpg), relative (./image.png), or use ~ for home directory (~/Pictures/photo.jpg)
threadNoOptional array of thread child posts (supported on X/Twitter and Threads only). The parent post is published first, then each child is published as a reply in order.
contentNoPost content text (caption/description). Required except for Stories: when instagram/facebook format is 'story', omit it or pass an empty string — Stories can't carry body text.
profilesYesArray of profile IDs (hashids) or platform names (e.g., 'linkedin', 'instagram', 'twitter'). When using platform names, posts to the first connected profile for that platform.
queue_idNoOptional queue ID to add the post to. The queue will automatically assign a timeslot. Do not use together with 'schedule'.
scheduleNoOptional ISO 8601 scheduled time (e.g., '2024-12-31T23:59:59Z')
platformsNoPlatform-specific parameters. Keys are platform names, values are parameter objects. Use this to add collaborators, set video titles, privacy settings, etc.
queue_priorityNoOptional priority when adding to a queue (default: medium). Higher priority posts get earlier timeslots.
idempotency_keyNoOptional idempotency key for request deduplication
require_confirmationNoIf true, return summary without publishing (dry run)

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed9 schema fields changed
    • changedInput schema / properties / platforms / properties / bluesky / description
      Previous value: -"Bluesky: No platform-specific parameters available. Supports threads. Auto-converts @handles, #tags, and URLs into clickable facets; link cards are generated from URLs when no media is attached."New value: +"Bluesky: alt_text (string or array matching media order). Supports threads. Auto-converts @handles, #tags, and URLs into clickable facets; link cards are generated from URLs when no media is attached."
    • changedInput schema / properties / platforms / properties / facebook / description
      Previous value: -"Facebook: format (post|story|reel; story requires empty content), title (string, reel only), first_comment (string), page_id (string, use profiles.placements to get available pages)"New value: +"Facebook: format (post|story|reel; story requires empty content), title (string, reel only), first_comment (string), page_id (string, use profiles.placements to get available pages), link (string, URL shared as a link post with preview card — text-only, can't be combined with media), alt_text (string or array matching media order), made_with_ai (bool, photo posts only), countries (ISO 3166-1 alpha-2 codes, array or comma-separated string — restrict to viewers in these countries)"
    • changedInput schema / properties / platforms / properties / instagram / description
      Previous value: -"Instagram: format (post|reel|story; story requires empty content), collaborators (array of usernames), first_comment (string), cover_url (reel thumbnail — URL or local file path; local paths are uploaded as cover_file), audio_name (string, ignored when audio_id is set), audio_id (reel soundtrack from instagram_available_audio; Facebook Login profiles only), audio_volume (integer 1-100, default 100, volume of the attached audio; Facebook Login only), video_volume (integer 1-100, default 100, volume of the video's own sound when audio_id is set; Facebook Login only), strip_audio (bool, reel/video story — removes the video's own audio track before upload; combine with audio_id to play only the music), made_with_ai (bool, disclose AI-generated content), trial_strategy (MANUAL|SS_PERFORMANCE), thumb_offset (string in ms), user_tags (array of {username, x, y, media_index} — tag public Instagram accounts on any format; images REQUIRE x and y as floats 0.0-1.0 from the top-left corner, reels and video slides are username-only (coordinates dropped), stories accept coordinates but don't need them; media_index picks the carousel slide 0-based, default 0; a leading @ is stripped; out-of-range coordinates or a media_index past the last media item are rejected with 422; private accounts and accounts with tagging off are silently skipped by Instagram)"New value: +"Instagram: format (post|reel|story; story requires empty content), collaborators (array of usernames), first_comment (string), cover_url (reel thumbnail — URL or local file path; local paths are uploaded as cover_file), audio_name (string, ignored when audio_id is set), audio_id (reel soundtrack from instagram_available_audio; Facebook Login profiles only), audio_volume (integer 1-100, default 100, volume of the attached audio; Facebook Login only), video_volume (integer 1-100, default 100, volume of the video's own sound when audio_id is set; Facebook Login only), strip_audio (bool, reel/video story — removes the video's own audio track before upload; combine with audio_id to play only the music), made_with_ai (bool, disclose AI-generated content), alt_text (string, or array matching media order; images incl. carousel, max 1,000 chars), disable_comment (bool, post/reel — turns comments off right after publishing), location_id (string, post/reel — numeric ID of a Facebook Page that has an address, NOT a place name; on carousels applies to the whole post; stories don't support it; a Page without an address fails the post), share_to_feed (bool, reel — false publishes to the Reels tab only; default shares to feed/grid), trial_strategy (MANUAL|SS_PERFORMANCE), thumb_offset (string in ms), user_tags (array of {username, x, y, media_index} — tag public Instagram accounts on any format; images REQUIRE x and y as floats 0.0-1.0 from the top-left corner, reels and video slides are username-only (coordinates dropped), stories accept coordinates but don't need them; media_index picks the carousel slide 0-based, default 0; a leading @ is stripped; out-of-range coordinates or a media_index past the last media item are rejected with 422; private accounts and accounts with tagging off are silently skipped by Instagram)"
    • changedInput schema / properties / platforms / properties / linkedin / description
      Previous value: -"LinkedIn: organization_id (string for company pages)"New value: +"LinkedIn: format (post|poll), organization_id (string for company pages), reshare_urn (string, reshare an existing LinkedIn post; no own media), alt_text (string or array matching media order), countries (organization posts only — ISO 3166-1 alpha-2 codes, array or comma-separated, up to 25; audience must exceed 300 followers), poll_question (poll: 1-140 chars), poll_options (poll: 2-4 strings, max 30 chars each; polls can't carry media), poll_duration_days (poll: 1|3|7|14, default 7), document_title (string, title shown above an attached PDF/DOC/DOCX/PPT/PPTX; defaults to the file name), first_comment (string, max 1,250 chars, posted right after publishing as the same author; not available on profiles connected before 2026-10-28)"
    • changedInput schema / properties / platforms / properties / pinterest / description
      Previous value: -"Pinterest: cover_url (cover image for video pins — URL or local file path; local paths are uploaded as cover_file), board_id (string), title (string), link (string)"New value: +"Pinterest: cover_url (cover image for video pins — URL or local file path; local paths are uploaded as cover_file), board_id (string — a board placement from profiles_placements; create one with pinterest_board_create), title (string, max 100 chars), destination_link (string, URL the pin links to, max 2,048 chars), thumb_offset (integer seconds, video pins), alt_text (string, image pins, truncated to 500 chars)"
    • changedInput schema / properties / platforms / properties / threads / description
      Previous value: -"Threads: No platform-specific parameters available. Supports threads."New value: +"Threads: alt_text (string or array matching media order), topic_tag (string, one tag without the leading #, max 50 chars, no periods or ampersands). Supports threads."
    • changedInput schema / properties / platforms / properties / tiktok / description
      Previous value: -"TikTok: format (video|image), privacy_status (PUBLIC_TO_EVERYONE|MUTUAL_FOLLOW_FRIENDS|FOLLOWER_OF_CREATOR|SELF_ONLY), photo_cover_index (integer, image only), auto_add_music (bool, image only), made_with_ai (bool, video only), disable_comment (bool), disable_duet (bool, video only), disable_stitch (bool, video only), brand_content_toggle (bool), brand_organic_toggle (bool)"New value: +"TikTok: format (video|image), privacy_status (PUBLIC_TO_EVERYONE|MUTUAL_FOLLOW_FRIENDS|FOLLOWER_OF_CREATOR|SELF_ONLY), photo_cover_index (integer, image only), auto_add_music (bool, image only), made_with_ai (bool, video only), disable_comment (bool), disable_duet (bool, video only), disable_stitch (bool, video only), brand_content_toggle (bool), brand_organic_toggle (bool), upload_as_draft (bool, send to the creator's TikTok inbox instead of publishing), thumb_offset (string ms, video cover frame; cover_url wins if both set)"
    • changedInput schema / properties / platforms / properties / twitter / description
      Previous value: -"Twitter/X: No platform-specific parameters available. Supports threads."New value: +"Twitter/X: format (post|poll), alt_text (string or array matching media order, max 1,000 chars), poll_options (poll: 2-4 strings, max 25 chars each), poll_duration_minutes (poll: integer 5-10080). Supports threads."
    • changedInput schema / properties / platforms / properties / youtube / description
      Previous value: -"YouTube: title (string), privacy_status (public|unlisted|private), cover_url (custom thumbnail — URL or local file path; local paths are uploaded as cover_file), made_for_kids (bool), tags (array of strings), category_id (string, defaults to '22' People & Blogs), contains_synthetic_media (bool, disclose AI-generated content)"New value: +"YouTube: title (string), privacy_status (public|unlisted|private), cover_url (custom thumbnail — URL or local file path; local paths are uploaded as cover_file), made_for_kids (bool), tags (array of strings), category_id (string, defaults to '22' People & Blogs), contains_synthetic_media (bool, disclose AI-generated content), playlist_id (string, add the video to this channel playlist — from youtube_playlists_list or youtube_playlist_create; checked before upload, an unknown id fails the post)"
  2. Changed1 schema field changed
    • changedInput schema / properties / platforms / properties / instagram / description
      Previous value: -"Instagram: format (post|reel|story; story requires empty content), collaborators (array of usernames), first_comment (string), cover_url (reel thumbnail — URL or local file path; local paths are uploaded as cover_file), audio_name (string), trial_strategy (MANUAL|SS_PERFORMANCE), thumb_offset (string in ms), user_tags (array of {username, x, y, media_index} — tag public Instagram accounts on any format; images REQUIRE x and y as floats 0.0-1.0 from the top-left corner, reels and video slides are username-only (coordinates dropped), stories accept coordinates but don't need them; media_index picks the carousel slide 0-based, default 0; a leading @ is stripped; out-of-range coordinates or a media_index past the last media item are rejected with 422; private accounts and accounts with tagging off are silently skipped by Instagram)"New value: +"Instagram: format (post|reel|story; story requires empty content), collaborators (array of usernames), first_comment (string), cover_url (reel thumbnail — URL or local file path; local paths are uploaded as cover_file), audio_name (string, ignored when audio_id is set), audio_id (reel soundtrack from instagram_available_audio; Facebook Login profiles only), audio_volume (integer 1-100, default 100, volume of the attached audio; Facebook Login only), video_volume (integer 1-100, default 100, volume of the video's own sound when audio_id is set; Facebook Login only), strip_audio (bool, reel/video story — removes the video's own audio track before upload; combine with audio_id to play only the music), made_with_ai (bool, disclose AI-generated content), trial_strategy (MANUAL|SS_PERFORMANCE), thumb_offset (string in ms), user_tags (array of {username, x, y, media_index} — tag public Instagram accounts on any format; images REQUIRE x and y as floats 0.0-1.0 from the top-left corner, reels and video slides are username-only (coordinates dropped), stories accept coordinates but don't need them; media_index picks the carousel slide 0-based, default 0; a leading @ is stripped; out-of-range coordinates or a media_index past the last media item are rejected with 422; private accounts and accounts with tagging off are silently skipped by Instagram)"
  3. First observed

TDQS

B3.4/5.0
Behavior3/5

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

Annotations already declare destructiveHint=true, openWorldHint=true, and idempotentHint=false, so the irreversible public-write nature is known. The description adds the thread/publishing-order constraint only implicitly via the schema and does not itself state that publishing is public and cannot be undone, nor mention the dry-run or dedup behaviors beyond naming features.

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?

Two compact sentences, front-loaded with the action and then the capability list. Every clause maps to a real capability, though the capability list reads a bit like a feature inventory rather than prioritized guidance.

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

Completeness3/5

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

For a destructive, open-world tool with 11 parameters and a large nested platform schema, the description is thin: it names no return value (no output schema exists), no source for profile/placement IDs, and no conflict rules such as schedule vs queue_id. The schema compensates heavily, keeping this at minimum-viable rather than inadequate.

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

Parameters3/5

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

Schema description coverage is 100% and the platform objects are extremely richly documented in-schema, so the schema does the heavy lifting. The description only points at the 'platforms' parameter and repeats the threads platform restriction, adding little syntax or constraint detail of its own.

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

Purpose4/5

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

The description states a specific verb and resource ("Publish a post to specified social media profiles") and enumerates the supported content modes. It stops short of distinguishing itself from the close sibling post_publish_draft, which also touches drafts, leaving the agent to infer the difference.

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

Usage Guidelines3/5

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

Usage is implied by "Publish a post" and the threads constraint ("X and Threads only"), but there is no explicit when-to-use versus post_publish_draft, post_update, or queues_create, and no prerequisites such as connected profiles being required.

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.