Skip to main content
Glama
hermoso-ai

Hermoso

Official

Publish a post to X (Twitter)

post_to_x

Publish posts, threads, replies, polls, and media to X (Twitter) after explicit user approval. Supports alt text, reply restrictions, and premium length limits.

Instructions

Publish to the user’s connected X (Twitter) account — a single post, a post with an image or video render attached, a reply to an existing post, or a whole THREAD (pass thread as an array and each part is posted as a reply to the one before). This PUBLISHES immediately and PUBLICLY — ALWAYS show the user the exact text and get an explicit yes BEFORE calling. Can also run a POLL (2-4 options) instead of media, and restrict who may reply. LENGTH IS THE POSTING ACCOUNT’S, NOT A FLAT 280: 280 characters on an ordinary account, but UP TO 25,000 if that account has X Premium. Hermoso reads the account’s own subscription from X and sends the post rather than refusing something it may be entitled to; if X declines it on length, the reply says so and names the subscription X reported. Over 25,000 is refused for free — that is X’s own ceiling on every account. Text is NEVER truncated. AND A LONG POST IS CHEAPER THAN A THREAD: it is ONE billed X call where the same words split across five posts are five, so prefer one long post over threading when the account has Premium. Only the first ~280 characters show in the timeline; the rest sits behind “Show more”. Write altText whenever you attach a render. COSTS CREDITS: X charges per API request, so every post in a thread is billed, and a post containing a LINK costs roughly 13× one without — mention the cost before publishing a long thread. Each brand also has a rolling 24-hour ceiling on what it can spend at X, and a request that would cross it is refused WHOLE before anything publishes, so a batch of posts is bounded rather than open-ended. THIS TOOL POSTS ORGANICALLY — it does not create an ad campaign. X ads are built with create_x_ads_campaign → create_x_ads_line_item → create_x_ads_promoted_tweet, and a promoted post needs a post id, so publish here first and promote that post. Needs X connected (Settings ▸ Connectors ▸ X).

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
hookNoWHAT ANGLE THIS POST IS BUILT ON — the single most valuable field here, and the only moment it can ever be recorded. post_performance groups on it to answer "which hooks work", and it needs 5 posts sharing ONE hook before it will call anything a winner, so REUSE THE SAME WORDING across a campaign instead of rephrasing it every time. Best of all, pass a hook id from list_hooks (e.g. "direct_callout", "mid_problem", "before_after") — those fold onto a stable key however they are spelled, so a whole brand accumulates evidence on one row. Your own wording is fine too; it just only groups when you repeat it exactly. Omitting it means this post can never vote on which hook works.
pollNorun a poll on the post. X does not allow a poll and media on the same post, and a poll cannot ride on a thread.
textNothe post text. 280 characters without X Premium, up to 25,000 with it — write the full thing, it is never truncated. Use this OR thread, not both.
threadNoa thread: each string is one post, published in order, each replying to the previous. Max 25. Each part follows the same length rule as `text`, and on an X Premium account ONE long post is usually both better reading and cheaper than a thread.
accountNoWHICH connected account of this channel to post as — its @handle or id from list_connector_accounts. Needed only when the brand has more than one x account connected (several and none named is refused by name, never guessed); omit when there is one.
altTextNoaccessibility description of the attached media, max 1000 characters — write one whenever you attach a render. Costs a small extra amount: X bills one metadata write PER media. With SEVERAL media, pass an ARRAY aligned to their order — X attaches alt text per media id, and a single string describes only the FIRST one (X renders up to four media as a GRID, not a carousel, so one sentence would be wrong for the other three).
subjectNoWHAT THIS POST IS ABOUT — the product, feature, offer or theme (e.g. "winter coat", "free trial", "founder story"). The second grouping axis in post_performance. Same rule as hook: reuse the exact wording so posts about one subject land in one group.
mediaUrlNoa Hermoso render (image or video) to attach to the first post — pass its served URL, or an upload_file url for external media
mediaUrlsNoUP TO FOUR Hermoso-hosted media attached to ONE post — X’s own schema caps media_ids at 4. X renders them as a GRID: every image visible at once, nothing to swipe to. That is NOT a carousel, and a numbered "1/6 · SWIPE" slide deck must still not be sent here — it would publish as a grid and the "swipe" instruction would make no sense. Order decides the layout. On a thread the media rides the FIRST post; give each later part its own post to attach more. Mutually exclusive with mediaUrl, and more than 4 is refused before anything is uploaded.
replyToIdNonumeric id of an existing X post to reply to
communityIdNopublish into an X COMMUNITY instead of the main timeline — the number in the community’s own URL (x.com/i/communities/<id>). The connected account must be a MEMBER of it; X answers a non-member and a non-existent id with the same refusal and does not separate them.
quotePostIdNonumeric id of a post to QUOTE — X renders the quoted post inside yours. This is NOT replyToId: a reply sits under the original in its thread, a quote stands alone on your own timeline with the original embedded, which is the one you want for commentary. X makes a quote mutually exclusive with media and with a poll (their own schema), and a quote is billed at the higher LINK rate because X appends the quoted post’s t.co URL whatever your text says.
replySettingsNorestrict who can reply — omit for everyone, which is the right default for a brand post
paidPartnershipNolabel the post a PAID PARTNERSHIP on X — the same disclosure Hermoso already ships for TikTok. OPT-IN ONLY: set it when the post is sponsored, gifted or otherwise paid for, and never assume it on the user’s behalf.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changedv0.1.189
    • addedInput schema / properties / account
      Added value: +{
      +  "description": "WHICH connected account of this channel to post as — its @handle or id from list_connector_accounts. Needed only when the brand has more than one x account connected (several and none named is refused by name, never guessed); omit when there is one.",
      +  "type": "string"
      +}
  2. Addedv0.1.161

