Skip to main content
Glama

Create several posts at once

bulk_post
Destructive

Create AND SEND up to 100 DIFFERENT posts in one call: each row goes out at its scheduled_at, or now, unless the project holds agent posts. Each row runs the full single-post path — allowance, approval — and reports on its own, so some rows can land while others refuse. A row's media is media_ids (from upload_media) or media_urls. A held row carries its own approval_link. An idempotency_key per row makes a resend after a timeout answer repeated: true instead of a second post. NOT for one post going to several accounts: that is ONE create_post with every account in accounts, with any per-platform wording in platform_configurations.<platform>.caption.

Input Schema

NameRequiredDescriptionDefault
rowsNoThe posts to create, one object per post. `posts` is accepted as the same thing.
postsNoAlias for `rows` — send one or the other.

Output Schema

NameRequiredDescriptionDefault
okNoPresent and false only on a refusal.
errorNoWhat was refused, in a sentence, when `ok` is false.
failedNo
createdNo
messageNoAbout the whole batch, written to be passed on — today, accounts it puts past a day's worth of posts.
resultsNoOne row per row you sent, in order. Rows are independent — some can land while others refuse.
retriableNoFalse when asking again cannot change the answer.
error_codeNoMachine reason for a refusal.
replaced_byNoThe id the post has now, when you asked with one an edit retired. An edit gives a post a new id: get_delivery_receipt and get_post_metrics answer for this current version (and `asked_for` is the id you sent); update_post and delete_post refuse with error_code `replaced`. Use this id from here on.
pace_warningsNoAccounts getting more posts in one day than the network likes — it may treat that as spam. Nothing is held. Mention it to the person once and offer to spread the rest out; don't stop to ask on every post.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changed
    • changedOutput schema / properties / replaced_by / description
      Previous value: -"With error_code `replaced`: the id the post has now. An edit gives a post a new id; use this one."New value: +"The id the post has now, when you asked with one an edit retired. An edit gives a post a new id: get_delivery_receipt and get_post_metrics answer for this current version (and `asked_for` is the id you sent); update_post and delete_post refuse with error_code `replaced`. Use this id from here on."
  2. Changed2 schema fields changed
    • addedOutput schema / properties / message
      Added value: +{
      +  "description": "About the whole batch, written to be passed on — today, accounts it puts past a day's worth of posts.",
      +  "type": "string"
      +}
    • addedOutput schema / properties / pace_warnings
      Added value: +{
      +  "description": "Accounts getting more posts in one day than the network likes — it may treat that as spam. Nothing is held. Mention it to the person once and offer to spread the rest out; don't stop to ask on every post.",
      +  "items": {
      +    "additionalProperties": {},
      +    "properties": {
      +      "account_id": {
      +        "type": "string"
      +      },
      +      "new_account": {
      +        "type": "boolean"
      +      },
      +      "platform": {
      +        "type": "string"
      +      },
      +      "posts_within_a_day": {
      +        "type": "number"
      +      },
      +      "same_site": {
      +        "additionalProperties": {},
      +        "properties": {
      +          "domain": {
      +            "type": "string"
      +          },
      +          "posts": {
      +            "type": "number"
      +          }
      +        },
      +        "type": "object"
      +      },
      +      "suggested_per_day": {
      +        "type": "number"
      +      },
      +      "username": {
      +        "type": "string"
      +      }
      +    },
      +    "type": "object"
      +  },
      +  "type": "array"
      +}
  3. Changed1 schema field changed
    • addedOutput schema / properties / replaced_by
      Added value: +{
      +  "description": "With error_code `replaced`: the id the post has now. An edit gives a post a new id; use this one.",
      +  "type": "string"
      +}
  4. First observed

TDQS

A4.5/5.0
Behavior5/5

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

Goes well beyond the annotations: rows are independently evaluated through the full single-post path (allowance, approval) and can partially succeed ("some rows can land while others refuse"), held rows return their own approval_link, and a per-row idempotency_key converts a timeout resend into `repeated: true` rather than a duplicate — useful nuance given idempotentHint=false applies to the call, not the row. This is exactly the failure/idempotency context an agent needs before firing 100 writes.

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?

Front-loads the create-and-send scope plus the batch limit, then the row-level mechanics, then the exclusion rule — a sensible order with no filler. It is dense (long sentences, heavy backtick usage) but every clause carries operational information.

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 high-blast-radius bulk write with an output schema present, it covers the essentials: partial success, approval holds, idempotent resends, and the sibling alternative. It stops short of stating whether schema-invalid rows fail the whole batch or just that row, and says nothing about rate limits or batch ordering on real-time sends.

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%, so the nested row fields are already documented (accounts refs, media_ids vs media_urls ordering, scheduled_at "next_slot", idempotency_key). The description largely restates those facts rather than adding new meaning — e.g. the media precedence rule already appears in the schema — so the baseline 3 holds.

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 + scale: "Create AND SEND up to 100 DIFFERENT posts in one call." It immediately distinguishes the bulk case from the single-post case, and the closing sentence names the sibling create_post for the opposite pattern (one post, many accounts).

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?

Gives an explicit negative rule with the alternative: "NOT for one post going to several accounts: that is ONE create_post with every account in `accounts`." It also routes media preparation to upload_media, and states the scheduling default ("or now") and the held-project exception, so the agent knows when this tool applies and when it does not.

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.