Skip to main content
Glama

create_post

Save drafts. Nothing is sent: schedule_post or publish_post does that.

One account: text + account_id; variants adds up to 3 alternative versions for that account, each its own draft. Several accounts: posts, one entry per draft, each with its own copy. Entries on different accounts are one post with a version per account (sent together with post_ids); entries repeating an account are separate posts. The result carries characterCount / characterLimit (overLimit when the text cannot publish), and, when they apply: mediaRequired (TikTok and YouTube need a video, Instagram and Pinterest an image or video), derivedTitle (YouTube takes the first 100 characters unless platform_options.title is set), settingsRequired (TikTok: the user's choices to ask, tiktokChoices), pinterestBoard, and similarRecent: this account's posts from the last 30 days that read nearly the same, which the user hears about before it goes out (no need to list posts to check for duplicates). The same text and media as an unsent post of the account is not saved again: the result is that post (duplicateOf, created: false), to use instead.

Args: text: Post copy; may be empty with media on X, Facebook, Instagram and Threads. @handle links by itself on X, Threads, Instagram (max 20 per caption), TikTok, YouTube, Bluesky (full handle, e.g. @name.bsky.social), Mastodon (@name on the same server, @name@server elsewhere) and Telegram channels; on Facebook, Pinterest, Discord, Google Business Profile and Slack it stays plain text; on LinkedIn it links only with user_tags. account_id: Social-account id (from list_social_accounts), not a platform name. hashtags: Appended to the text as #tags, counted in its limit (YouTube: video tags, unless platform_options.tags). A list, or a string split on commas (on spaces if it has none). goal: e.g. "Educate", "Engage", "Promote", "Entertain". scheduled_for: ISO 8601. Proposes a time on the draft; only schedule_post schedules. proposedTimeConflict in the result means the account's daily cap refuses that time; propose its nextFreeAt. campaign_id: The campaignId of a post made with posts: this draft becomes one more account's version of it. user_tags: LinkedIn company: [{company: ""}] with "@" in the text; Antwork finds the Page and links its exact name. LinkedIn people can't be looked up, only the user's own connected accounts. Instagram people on the media: [{username, platform: "instagram", type: "photo_tag", x, y (0-1 from left/top), mediaIndex (carousel photo, 0-based)}]; a photo needs x/y (centre if omitted), a reel takes the username only, a story either. Tagged accounts must be public; recentTags in get_post_context lists handles tagged before. The result's tagChecks shows each handle as found on Instagram or unchecked (personal accounts can't be looked up; still taggable). pinterest_board_id: Pinterest only, from boards in get_post_context. Omitted = the account's first board. slack_channel: Slack only: a channel id or #name from slackChannels in get_post_context. Omitted = the account's last channel (defaultSlackChannel); with none the post cannot publish. platform_options: Only what the user asked for. Instagram: publishType ("timeline" | "story"; a reel is "timeline" with a video; a story with several media_urls drafts one story per file, in order, as one set), postToGrid, coverUrl (a Reel's cover image, https). Facebook: publishType ("timeline" | "story"; a story is one photo or one video, its text is not shown). Pinterest: pinTitle (≤100), link (the pin's destination URL, https). YouTube: privacyStatus ("public" | "unlisted" | "private"), title (≤100), categoryId (e.g. "22", "28"), madeForKids, containsSyntheticMedia (realistic content made or altered with AI), thumbnailUrl (custom thumbnail, JPEG/PNG under 2 MB, https; needs a phone-verified channel), tags (list of video tags viewers do not see, ≤500 chars in all; used instead of hashtags). LinkedIn, Facebook, Instagram, Threads, YouTube, Bluesky, Mastodon: firstComment, a comment Antwork posts on the post right after it goes live (not on a story; links in YouTube Shorts comments are not clickable). TikTok settings are set by the user at settingsUrl, not here. variants: Up to 3 alternative versions for the same account. workspace_id: Workspace ID or name. Optional if user has only one workspace. media_urls: Media for the draft (every draft, with posts): library URLs, or public https links to a file, fetched into the library first as add_media(url=...) does. Saves the add_media call when moving posts in from another tool. posts: Up to 25 drafts in one call, instead of text + account_id: [{"account_id": str, "text": str}], each entry optionally with hashtags, goal, user_tags, pinterest_board_id, slack_channel, platform_options. Each account's copy is written in its own voice; there is no shared body. allow_duplicate: Save a second copy of a post the account already has unsent, only when the user asks for one. routine_id: The Autopilot routine this run is for (get_post_context(routine_id)): its accounts and post limit apply.

Tool call template

This tool declares no required parameters. Add optional parameters from the input schema as needed.

{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "arguments": {},
    "name": "create_post"
  }
}

