Skip to main content
Glama

Edit a draft

update_content
Idempotent

[writes flayr data · write scope] Edits a draft in place; only the fields you pass change. Any media field replaces the draft's media as a set (keeps the id, so queue items still point at it). Refused (409) for archived or already-published items, and a media swap is refused once a queue booked it. labels, opus, videoWatermarked, library and aiGenerated may be changed on published items too. aiGenerated is the post's AI label: false for real footage, null back to automatic. A video draft's custom thumbnail/cover: thumbnailStorageId (an image from upload_media) or thumbnailUrl, or thumbnailFrameOffsetMs for a frame of the video; thumbnailUrl: null clears it. It is sent to YouTube (long-form), Facebook, LinkedIn, Instagram Reels, TikTok and Pinterest at publish. (Wraps PATCH /api/v2/content/{id}.)

Tool call template

Replace each placeholder with a value matching the input schema. Only required parameters are included; add optional parameters as needed.

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

Input Schema

NameRequiredDescriptionDefault
idYes
opusNoLink this row to an Opus Clip clip (owner only; allowed on published rows) so an Opus project import skips it instead of creating a duplicate. null unlinks.
textNo
titleNoShorthand for youtube.title (the video title). No < or >.
imagesNoCarousel image URLs. Cannot be combined with the other media fields.
labelsNoReplaces the labels ([] or null clears). Allowed on published items too. Normalized "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.
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.
libraryNoThe Library item's own title and description, searchable from the Library. null or "" clears one. Metadata: allowed on published items. Not the same as `title` (the YouTube video title).
youtubeNoMerged into the stored YouTube options. 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.
imageUrlNohttp(s) image URL: the video's thumbnail, or on its own the post's single image. Not with imageStorageId.
videoUrlNohttp(s) URL of the new video. Not with videoStorageId.
platformsNo
aiGeneratedNoThe post's "AI-generated" label toggle: false = real footage (no AI label), true = always label, null = automatic (on when flayr made the media). Metadata: allowed on published items. Removing the `source:ai-generated` label alone does not turn it off.
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.
thumbnailUrlNoCustom video thumbnail: an http(s) image URL. Not with thumbnailStorageId. null clears.
imageStorageIdNoUploaded image storageId: the video's thumbnail, or on its own the post's single image. Not with imageUrl.
videoStorageIdNostorageId from uploading to POST /api/v2/media/upload-url's uploadUrl. Not with videoUrl. Another account's upload is refused (422).
videoWatermarkedNoThe item's own video already has the "Posted by flayr.social" watermark: publish it as-is. null clears.
thumbnailStorageIdNoCustom video thumbnail: an image storageId from POST /api/v2/media/upload-url. Not with thumbnailUrl. null clears.
thumbnailFrameOffsetMsNoUse this frame of the video (ms from the start) as the cover. Instagram and TikTok get the offset; YouTube/Facebook/LinkedIn need an image, so pass the captured frame as thumbnailStorageId / thumbnailUrl too.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed2 schema fields changed
    • addedInput schema / properties / aiGenerated
      Added value: +{
      +  "description": "The post's \"AI-generated\" label toggle: false = real footage (no AI label), true = always label, null = automatic (on when flayr made the media). Metadata: allowed on published items. Removing the `source:ai-generated` label alone does not turn it off.",
      +  "type": [
      +    "boolean",
      +    "null"
      +  ]
      +}
    • addedInput schema / properties / library
      Added value: +{
      +  "additionalProperties": false,
      +  "description": "The Library item's own title and description, searchable from the Library. null or \"\" clears one. Metadata: allowed on published items. Not the same as `title` (the YouTube video title).",
      +  "minProperties": 1,
      +  "properties": {
      +    "description": {
      +      "maxLength": 2000,
      +      "type": [
      +        "string",
      +        "null"
      +      ]
      +    },
      +    "title": {
      +      "maxLength": 120,
      +      "type": [
      +        "string",
      +        "null"
      +      ]
      +    }
      +  },
      +  "type": "object"
      +}
  2. First observed

TDQS

A4.6/5.0
Behavior5/5

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

Beyond annotations, the description discloses partial-update behavior, media replacement semantics, preserved media IDs, 409 refusal cases, published-item exceptions, and thumbnail publishing behavior across platforms. These are substantive behavioral details rather than restatements of 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.

Conciseness4/5

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

The description is front-loaded with scope and core update behavior, then moves through restrictions and field-specific exceptions. It is dense and somewhat long, but most detail is warranted for a 20-parameter nested update tool; a few sentences repeat schema-level details.

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 complex 20-parameter mutation with nested objects and no output schema, the description covers the core edit behavior, restrictions, partial-update semantics, media replacement, thumbnail handling, and published-item exceptions. It gives an agent enough context to invoke the tool correctly without needing to infer critical constraints.

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 coverage is high at 85%, so much parameter meaning is already structured. The description still adds cross-field meaning: media fields replace as a set, certain fields remain editable after publishing, `aiGenerated` null restores automatic labeling, and the thumbnail alternatives have distinct effects. Some parameters such as `platforms` are not clarified in the description, but overall it adds useful semantics.

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 and resource: "Edits a draft in place; only the fields you pass change." It also identifies the underlying PATCH endpoint, making the partial-update semantics unambiguous and clearly distinct from create/delete siblings.

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 supplies meaningful when-not conditions: archived or published items are refused with 409, and media swaps are refused once a queue has booked the item. It also says several metadata fields may still be edited on published items. It does not explicitly name alternative sibling tools, which keeps it below a 5.

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