TDQS

A4.3/5.0
Behavior5/5

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

Goes far beyond the sparse annotations (readOnlyHint=false, openWorldHint=true): it discloses immediate and public publishing, that text is never truncated, that length limits depend on the account's own X subscription (280 vs 25,000), that only the first ~280 characters show in the timeline, and that a batch is refused WHOLE if it would cross the 24-hour spend ceiling. It also surfaces the cost model (per-request billing, ~13× for links) and names the subscription X reported on a length refusal. No contradiction 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.

Conciseness3/5

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

The description is logically organized — core action, length behavior, cost, organic-vs-ads, prerequisite — and front-loaded with the safety-critical instruction to show exact text and get explicit yes before calling. However, it is roughly 450 words and repeats details already fully covered in the schema (poll constraints, media/poll/quote exclusions, alt text), so not every sentence earns its place. The heavy all-caps emphasis adds noise.

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 14-parameter, zero-required, high-stakes publishing tool with billing consequences and no output schema, the description covers everything an agent needs: modes, exclusions, safety confirmation, account-specific length rules, per-post cost, whole-batch ceiling refusal, and error behavior ('if X declines it on length, the reply says so'). The return shape is implied by the promotion flow (a post id is needed for ads). Nothing material is missing.

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% with unusually rich per-parameter explanations (hook, subject, mediaUrls grid behavior, quotePostId exclusions, altText arrays), so the baseline of 3 applies. The description adds contextual semantics around account-specific length limits affecting text/thread and the cost difference between one long post and several thread posts, but the schema carries the parameter-level burden.

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 — 'Publish to the user's connected X (Twitter) account' — and enumerates the exact modes: single post, post with media, reply, thread, poll, and restricted replies. It also separates itself from ad creation by stating 'THIS TOOL POSTS ORGANICALLY — it does not create an ad campaign,' and its X-specificity distinguishes it from sibling channel tools like post_to_bluesky and post_to_linkedin.

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?

Routing to the closest alternative is explicit: promoted posts belong to create_x_ads_campaign → create_x_ads_line_item → create_x_ads_promoted_tweet, and this tool should be called first to produce the post id. It also prescribes when to prefer one long post over a thread ('prefer one long post over threading when the account has Premium') and requires X to be connected. It does not explicitly contrast with schedule_post or post_x_article, though immediate publishing is emphasized.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Deploy Server

Other Tools