Input Schema

NameRequiredDescriptionDefault
goalNo
textNo
postsNo
contextNoThe user's underlying goal for this call, in one sentence without personal details. Used for product analytics only.
hashtagsNo
variantsNo
llm_modelNoThe model identifier of the calling assistant, or "unknown". Used for product analytics only.
user_tagsNo
account_idNo
media_urlsNo
routine_idNo
campaign_idNo
workspace_idNo
scheduled_forNo
slack_channelNo
allow_duplicateNo
conversation_idNoPass the exact conversation_id from the server's previous response, unchanged. The server provides it on the first call — never invent one, and do not issue parallel tool calls until you have it. Keep passing the same conversation_id for the rest of the conversation, including after later user messages or on a different task; do not reset it when the user starts a new request.
platform_optionsNo
pinterest_board_idNo

Output Schema

NameRequiredDescriptionDefault
_mcp_instructionsNoServer-issued metadata for this conversation.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changed
    • addedInput schema / properties / routine_id
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "title": "Routine Id"
      +}
  2. Changed1 schema field changed
    • addedInput schema / properties / allow_duplicate
      Added value: +{
      +  "default": false,
      +  "title": "Allow Duplicate",
      +  "type": "boolean"
      +}
  3. Changed1 schema field changed
    • addedInput schema / properties / slack_channel
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "title": "Slack Channel"
      +}
  4. Changed8 schema fields changed
    • addedInput schema / properties / account_id / anyOf
      Added value: +[
      +  {
      +    "type": "string"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • addedInput schema / properties / account_id / default
      Added value: +null
    • removedInput schema / properties / account_id / type
      Removed value: -"string"
    • addedInput schema / properties / posts
      Added value: +{
      +  "anyOf": [
      +    {
      +      "items": {
      +        "additionalProperties": true,
      +        "type": "object"
      +      },
      +      "type": "array"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "title": "Posts"
      +}
    • addedInput schema / properties / text / anyOf
      Added value: +[
      +  {
      +    "type": "string"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • addedInput schema / properties / text / default
      Added value: +null
    • removedInput schema / properties / text / type
      Removed value: -"string"
    • changedInput schema / required
      Previous value: -[
      -  "text",
      -  "account_id"
      -]New value: +[]
  5. Changed1 schema field changed
    • addedInput schema / properties / media_urls
      Added value: +{
      +  "anyOf": [
      +    {
      +      "items": {
      +        "type": "string"
      +      },
      +      "type": "array"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "title": "Media Urls"
      +}
  6. Changed1 schema field changed
    • changedInput schema / required
      Previous value: -[
      -  "text",
      -  "account_id",
      -  "context",
      -  "llm_model"
      -]New value: +[
      +  "text",
      +  "account_id"
      +]
  7. First observed

TDQS

A4.8/5.0
Behavior5/5

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

Annotations are thin (readOnlyHint=false, destructiveHint=false, openWorldHint=true), so the description carries the burden and delivers: nothing is transmitted, duplicates are refused and returned as `duplicateOf`/`created: false`, near-duplicates surfaced via `similarRecent`, `overLimit`/`mediaRequired`/`settingsRequired`/`pinterestBoard` preconditions, and per-platform defaults (Slack defaults to last channel and can't publish without one). No behavior contradicts the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded and the Args block is scannable, but the text is very long and several entries are convoluted ('Entries on different accounts are one post with a version per account...'). It also spends space enumerating result fields (`characterCount`, `tagChecks`, `proposedTimeConflict`) that the output schema already documents, which is value-duplicating rather than value-adding.

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 19-parameter, zero-required, open-world creation tool, the description covers the batch/single duality, duplicate and near-duplicate handling, per-platform media and title derivation, and where to look up ids (list_social_accounts, get_post_context). 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.

Parameters5/5

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

Schema description coverage is only 16% across 19 parameters, so the description must compensate and does: every argument is given semantics the bare schema lacks, e.g. hashtags counting toward the text limit and behaving as video tags on YouTube, `user_tags` shapes per LinkedIn/Instagram case, Instagram `publishType` mapping a reel to 'timeline', and `posts` entry sub-fields.

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 ('Save drafts') and immediately scopes it against siblings: 'Nothing is sent: schedule_post or publish_post does that.' An agent can distinguish create_post from publish_post/schedule_post without inspecting 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 states when to use this tool versus the sending siblings, and enumerates the alternative input shapes (single account via text+account_id vs. `posts` batch vs. `variants`), when to use allow_duplicate ('only when the user asks for one'), and when to use campaign_id. Nothing about routing is left to inference.

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.