Skip to main content
Glama

Create post

create_post

Create a new social media post. Can be saved as a draft or scheduled for a specific time. Supports platform-specific content overrides, media attachments, labels, and thread format. IMPORTANT: YouTube and TikTok REQUIRE video — do not include them when posting images only. Instagram defaults to feed_photo — set postTypeOverrides for video content (reel, feed_video). Use this when the user wants to draft or schedule one new post (do not publish immediately unless asked).

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
labelsNoArray of label IDs to tag the post with.
statusNoPost status. "draft" (default) or "scheduled".
contentNoThe post text content. Optional — defaults to empty for media-only posts. LinkedIn mentions: write @[Display Name](urn:li:organization:ID) for a Page or @[Display Name](urn:li:person:ID) for a person; search_mentions on a LinkedIn channel returns ready-made Page tokens. The token publishes as a real mention on LinkedIn and as plain @Display Name on other channels.
channelsYesArray of channels to post to. Get channel IDs from list_channels.
timezoneNoTimezone for scheduling (e.g. "America/New_York"). Defaults to UTC.
postFormatNoPost format. "post" (default), "video", "reel", "story", "carousel", or "thread" for multi-part threads.
scheduledAtNoISO 8601 datetime for scheduling (e.g. 2025-01-15T10:00:00Z). Required when status is scheduled.
threadPartsNoThread parts array. Required when postFormat is thread (min 2 parts). EVERY part is measured against the character limit of every platform the post targets, not only the first — an over-long part is rejected with 400 VALIDATION_ERROR naming the part number, the platform and its limit. URLs count as 23 characters on X and Mastodon, their real length elsewhere.
mediaFileIdsNoArray of media file IDs to attach. Upload media first with upload_media.
platformContentNoPer-platform content overrides, e.g. { "x": "Short tweet", "linkedin": "Longer LinkedIn post" }.
requestApprovalNoOptional (default false). Set true to hold a scheduled post for team approval (approvalStatus becomes 'pending'). Forced on server-side for API keys of roles without post:publish (contributors), regardless of this flag.
platformSpecificNoPlatform-specific settings, e.g. { "youtube": { "title": "…", "privacyStatus": "public" } }. Reddit, Discord, Tumblr and Snapchat nest their options under the BulkPublish channel id, e.g. { "reddit": { "12": { "subreddit": "webdev" } } }. Telegram takes no options.
postTypeOverridesNoPer-platform post type override. E.g. { "instagram": "reel", "youtube": "short" }.
publishWhenApprovedNoOptional (default false). Set true on a post that waits for approval when it should go out as soon as it is approved, even if that is after its scheduled time. This is how someone who needs approval says 'publish now': status 'scheduled', scheduledAt = now, requestApproval true (or a contributor key), publishWhenApproved true. An approval arriving more than 15 minutes late then publishes immediately; with false it is approved but returned to draft for a new time. Stored only when the post ends up approvalStatus 'pending'; otherwise saved as false.
linkTrackingOverrideNoOptional per-post override for link tracking (bulkpubli.sh). true forces links in this post to be shortened and their clicks counted, false forces them to publish as written, and null/omitted (the default) inherits the organization's Link Tracking setting. Shortening happens at publish time, per channel, so two accounts on the same platform get distinct codes; it is skipped for a channel when the rewrite would push the post past that platform's character limit (a short URL is 28 characters and can be longer than the link it replaces).

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
idNo
authorNoWho wrote the post: { id, name, image }. Null when that account is gone.
labelsNo
statusNodraft, scheduled, processing, published, partial or failed.
contentNo
approverNoWho approved it: { id, name, image }. Null unless approvalStatus is approved.
assigneeNoWho is expected to act on it next: { id, name, image }. Null when nobody is.
timezoneNo
createdAtNo
mediaFilesNo
publishedAtNo
scheduledAtNo
postPlatformsNo
approvalStatusNo

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed24 schema fields changed
    • changedInput schema / properties / content / description
      Previous value: -"The post text content. Optional — defaults to empty for media-only posts."New value: +"The post text content. Optional — defaults to empty for media-only posts. LinkedIn mentions: write @[Display Name](urn:li:organization:ID) for a Page or @[Display Name](urn:li:person:ID) for a person; search_mentions on a LinkedIn channel returns ready-made Page tokens. The token publishes as a real mention on LinkedIn and as plain @Display Name on other channels."
    • addedInput schema / properties / platformSpecific / properties / bluesky / properties / repostId
      Added value: +{
      +  "description": "With postTypeOverrides.bluesky = 'repost': the bsky.app post URL (or at:// URI) to repost.",
      +  "type": "string"
      +}
    • addedInput schema / properties / platformSpecific / properties / facebook / properties / thumbnailUrl
      Added value: +{
      +  "description": "Cover image URL for a video or Reel. Facebook only accepts a cover once the video exists, so it is applied after the video publishes and appears a moment after the post; a cover that cannot be fetched or that Facebook rejects leaves the video published with Facebook's own chosen frame rather than failing the post.",
      +  "type": "string"
      +}
    • addedInput schema / properties / platformSpecific / properties / instagram / properties / collaborators / description
      Added value: +"Comma-separated Instagram usernames (no leading @) tagged as co-authors. Applies with postTypeOverrides.instagram of 'feed_photo', 'feed_video', 'reel' or 'carousel' — on a carousel the co-authors are set on the carousel itself, not on its individual items. Ignored on 'story', which has no co-author concept."
    • addedInput schema / properties / platformSpecific / properties / instagram / properties / coverUrl
      Added value: +{
      +  "description": "Cover image URL for a video or Reel. Takes precedence over thumbnailTimestamp: Instagram accepts one or the other and rejects a request carrying both, so only this one is forwarded when both are sent.",
      +  "type": "string"
      +}
    • addedInput schema / properties / platformSpecific / properties / instagram / properties / graduationStrategy / description
      Added value: +"How a trial reel becomes a normal one: 'manual' (the creator releases it) or 'auto' (released automatically if it performs well). Default 'manual'. Ignored unless trialReel is true."
    • addedInput schema / properties / platformSpecific / properties / instagram / properties / thumbnailTimestamp / description
      Added value: +"Cover frame for a video or Reel, in seconds from the start. Applies to postTypeOverrides.instagram of 'feed_video' or 'reel'. Ignored when coverUrl is also set."
    • addedInput schema / properties / platformSpecific / properties / instagram / properties / trialReel / description
      Added value: +"Publish as a trial reel, shown to people who do not follow the account first. Only takes effect with postTypeOverrides.instagram of 'reel' — a 'feed_video' publishes as an ordinary reel and this is ignored, even though both use the same underlying reel container."
    • addedInput schema / properties / platformSpecific / properties / mastodon / properties / repostId
      Added value: +{
      +  "description": "With postTypeOverrides.mastodon = 'repost': the status URL or ID to boost.",
      +  "type": "string"
      +}
    • addedInput schema / properties / platformSpecific / properties / threads / properties / locationId
      Added value: +{
      +  "description": "Numeric place ID from get_channel_options with a `q` search on a Threads channel. Only works once the channel has granted location tagging.",
      +  "type": "string"
      +}
    • addedInput schema / properties / platformSpecific / properties / threads / properties / repostId
      Added value: +{
      +  "description": "With postTypeOverrides.threads = 'repost': the numeric ID of the Threads post to repost (Threads links cannot be used; the ID of a post published through BulkPublish is in get_post's platforms[].platformPostId).",
      +  "type": "string"
      +}
    • addedInput schema / properties / platformSpecific / properties / threads / properties / topicTag
      Added value: +{
      +  "description": "One topic tag for the post, without a leading '#'. Must not contain periods or ampersands.",
      +  "type": "string"
      +}
    • addedInput schema / properties / platformSpecific / properties / tiktok / properties / thumbnailTimestamp / description
      Added value: +"Cover frame for the video, in seconds from the start."
    • changedInput schema / properties / platformSpecific / properties / tumblr / description
      Previous value: -"Tumblr options, nested under the BulkPublish channel id: { \"12\": { \"blogName\": \"myblog\", \"tags\": [\"art\"] } }. A flat object applies to every Tumblr channel on the post. Up to 30 images OR exactly one video per post."New value: +"Tumblr options, nested under the BulkPublish channel id: { \"12\": { \"blogName\": \"myblog\", \"tags\": [\"art\"] } } (tags: array of strings or one comma-separated string). A flat object applies to every Tumblr channel on the post. Up to 30 images OR exactly one video per post."
    • addedInput schema / properties / platformSpecific / properties / x / properties / repostId
      Added value: +{
      +  "description": "With postTypeOverrides.x = 'repost': the X post URL or ID to repost (retweet).",
      +  "type": "string"
      +}
    • changedInput schema / properties / postTypeOverrides / properties / bluesky / enum
      Previous value: -[
      -  "post",
      -  "video"
      -]New value: +[
      +  "post",
      +  "video",
      +  "thread",
      +  "repost"
      +]
    • changedInput schema / properties / postTypeOverrides / properties / mastodon / enum
      Previous value: -[
      -  "post"
      -]New value: +[
      +  "post",
      +  "thread",
      +  "repost"
      +]
    • changedInput schema / properties / postTypeOverrides / properties / threads / enum
      Previous value: -[
      -  "text",
      -  "image",
      -  "video",
      -  "carousel"
      -]New value: +[
      +  "text",
      +  "image",
      +  "video",
      +  "carousel",
      +  "repost"
      +]
    • changedInput schema / properties / postTypeOverrides / properties / x / enum
      Previous value: -[
      -  "tweet",
      -  "video",
      -  "thread"
      -]New value: +[
      +  "tweet",
      +  "video",
      +  "thread",
      +  "repost"
      +]
    • addedInput schema / properties / publishWhenApproved
      Added value: +{
      +  "description": "Optional (default false). Set true on a post that waits for approval when it should go out as soon as it is approved, even if that is after its scheduled time. This is how someone who needs approval says 'publish now': status 'scheduled', scheduledAt = now, requestApproval true (or a contributor key), publishWhenApproved true. An approval arriving more than 15 minutes late then publishes immediately; with false it is approved but returned to draft for a new time. Stored only when the post ends up approvalStatus 'pending'; otherwise saved as false.",
      +  "type": "boolean"
      +}
    • changedInput schema / properties / threadParts / description
      Previous value: -"Thread parts array. Required when postFormat is thread (min 2 parts)."New value: +"Thread parts array. Required when postFormat is thread (min 2 parts). EVERY part is measured against the character limit of every platform the post targets, not only the first — an over-long part is rejected with 400 VALIDATION_ERROR naming the part number, the platform and its limit. URLs count as 23 characters on X and Mastodon, their real length elsewhere."
    • addedOutput schema / properties / approver
      Added value: +{
      +  "anyOf": [
      +    {
      +      "additionalProperties": {},
      +      "properties": {},
      +      "type": "object"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "description": "Who approved it: { id, name, image }. Null unless approvalStatus is approved."
      +}
    • addedOutput schema / properties / assignee
      Added value: +{
      +  "anyOf": [
      +    {
      +      "additionalProperties": {},
      +      "properties": {},
      +      "type": "object"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "description": "Who is expected to act on it next: { id, name, image }. Null when nobody is."
      +}
    • addedOutput schema / properties / author
      Added value: +{
      +  "anyOf": [
      +    {
      +      "additionalProperties": {},
      +      "properties": {},
      +      "type": "object"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "description": "Who wrote the post: { id, name, image }. Null when that account is gone."
      +}
  2. Changed1 schema field changed
    • changedOutput schema / properties / mediaFiles / anyOf
      Previous value: -[
      -  {
      -    "items": {
      -      "additionalProperties": {},
      -      "properties": {},
      -      "type": "object"
      -    },
      -    "type": "array"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "items": {
      +      "anyOf": [
      +        {
      +          "type": "number"
      +        },
      +        {
      +          "type": "string"
      +        },
      +        {
      +          "additionalProperties": {},
      +          "properties": {},
      +          "type": "object"
      +        }
      +      ]
      +    },
      +    "type": "array"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
  3. Changed1 schema field changed
    • changedOutput schema / (root)
      Previous value: -nullNew value: +{
      +  "$schema": "http://json-schema.org/draft-07/schema#",
      +  "additionalProperties": false,
      +  "properties": {
      +    "approvalStatus": {
      +      "anyOf": [
      +        {
      +          "type": "string"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ]
      +    },
      +    "content": {
      +      "anyOf": [
      +        {
      +          "type": "string"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ]
      +    },
      +    "createdAt": {
      +      "anyOf": [
      +        {
      +          "type": "string"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ]
      +    },
      +    "id": {
      +      "anyOf": [
      +        {
      +          "anyOf": [
      +            {
      +              "type": "number"
      +            },
      +            {
      +              "type": "string"
      +            }
      +          ]
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ]
      +    },
      +    "labels": {
      +      "anyOf": [
      +        {
      +          "items": {
      +            "additionalProperties": {},
      +            "properties": {},
      +            "type": "object"
      +          },
      +          "type": "array"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ]
      +    },
      +    "mediaFiles": {
      +      "anyOf": [
      +        {
      +          "items": {
      +            "additionalProperties": {},
      +            "properties": {},
      +            "type": "object"
      +          },
      +          "type": "array"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ]
      +    },
      +    "postPlatforms": {
      +      "anyOf": [
      +        {
      +          "items": {
      +            "additionalProperties": {},
      +            "properties": {
      +              "platform": {
      +                "anyOf": [
      +                  {
      +                    "type": "string"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ]
      +              },
      +              "status": {
      +                "anyOf": [
      +                  {
      +                    "type": "string"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ]
      +              }
      +            },
      +            "type": "object"
      +          },
      +          "type": "array"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ]
      +    },
      +    "publishedAt": {
      +      "anyOf": [
      +        {
      +          "type": "string"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ]
      +    },
      +    "scheduledAt": {
      +      "anyOf": [
      +        {
      +          "type": "string"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ]
      +    },
      +    "status": {
      +      "anyOf": [
      +        {
      +          "type": "string"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ],
      +      "description": "draft, scheduled, processing, published, partial or failed."
      +    },
      +    "timezone": {
      +      "anyOf": [
      +        {
      +          "type": "string"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ]
      +    }
      +  },
      +  "type": "object"
      +}
  4. First observed

TDQS

A4.1/5.0
Behavior4/5

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

Annotations indicate readOnlyHint=false and destructiveHint=false, and the description adds valuable context: YouTube and TikTok require video, Instagram defaults to feed_photo, and it supports draft/schedule. No contradictions with annotations.

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 compact and front-loaded: it states the purpose, lists features, then gives important platform warnings. It is not bloated and each sentence adds value.

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?

For a complex tool with 15 parameters and nested objects, the description provides a clear overview and key constraints, while the schema and output schema cover the rest. It omits some details like approval flow, but those are captured in parameter descriptions.

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% – every parameter is documented in the schema. The description adds little beyond schema (e.g., mentions overrides and media generally) but that is acceptable given high coverage. Baseline 3 is appropriate.

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 clearly states 'Create a new social media post' – a specific verb and resource. It distinguishes from siblings like publish_post by explicitly noting it is for drafting or scheduling, and says 'do not publish immediately unless asked', which differentiates it from immediate-publish tools.

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 explicitly says 'Use this when the user wants to draft or schedule one new post' and clarifies not to publish immediately unless asked, steering the agent away from publish_post. It does not name alternatives directly, but the context is clear enough for selection.

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.

Resources