Skip to main content
Glama

Create a draft

create_content

[writes flayr data · write scope] Creates a DRAFT content item. Nothing is posted. Give text plus optional media (videoUrl / imageUrl, or videoStorageId / imageStorageId from upload_media), target platforms, brandId (from list_brands; omitted → the brand last active in the dashboard), per-platform captions (platformText), creator credits, labels and YouTube options. Returns the new id — pass it as contentId to publish or add_queue_items. (Wraps POST /api/v2/content.)

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_content"
  }
}

Input Schema

NameRequiredDescriptionDefault
textNo
labelsNoNormalized "key:value" labels (keys and values are lower-cased, spaces become "-"). Linked keys: campaign:<media campaign id>, experiment:<experiment id> (+ variant:<name> or the experiment's compareKey), type:<post type> (short, long-form, carousel, image, text, reel, story, poem, timelapse…). Free keys work too: cut:opus, lane:tech, parent:pantheon-part-1, ab:<pair id> (an A/B pair). Labels are copied onto every post made from the draft, and compared in GET /api/v2/analytics/experiments.
brandIdNoAn id from GET /api/v2/brands, or "personal".
creditsNoCreator credits for work this post uses. Added to the published caption above the flayr footer, one line each: model → "Print your own: <url> (model by <author>)"; other kinds → "Credit: <title> by <author> <url>". Never added twice (a URL already in the caption is skipped); on X a shorter line (or no URL) is used, or the credits are left out, before the caption text is ever cut. YouTube: description only, never the title.
youtubeNoStored on the draft and used when it is published (POST /api/v2/publish with contentId). YouTube upload options, applied to YouTube targets only. madeForKids is always sent to YouTube (default false). A missing title is derived from the first sentence of the caption, cut to 100 characters at a word boundary. SCHEDULED UPLOADS: the video is uploaded ahead of scheduledAt. "public" is uploaded as private and released by YouTube at the scheduled time; "unlisted" is watchable by anyone with the link from upload time; "private" stays private.
imageUrlNo
videoUrlNo
platformsNo
contentTypeNo
sourceLabelNo
platformTextNoPer-platform captions: platform id → the caption that platform gets instead of `text`, e.g. { "twitter": "short version" }. Each must fit its platform: X 280 (a link counts 23, an emoji 2), Bluesky 300, Threads 500, Instagram 2200, LinkedIn 3000. Platforms without one get `text` when it fits, else an automatic short version: the first line, the credits in short form, as many hashtags as fit and the short flayr link (hashtags go first, then the credit link becomes "Model by <author>"; words are never cut). PATCH merges: a null (or "") value clears that platform, platformText: null clears all. At publish every platform is validated on its own caption: one failing platform no longer fails the others — the post publishes to the rest and reports the failures in platformErrors.
imageStorageIdNo
instanceLabelsNoInternal labels per platform/account instance. An array of {platform, accountId?, labels}; accountId is the Zernio connected account id. Omit accountId when unknown. instanceKey is derived as canonical platform + ":account:" + URL-encoded account id, or ":pending" when unknown (twitter canonicalizes to x). Replaces the instance set when editing; [] clears it. Never published.
referralFooterNoCaption watermark: appends "Posted with flayr.social — try it: flayr.social/r/<code>/<ch>" to each platform's text (<code> is your referral code — your custom one if you claimed it; <ch> names the platform: yt, x, li, ig, tt, fb, th, bs). (YouTube: description only, never the title; X: the shorter "via flayr.social/r/<code>/x" or nothing when it would not fit — your text is never cut). On by default. false removes it only on plans that can remove the Flayr watermark (Pro and up); omitted follows your watermark setting.
videoStorageIdNo
copyFromContentIdNoCOPY TO BRAND (staff and the Agency plan): the id of an existing item (GET /api/v2/content) to copy into `brandId` as a new draft. Images, video, slides, documents and thumbnails are copied into new storage objects, so deleting the source never breaks the copy. Combine only with `brandId` (required, a brand id — not "personal") and optionally `text` (replaces the caption; omitted = the source caption). Labels, mentions, campaign/experiment links and post history are not copied. Needs an account-wide key. Errors: 403 below the Agency plan or with a brand-bound key; 404 unknown item or brand; 409 the item changed mid-copy; 413 the brand's storage is full; 422 the item is already in that brand or its media is missing.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changed
    • addedInput schema / properties / instanceLabels
      Added value: +{
      +  "description": "Internal labels per platform/account instance. An array of {platform, accountId?, labels}; accountId is the Zernio connected account id. Omit accountId when unknown. instanceKey is derived as canonical platform + \":account:\" + URL-encoded account id, or \":pending\" when unknown (twitter canonicalizes to x). Replaces the instance set when editing; [] clears it. Never published.",
      +  "items": {
      +    "additionalProperties": false,
      +    "properties": {
      +      "accountId": {
      +        "maxLength": 200,
      +        "type": "string"
      +      },
      +      "labels": {
      +        "items": {
      +          "type": "string"
      +        },
      +        "maxItems": 30,
      +        "type": "array"
      +      },
      +      "platform": {
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "platform",
      +      "labels"
      +    ],
      +    "type": "object"
      +  },
      +  "maxItems": 20,
      +  "type": "array"
      +}
  2. Changed2 schema fields changed
    • removedInput schema / properties / help
      Removed value: -{
      -  "description": "Staff only. Bind the draft to a help center slot: `<feature>` (its official tutorial, e.g. \"workflows\"), `<feature>:official|how-to|community`, a how-to slot key (e.g. \"flayr-04-workflows-light\") or `how-to-<n>` (n = 1-6). Only one of ?help=, help and helpBinding.",
      -  "type": "string"
      -}
    • removedInput schema / properties / helpBinding
      Removed value: -{
      -  "additionalProperties": false,
      -  "description": "Staff only. The help center slot this draft's published YouTube video fills. Default: fills only an empty slot.",
      -  "properties": {
      -    "feature": {
      -      "description": "A help feature slug (see /help/features).",
      -      "type": "string"
      -    },
      -    "howTo": {
      -      "description": "The how-to slot (key or 1-6); required for slot \"how-to\" and must belong to `feature`.",
      -      "oneOf": [
      -        {
      -          "type": "string"
      -        },
      -        {
      -          "maximum": 6,
      -          "minimum": 1,
      -          "type": "integer"
      -        }
      -      ]
      -    },
      -    "replace": {
      -      "default": false,
      -      "description": "Replace a video already in the slot.",
      -      "type": "boolean"
      -    },
      -    "slot": {
      -      "default": "official",
      -      "enum": [
      -        "official",
      -        "how-to",
      -        "community"
      -      ],
      -      "type": "string"
      -    }
      -  },
      -  "required": [
      -    "feature"
      -  ],
      -  "type": "object"
      -}
  3. First observed

TDQS

A4.4/5.0
Behavior4/5

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

Annotations already declare non-read-only, non-destructive, non-idempotent. The description adds meaningful behavior on top: that the call only creates a draft, that the response yields a new id used by later calls, the write scope requirement, and the brandId fallback ("omitted → the brand last active in the dashboard"). It does not surface the authorization/plan edge cases for copyFromContentId, but those live in the schema.

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

Conciseness5/5

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

Front-loads the draft-vs-publish distinction, then lists inputs compactly with each source pointer earning its place, and closes with the returned id's use. The trailing "Wraps POST /api/v2/content" is a small but legitimate debugging aid; no filler sentences.

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 16-parameter tool with nested objects and no output schema, the description covers the create flow, media sourcing, brand defaulting, and what the return value is for. It leaves copy/duplication and internal-label behavior to the schema, which is acceptable since those are richly described there, but a one-line mention of the copyFromContentId alternative mode would have closed the gap.

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?

With 50% schema coverage, the description compensates by naming the key parameters and their sources: media via `videoUrl`/`imageUrl` or `videoStorageId`/`imageStorageId` from upload_media, `platforms`, `brandId` from list_brands with a documented default, per-platform `platformText`, `credits`, `labels`, and YouTube options. Several params (contentType, sourceLabel, instanceLabels) get no mention in the description, but those are documented in the schema itself.

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?

States a specific verb and resource ("Creates a DRAFT content item") and immediately bounds it against the obvious confusion with publishing ("Nothing is posted"). The scope tag ("writes flayr data · `write` scope") and the sibling reference to publish/add_queue_items make it distinguishable from the many adjacent 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?

Gives clear entry conditions (give `text` plus optional media) and explicit routing for downstream steps: "Returns the new `id` — pass it as `contentId` to publish or add_queue_items." It also points at upload_media and list_brands as sources for inputs. It stops short of naming when not to use it (e.g., update_content for edits, or copyFromContentId duplication), so no full when/when-not pairing.

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