Skip to main content
Glama

Server Details

Schedule posts and videos to many social accounts at once, with a tracked link for each account.

Ownership verified
Status
Healthy
OAuth
Works in Glama
Last Tested
Transport
Streamable HTTP · MCP 2025-11-25
URL

TDQS

A3.6/5.0

Scored across 39 tools

Disambiguation4/5

Most tools target a distinct resource+action pair, and the long descriptions explicitly state boundaries (e.g. cancel_post vs delete_post vs update_post, hide_comment vs delete_comment vs reply_to_comment). A few clusters still overlap: create_post accepts schedule_at and thus duplicates schedule_post, get_structure returns the same tree as list_workspaces/list_channels/list_groups combined, and get_claim_link vs create_connect_link both mint links for humans. These are recoverable via the descriptions but require careful reading.

Naming Consistency4/5

Nearly everything follows a clean verb_noun snake_case pattern (list_posts, create_webhook, update_auto_reply, send_test_webhook). Minor deviations exist: reply_to_comment uses a prepositional verb instead of create_reply, and whoami is a single-token idiom. The set is still highly predictable overall.

Tool Count3/5

39 tools is heavy, though the surface genuinely spans a large domain (12 networks, workspaces/groups, media, comments, auto-replies, approvals, webhooks, team, analytics, holidays, X budget). Several tools are thin single-purpose utilities (get_holidays, set_x_budget, get_claim_link, whoami) that could be folded into a broader get/settings call. The count is defensible but at the upper edge of comfortable scoping.

Completeness4/5

Post, comment, auto-reply, webhook, group and workspace lifecycles are largely covered (create/list/get/update/delete plus validation and scheduling). Gaps remain: no list_media or delete_media despite upload_media_from_url, no update_group/delete_group, no remove_member or update_member_role, and no tool for managing tracked links even though they are referenced throughout.

Available Tools

39 tools
cancel_postCancel a scheduled postA
DestructiveIdempotent
Inspect

Unschedules a post that has not started publishing (it stays as an approved draft you can schedule again).

NameRequiredDescriptionDefault
post_idYes
workspace_idYesWorkspace id from list_workspaces

TDQS

A3.8/5.0
Behavior4/5

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

Annotations already declare the mutation profile (readOnlyHint=false, destructiveHint=true, idempotentHint=true), so the bar is lower. The description still adds real value the annotations cannot: the post is not removed but demoted to an approved draft, and the action is reversible via re-scheduling — useful context against a destructiveHint label. It does not cover error behavior or permissions.

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?

One sentence, zero waste, with the precondition and the resulting state front-loaded. Nothing repeats the title or annotations.

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 two-parameter mutation with no output schema and solid annotations, the description covers the essential outcome and precondition. The remaining gap — failure mode when the post is already publishing, and the post_id semantics — is minor but real.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

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

Schema coverage is 50%: workspace_id is documented ('from list_workspaces') but post_id has no description at all. The description adds no parameter-level meaning — not even that post_id must identify a scheduled, not-yet-publishing post. With half the parameters undocumented, the description should be compensating and is not.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('Unschedules') and resource ('post'), and the parenthetical ('stays as an approved draft you can schedule again') implicitly distinguishes it from delete_post by naming the resulting state rather than removal. Sibling differentiation is present but implicit — no sibling is named.

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?

'a post that has not started publishing' gives a clear precondition that scopes when the tool applies, and 'you can schedule again' points to the recovery path (schedule_post). It stops short of saying what to do when the post has already started publishing — presumably an error case that is left unstated.

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

create_auto_replyCreate an auto-replyA
Destructive
Inspect

Adds a rule that answers comments or direct messages automatically, on the person's behalf, from now on (never older comments). trigger COMMENT: when someone comments (optionally only with one of keywords, whole words, any case; only on post_ids; only on channel_ids), post one of public_replies (picked at random) under the comment and/or send message (+ link_url as a tracked short link) privately to the commenter, once per comment within 7 days. trigger MESSAGE: when someone sends a direct message (optionally with a keyword), answer with message within 24 hours. once_per_person (default true) answers each person once per rule per 30 days. At most 120 replies per account per hour. This sends messages to real people without a human in the loop: show the person the exact texts and get their OK before creating it enabled, or create it with enabled=false. (Not available in an unclaimed sandbox.)

NameRequiredDescriptionDefault
nameYesA short name the person will recognize, e.g. "Link in DM"
enabledNo
messageNoThe private message (to the commenter, or the answer to a direct message)
triggerYesCOMMENT: someone comments on a post. MESSAGE: someone sends a direct message
keywordsNoWhole words or phrases, any case; empty = every comment or message
link_urlNoAdded at the end of the private message as a tracked short link
post_idsNoCOMMENT only: only comments on these Shager posts; empty = every post
channel_idsNoOnly these accounts; empty = every account that supports the trigger
workspace_idYesWorkspace id from list_workspaces
public_repliesNoCOMMENT only: public answers under the comment, one picked at random
idempotency_keyNoAny unique string you choose (REST: the Idempotency-Key header works too). Retrying with the same key and body returns the first result instead of creating a second one. Kept 24 hours.
once_per_personNoAnswer each person once per rule (30 days)

TDQS

A4.8/5.0
Behavior5/5

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

Goes well past the annotations: discloses rate limits (120 replies/account/hour), dedupe windows (once per comment within 7 days, per person per 30 days, 24-hour DM window), that public replies are picked at random, that link_url becomes a tracked short link, and that this messages real people without human review — consistent with destructiveHint=true. That safety framing is exactly the context an agent needs before a write with real-world side effects.

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-loaded with the core action and effect, then trigger-specific rules, then the safety caveat — every sentence carries information. It is dense to the point of being a single wall of text, which slightly hurts scanability, but nothing is filler.

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 12-parameter mutation with no output schema and openWorldHint=true, the description covers timing, scoping, rate limits, failure/sandbox constraints, and the human-approval requirement. An agent has everything needed to decide whether and how to call it.

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 92%, so the schema already carries most parameter meaning; the description still adds value by explaining cross-parameter semantics the schema does not — which params apply to COMMENT vs MESSAGE, that public_replies is randomly selected, and that link_url is appended as a tracked short link. It does not explain enabled's default/effect beyond the safety note, leaving a small gap.

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 ('Adds a rule that answers comments or direct messages automatically') and immediately delimits scope ('from now on, never older comments'). It is clearly distinguishable from siblings like update_auto_reply and list_auto_replies without opening a 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?

Gives explicit when-to-use conditions per trigger type, plus a when-not condition ('Not available in an unclaimed sandbox') and a safety protocol for the risky path ('get their OK before creating it enabled, or create it with enabled=false'). The routing between COMMENT and MESSAGE usage is fully spelled out.

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

create_groupCreate an account groupAInspect

Create a group inside one workspace: a named set of its channels, so a post can target all of them at once. channel_ids must belong to this workspace.

NameRequiredDescriptionDefault
nameYes
channel_idsNo
workspace_idYesWorkspace id from list_workspaces
idempotency_keyNoAny unique string you choose (REST: the Idempotency-Key header works too). Retrying with the same key and body returns the first result instead of creating a second one. Kept 24 hours.

TDQS

A3.6/5.0
Behavior3/5

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

Annotations already declare this is a non-read-only, non-destructive, non-idempotent, closed-world write, so the safety profile is covered. The description adds the real validation rule that channel_ids must belong to the workspace, but says nothing about name collisions, what happens to an existing group with the same name, or what the call returns. Note the idempotentHint=false annotation while the schema exposes an idempotency_key — the description doesn't reconcile this, though it does not contradict it either.

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?

Two sentences, zero filler, with the definition and the cross-workspace constraint both front-loaded. Nothing repeats the title or annotations.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, an agent doesn't learn what a successful create returns (presumably a group id for later post targeting), and duplicate-name behavior is unstated. The annotations plus the workspace constraint cover most of what's needed to call it correctly, but the post-call picture is incomplete.

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 only 50%: workspace_id and idempotency_key are documented in the schema, while name and channel_ids are not. The description compensates by defining name as the group's name and channel_ids as this workspace's channels, which is meaningful added constraint beyond the bare array schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Uses a specific verb+resource ('Create a group inside one workspace') and defines what a group is — a named set of channels used for post targeting. That definition implicitly separates it from list_groups and create_workspace, but no sibling is named explicitly, so it falls short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives a purpose-driven context ('so a post can target all of them at once') and one hard constraint ('channel_ids must belong to this workspace'), which implies when to use it. It stops short of stating when-not-to-use, whether to check list_groups first for duplicates, or any prerequisites beyond workspace membership.

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

create_postCreate a postA
Destructive
Inspect

One post, many accounts. Pick accounts with channel_ids and/or group_ids from one workspace; the post gets one destination per account, each with its own format, text override and network fields (per_channel). Without schedule_at the post is saved as a DRAFT and the response lists every validation issue (issues[]) so you can fix them with update_post; nothing is published. With schedule_at it is validated (all issues at once), checked against the key's caps and the X link allowance, and scheduled — then every account publishes at its own staggered time. Formats: default per network (Facebook/Instagram FEED, REEL with a video; YouTube SHORT; TikTok VIDEO; LinkedIn FEED, VIDEO with a video; X FEED). An unsupported format is an issue, never swapped silently. Links: cta_url becomes a tracked short link per account with UTM tags — in the caption where links are clickable (Facebook, LinkedIn, YouTube, Bluesky, Telegram, Mastodon) and in the first comment on Instagram. first_comment is a comment on Facebook/Instagram/YouTube and LinkedIn company Pages, a reply on X, Bluesky and Mastodon, and skipped on LinkedIn profiles, TikTok and Telegram. On X nothing is added automatically and any link you write (text or reply) costs one of the plan's monthly X link posts (whoami shows what is left). TikTok: per_channel.tiktok_privacy is required per account (values from list_channels); comments/duet/stitch default to off; set tiktok_commercial with brand_organic/brand_content for ads. YouTube: youtube_title/privacy/made_for_kids, overridable per channel. Time: schedule_at is ISO 8601 with an offset (2026-10-20T09:00:00+03:00); its exact UTC instant is preserved; the workspace timezone is for display. Staggering: accounts on one network go out one after another with a random stagger_min_seconds–stagger_max_seconds pause (default 30–90 s; Facebook and Instagram share a lane). Sends to more than 10 accounts or within 60 minutes need confirmation_token from the returned plan (you first get needs_confirmation with the plan). A different time per network, in the same post: schedule_at is the earliest send, and per_channel.delay_minutes moves an account later (Instagram 9:00, LinkedIn 12:00, X 18:00 = schedule_at 9:00, LinkedIn 180, X 540). get_post shows each account's send_at. Approval: if the workspace has approval_required, create the draft, request_approval, wait for get_approval to show approved, then schedule_post. Vary the caption per account — identical mass posts look like spam. With schedule_at the post goes out publicly on the person's real accounts at that time: only schedule what your human asked to publish.

NameRequiredDescriptionDefault
pollNoA poll on X, LinkedIn and Mastodon. A poll post carries no media.
labelNoInternal name for the post (never published).
formatNoFormat for every account. Default per network: Facebook/Instagram FEED (REEL with a video), YouTube SHORT, TikTok VIDEO, LinkedIn FEED (VIDEO with a video), X FEED. Unsupported on a network = an issue, not a silent change.
captionYesMaster text. Goes to every account unless per_channel overrides it. X: 280 characters; Bluesky: 300; Mastodon: 500 (links count as 23); Instagram and TikTok: 2,200; Telegram: 4,096 for text, 1,024 under photos, a video or a file.
confirmNoDeprecated boolean; does not bypass confirmation. A confirmation_token is required when a schedule goes to more than 10 accounts, starts within 60 minutes, or includes a Pinterest account. Without it you get needs_confirmation with the dispatch plan; show it to your human, then resend with confirmation_token from the returned plan.
cta_urlNoLink to track. Each account gets its own short link with UTM tags, placed in the caption or the first comment per network. Never added on X (paid links).
gbp_endNoGoogle Business Profile event or offer: when it ends (not before gbp_start), same format.
campaignNoutm_campaign value for the tracked links.
cta_textNo
draft_idNoReserved post ID returned by validate_post or needs_confirmation. Pass it unchanged to create_post so previewed tracked URLs and the confirmation plan remain exact.
gbp_linkNoGoogle Business Profile: where the button (or an offer's "redeem online") leads, https. Omitted: cta_url. Either way it becomes a tracked short link; links in the post's text aren't clickable on Google.
gbp_typeNoGoogle Business Profile: STANDARD (an update, the default), EVENT or OFFER. Events and offers need gbp_title, gbp_start and gbp_end.
x_threadNoX: up to 5 follow-up posts that continue the post as a thread (each is a paid X post).
alt_textsNoImage descriptions for screen readers, by media id (images in media_ids). Sent to Instagram, Facebook, X, LinkedIn, Bluesky and Mastodon. Stored on the image, so later posts reuse it; an empty string clears it.
gbp_startNoGoogle Business Profile event or offer: when it starts, in the location's own time, "2026-11-05" (the whole day) or "2026-11-05T18:30". No time zone.
gbp_termsNoGoogle Business Profile offer: terms and conditions (optional).
gbp_titleNoGoogle Business Profile event or offer: its title (required there, up to 58 characters).
group_idsNoAccount groups — every active account in them is added to channel_ids.
media_idsNoMedia from upload_media_from_url, in display order. Instagram, TikTok and YouTube need media; Reels/Shorts/Video need a video file.
gbp_buttonNoGoogle Business Profile update or event: the button. CALL dials the profile's phone number (no link); the others lead to gbp_link or cta_url. Omitted with a link: LEARN_MORE. Offers get Google's own button instead.
gbp_couponNoGoogle Business Profile offer: a coupon code (optional).
channel_idsNoAccounts to publish to (ids from list_channels).
per_channelNoPer-account overrides and network fields. TikTok accounts need tiktok_privacy here.
schedule_atNoISO 8601 with offset, e.g. 2026-10-20T09:00:00+03:00. Omit to save a draft.
video_titleNoVideo title on Facebook and LinkedIn videos (YouTube uses youtube_title).
ai_generatedNoMade or meaningfully altered with AI. Sent as each network's AI label: Instagram, Facebook Reels, YouTube (altered or synthetic content), TikTok (AI-generated), X (made with AI), Pinterest (AI-modified disclosure).
workspace_idYesWorkspace id from list_workspaces
youtube_tagsNoYouTube tags, 500 characters in total.
first_commentNoPosted right after the post as its first comment (the usual place for a lead link). Facebook, Instagram, YouTube: a comment. X: a reply (a link in it counts against the X link allowance). LinkedIn company Pages: a comment as the Page. LinkedIn profiles and TikTok: skipped (list_channels first_comment=false).
post_languageNoMastodon: the post's language as an ISO 639-1 code (he, en, es…); omitted = the account's default.
threads_topicNoThreads: the post's topic, 1–50 characters, no period or ampersand (e.g. Recipes).
youtube_titleNoYouTube video title (default: first line of the caption). Overridable per channel.
cover_media_idNoCover image for the post's video: an IMAGE id from upload_media_from_url (not in media_ids). A cover the network refuses never fails the post: the result carries a notice. null removes it. Per network ("Cover at the start of the video" is cover_first_frame): Facebook: The image becomes the thumbnail of the video or Reel. Stories have no cover. Instagram: The image becomes the Reel's cover, in the feed and on the profile. Stories have no cover. YouTube: The image becomes the video's thumbnail. YouTube allows this only for phone-verified channels (youtube.com/verify); without that, the video goes up with a thumbnail YouTube picks. X: X has no cover setting: it shows the video's first frame. To show your cover, turn on "Cover at the start of the video". LinkedIn: The image becomes the video's thumbnail. TikTok: TikTok takes no cover image through its API, only a moment of the video, and applies even that only to public posts (a private post shows the first frame). To always show your cover, private posts included, turn on "Cover at the start of the video". Bluesky: Bluesky has no cover setting: it shows the video's first frame. To show your cover, turn on "Cover at the start of the video". Telegram: The image becomes the video's cover in the channel. Mastodon: The image is shown on the video on Mastodon until it's played. Threads: Threads has no cover setting: it shows the video's first frame. To show your cover, turn on "Cover at the start of the video". Pinterest: The image becomes the video Pin's cover on Pinterest. Google Business Profile: Google Business Profile posts take no video, so there is no cover.
paid_promotionNoPaid promotion or partnership disclosure: YouTube (paid product placement), X (paid partnership). TikTok uses tiktok_commercial.
pinterest_linkNoPinterest: where the Pin leads (https). Omitted: cta_url. Either way it becomes a tracked short link; links in the description aren't clickable on Pinterest.
content_warningNoMastodon: a content warning shown before the post (readers tap to see it; it also hides images). Counts toward the 500 characters.
idempotency_keyNoAny unique string you choose (REST: the Idempotency-Key header works too). Retrying with the same key and body returns the first result instead of creating a second one. Kept 24 hours.
pinterest_titleNoPinterest: the Pin's title, up to 100 characters (feeds show about the first 40). The caption is the Pin's description (≤800).
stagger_secondsNoDeprecated: [min, max] — use stagger_min_seconds and stagger_max_seconds.
telegram_silentNoTelegram: send without a sound, so channel subscribers get no notification.
tiktok_cover_msNoTikTok: which frame of the video becomes the cover, in milliseconds from the start (TikTok can't take a cover image). TikTok applies it to public posts only; private posts show the first frame. To show your cover image on every TikTok post, public or private, use cover_media_id with cover_first_frame instead. Default: the first frame.
youtube_licenseNoYouTube license (default youtube).
youtube_privacyNoYouTube: public (default), unlisted or private.
x_reply_settingsNoX: who can reply (default everyone): following, mentionedUsers, subscribers or verified.
cover_first_frameNoPut the cover image (cover_media_id) at the start of the video, as its first two frames (~1/15 s), so networks that show the video's first frame show your cover: true = only where the network can't take a cover image (TikTok, X, Bluesky, Stories), "all" = on every network, false = never. The original video isn't changed; Shager publishes a copy. Default when omitted: true if the post has a cover and goes to TikTok, X or Bluesky, else false.
threads_link_cardNoThreads text post (no media): an https link shown as a card under the text (link_attachment). Without it, Threads previews the first link in the text.
confirmation_tokenNoToken returned by needs_confirmation or validate_post for this exact plan; expires after 15 minutes.
pinterest_board_idNoREQUIRED for a Pinterest account (per_channel, since each account has its own boards): the board the Pin goes to, one of that account's pinterest.boards from list_channels.
youtube_embeddableNoYouTube: allow embedding on other sites (default true).
facebook_pin_to_topNoFacebook: pin the post to the top of the Page (feed posts).
instagram_user_tagsNoInstagram single photo: people tagged on it, x/y from 0 to 1 measured from the top-left.
linkedin_visibilityNoLinkedIn: PUBLIC (default), CONNECTIONS or LOGGED_IN.
mastodon_visibilityNoMastodon: who sees the post: public (default), unlisted (quiet public: not in public timelines or hashtags) or private (followers only).
stagger_max_secondsNoLongest pause between two accounts of the same network (default 90).
stagger_min_secondsNoShortest pause between two accounts of the same network (default 30). Facebook and Instagram share one lane.
youtube_category_idNoYouTube category id (default 22, People & Blogs).
youtube_playlist_idNoYouTube: add the video to this playlist of the channel (per_channel, since each channel has its own playlists).
facebook_link_buttonNoFacebook text post: a button (e.g. LEARN_MORE, SHOP_NOW, SIGN_UP, BOOK_NOW) that opens the post's link, usually cta_url. If Facebook refuses the button, the post goes without it.
instagram_trial_reelNoInstagram trial Reel, shown to non-followers first: MANUAL (you share it later from the app) or SS_PERFORMANCE (shared automatically if it performs well).
instagram_location_idNoInstagram: the location shown on the post, as the numeric id of a Facebook Page for that place (Meta's location_id; Shager has no place search yet, so pass an id you already know). Feed photos, carousels and Reels; per_channel to vary it per account.
threads_reply_controlNoThreads: who can reply: everyone (default), accounts_you_follow, mentioned_only or followers_only.
youtube_made_for_kidsNoYouTube's made-for-kids declaration (COPPA). Required explicitly when targeting YouTube; declare whether the video is made for children.
instagram_comments_offNoInstagram: turn comments off right after publishing.
instagram_collaboratorsNoInstagram: up to 3 usernames invited as collaborators (feed, carousel, Reel). The post appears on their profile once they accept in the app.
instagram_share_to_feedNoInstagram Reel: also show it in the profile's main grid (default true).
linkedin_disable_reshareNoLinkedIn: stop others from resharing the post.
youtube_notify_subscribersNoYouTube: notify subscribers about the upload (default true).

TDQS

A4.6/5.0
Behavior4/5

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

Annotations already flag destructive/openWorld/not-idempotent, but the description adds the crucial consequence: the post publishes publicly on real accounts, X links consume a paid monthly quota, sends over 10 accounts or within 60 minutes trigger needs_confirmation with a plan, and staggering applies per network. It omits retry/idempotency behavior (deferred to the schema's idempotency_key), which keeps it from a 5.

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-loaded with the core purpose, then logically grouped by drafts/scheduling, formats, links, per-network quirks, time, and approval. It is long, but the 67-parameter surface justifies most of it; a few per-network link/comment lists overlap with schema descriptions.

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?

No output schema exists, yet the description covers the response shape it must: issues[] on draft validation, needs_confirmation with a plan, confirmation_token, and post-approval scheduling. For a tool this complex, an agent has what it needs to call it correctly and interpret results.

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 99% schema coverage the baseline is 3, but the description adds cross-parameter meaning the schema cannot: schedule_at as the earliest send with per_channel.delay_minutes moving accounts later (with a concrete 9:00/12:00/18:00 example), per-network format defaults and silent-swap prohibition, and cta_url/first_comment placement rules per network.

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 opening sentence — 'One post, many accounts' — states a specific verb and resource, and immediately distinguishes fan-out creation from siblings like update_post, schedule_post, and validate_post. An agent can identify the tool's role without opening the 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?

Explicit branching: without schedule_at it saves a draft and returns issues to fix with update_post; with schedule_at it validates, checks caps, and schedules. It also names the approval flow (request_approval → get_approval → schedule_post) and the confirmation-token threshold, leaving little to inference.

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

create_webhookAdd a webhook endpointA
Destructive
Inspect

Instead of polling get_post, have Shager POST events to your HTTPS endpoint (a CRM, your agent's server): post.destination.published (data: post_id, destination_id, channel_id, network, account, format, remote_url, remote_post_id, published_at, notice), post.destination.failed (… error, unconfirmed), post.completed (post_id, status, counts, destinations[] with state and remote_url), approval.decided (post_id, approval_id, decision, post_status, reviewer.name, comment). Body: { id, type, created_at, data } (data always has workspace_id). The id is the same on every retry: dedupe on it. Order is not guaranteed. Headers: Shager-Event-Id, Shager-Event-Type and Shager-Signature: t=,v1=<hex HMAC-SHA256 of "." with the secret>. Verify it on the raw body in constant time and refuse timestamps older than 5 minutes. Answer 2xx within 10 s. Anything else (redirects included) is retried: 6 attempts over about a day. An endpoint whose every attempt fails for 3 days is turned off; a successful send_test_webhook turns it back on. Signing secret (whsec_…): the REST API returns it once, in this response. Through an AI assistant it is never returned: the person copies a fresh one in the app (the workspace's Settings → webhooks → "New signing key") and puts it in the receiving system. https only; private, local and credentialed URLs are refused. Up to 10 endpoints per workspace. Publishing never waits for webhooks. (Not available in an unclaimed sandbox.)

NameRequiredDescriptionDefault
urlYeshttps:// URL that receives the events.
eventsNoEvent types to send. Omit for every event, including ones added later.
descriptionNoWhat it is for (shown in the app).
workspace_idYesWorkspace id from list_workspaces

TDQS

A4.6/5.0
Behavior5/5

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

Goes far beyond the annotations: retry policy (6 attempts over ~a day, redirects treated as failures), 10s 2xx window, auto-disable after 3 days of failure and re-enable via send_test_webhook, at-least-once delivery with a stable event id for dedupe, unordered delivery, and the HMAC signature scheme with a 5-minute replay window. It also discloses the secret-return behavior, which is the one thing an agent most needs to know. No contradiction with destructiveHint/openWorldHint/idempotentHint — the outbound POST side effects and at-least-once semantics are consistent with them.

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?

Purpose and the polling alternative are front-loaded in sentence one, and essentially every subsequent sentence carries operational information. It is, however, a dense unbroken block with no paragraph or list structure, and the payload field enumerations are verbose enough to slow scanning; minor restructuring would improve it without cutting content.

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?

With no output schema, the description correctly covers the return value: the signing secret is returned exactly once in this response via REST but never through an AI assistant, with the manual app-based workaround spelled out. Combined with delivery, retry, and verification behavior, an agent has everything needed to create the endpoint and tell the user what to do next.

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 100%, so the schema carries the field definitions and baseline would be 3. The description adds real constraint semantics the schema lacks — the HTTPS-only rule and the refusal of private, local, and credentialed URLs for `url`, plus the per-workspace cap that bounds how many of these can exist — which meaningfully sharpens how the agent should construct `url`.

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 and resource plus the alternative it replaces: 'Instead of polling get_post, have Shager POST events to your HTTPS endpoint'. It then enumerates the exact event types this endpoint will receive, so an agent can distinguish it from delete_webhook, list_webhooks, and send_test_webhook without reading the schema.

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?

Explicitly frames the use case as a push alternative to polling get_post, and gives hard constraints that gate invocation: https only, no private/local/credentialed URLs, max 10 endpoints per workspace, unavailable in an unclaimed sandbox. It does not explicitly point to list_webhooks for checking existing endpoints or delete_webhook for removal, so it stops short of full sibling routing.

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

create_workspaceCreate a workspaceAInspect

Create a workspace for a new client (agency) or brand. Its accounts are then connected inside it (create_connect_link). Its timezone is how schedule times without an offset are read and how dates are shown.

NameRequiredDescriptionDefault
nameYes
timezoneNoIANA zone, default Asia/Jerusalem
idempotency_keyNoAny unique string you choose (REST: the Idempotency-Key header works too). Retrying with the same key and body returns the first result instead of creating a second one. Kept 24 hours.
approval_requiredNoRequire client approval before scheduling (default false for agents).

TDQS

A3.7/5.0
Behavior4/5

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

Annotations already declare the mutation is non-destructive and non-idempotent, so the description only needs to add context. It does: it explains the downstream effect of the workspace (accounts connected inside) and, unusually usefully, spells out the consequences of the timezone setting on un-offset schedule times and date display. It leaves the approval_required default behavior unaddressed, keeping it short of a 5.

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?

Three short sentences, each earning its place: the first identifies the resource and its owner, the second names the follow-up tool, the third defines a tricky parameter's effect. No filler and the core purpose is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a creation mutation with no output schema, the description never says what comes back (presumably a workspace id) even though the mentioned create_connect_link flow depends on it. Between that gap and the silent approval_required default, it is adequate but not complete enough to call the tool confidently end-to-end.

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 coverage is 75%, with timezone, idempotency_key and approval_required already documented in the schema, so baseline 3 applies. The description does add real meaning for timezone — how it is interpreted downstream — but says nothing about approval_required's 'default false for agents' semantics or how name is used, so it does not clearly exceed the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a clear verb+resource ("Create a workspace") and adds scope that the name alone doesn't convey: a workspace belongs to a client/agency or brand. It does not explicitly contrast itself with list_workspaces or update-style siblings, but the create semantics are unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage (a workspace must exist before its accounts are connected) and points to create_connect_link as the follow-up step. However, it never states when-not to use it — e.g. that an existing workspace should be found via list_workspaces rather than recreated — leaving the agent to infer preconditions.

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

delete_auto_replyDelete an auto-replyA
DestructiveIdempotent
Inspect

Deletes a rule; it stops answering at once. Its activity stays in list_auto_reply_activity (kept 90 days).

NameRequiredDescriptionDefault
rule_idYes
workspace_idYesWorkspace id from list_workspaces

TDQS

A3.7/5.0
Behavior4/5

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

Annotations already declare destructive=true and idempotent=true. The description adds useful behavior beyond that: the rule stops answering immediately and its activity remains available in list_auto_reply_activity for 90 days.

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?

Two short sentences with the core delete behavior front-loaded. The retention detail in the second sentence is useful and earns its place.

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 simple two-parameter delete tool with rich annotations and no output schema, the description covers the key behavioral consequences. It still leaves a gap around obtaining rule_id and does not clarify when to choose deletion over update/disable.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

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

Schema description coverage is only 50%: workspace_id is described in the schema, but rule_id is undocumented in both schema and description. The phrase 'a rule' weakly maps to rule_id but does not explain its format, source, or lookup method.

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 ('Deletes') and object ('rule'), plus the immediate effect ('stops answering at once'), which identifies the auto-reply deletion operation and separates it from list_auto_replies and update_auto_reply.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no explicit when-to-use or when-not-to-use guidance, and no alternative is named. It does not address whether an agent should delete versus update/disable an auto-reply.

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

delete_commentDelete a commentA
DestructiveIdempotent
Inspect

Deletes a comment from the network for good. Instagram and Facebook: any comment on the account's post. YouTube: only the account's own comments (hide others instead). Bluesky and Mastodon: only the account's own replies. Cannot be undone. (Not available in an unclaimed sandbox.)

NameRequiredDescriptionDefault
post_idYes
channel_idYes
comment_idYes
workspace_idYesWorkspace id from list_workspaces

TDQS

A4.4/5.0
Behavior4/5

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

Annotations already declare destructiveHint and idempotentHint, so the safety profile is covered. The description adds non-obvious behavior beyond that: irreversibility, platform-specific ownership restrictions, and unavailability in an unclaimed sandbox. It stops short of describing failure modes (e.g., what happens when deleting a non-owned comment) or the response, keeping it at 4.

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?

Four dense sentences, no waste, with the destructive nature and platform scoping front-loaded. Every clause carries actionable information (per-platform rules, undo warning, sandbox caveat).

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 destructive 4-param tool with no output schema, the definition covers the essential risks (irreversible, platform-limited, sandbox-restricted). The remaining gap is channel_id semantics and error behavior, which are minor but real.

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 coverage is only 25%, and only workspace_id is documented (via list_workspaces). The description clarifies what a 'post' or 'comment' means per platform, which indirectly helps post_id/comment_id, but channel_id and comment_id semantics are left entirely unstated in both schema and description.

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 (deletes) and resource (a comment), and immediately scopes it per platform (Instagram/Facebook any comment, YouTube/Bluesky/Mastodon own only). It even distinguishes itself from the sibling hide_comment by naming it as the alternative for non-owned YouTube comments.

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 explicit per-platform eligibility rules and routes the agent to hide_comment when the comment isn't owned. The sandbox exclusion is a clear when-not condition, leaving little to inference.

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

delete_postDelete a draftA
DestructiveIdempotent
Inspect

Deletes a post that is not scheduled and never published (DRAFT, IN_REVIEW, CHANGES_REQUESTED, APPROVED, or a canceled post). A pending approval link stops working. Scheduled posts: cancel_post first. Published posts stay for their analytics. Cannot be undone through the API.

NameRequiredDescriptionDefault
post_idYes
workspace_idYesWorkspace id from list_workspaces

TDQS

A4.7/5.0
Behavior5/5

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

Annotations already declare destructiveHint=true and idempotentHint=true, so the safety profile is covered; the description goes well beyond by naming concrete consequences (approval link invalidated, analytics retention decision for published posts) and a hard constraint the annotations cannot express ('Cannot be undone through the API'). This is exactly the value-add expected when annotations are present.

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?

Four short clauses, each carrying distinct information: eligibility, side effect, sibling routing, irreversibility. The eligibility constraint is front-loaded where the agent needs it for a routing decision, and no sentence restates the title or annotations.

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 two-parameter destructive mutation with no output schema, everything an agent needs is present: status eligibility, the alternative for scheduled posts, the analytics rationale for published posts, and the irreversibility warning. Remaining gap (post_id documentation) is shared with the schema rather than a description omission.

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 coverage is 50%: workspace_id is documented in the schema ('Workspace id from list_workspaces') but post_id is undocumented in both schema and description. The description adds no format, source, or lookup guidance for post_id, so it neither compensates for the gap nor adds much beyond the schema — baseline 3.

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 (deletes) and resource (post) and immediately bounds scope by an enumerated list of eligible statuses (DRAFT, IN_REVIEW, CHANGES_REQUESTED, APPROVED, canceled). It also names the sibling distinction (scheduled posts → cancel_post; published posts are preserved), so an agent can separate this from cancel_post without opening a 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?

Explicit when-to-use is encoded as status preconditions, with a named alternative for the excluded case ('Scheduled posts: cancel_post first') and a stated exclusion for published posts. It even flags a side effect an agent should weigh before calling ('A pending approval link stops working').

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

delete_webhookDelete a webhook endpointA
DestructiveIdempotent
Inspect

Stops sending events to this endpoint, including retries still pending. Cannot be undone.

NameRequiredDescriptionDefault
webhook_idYes
workspace_idYesWorkspace id from list_workspaces

TDQS

A3.6/5.0
Behavior3/5

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

Annotations already declare destructiveHint=true and idempotentHint=true, so the safety profile is covered structurally. The description does add genuine context beyond them: that queued retries are also cancelled and that the action is irreversible. It still omits practical behavior such as what happens to delivery history or how a missing webhook_id is handled.

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?

Two short sentences with no filler, and the destructive consequence is front-loaded ahead of the irreversibility warning. Nothing could be removed without losing 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 two-parameter destructive delete whose annotations already flag destructiveness and idempotency, the description supplies the key missing facts: retry cancellation and non-reversibility. Only minor gaps remain, such as failure modes and whether auth or ownership is required.

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 coverage is 50%: workspace_id is documented as coming from list_workspaces, while webhook_id has no description anywhere. The description says nothing about either parameter, though both names are largely self-explanatory, so the gap is modest rather than harmful.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('Stops sending events') on a specific resource ('this endpoint'), which unambiguously distinguishes it from create_webhook and list_webhooks. It never names a sibling explicitly, but the mutation-versus-listing distinction is obvious from the phrasing.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied rather than stated: the agent can infer this is the teardown path for a webhook, and 'including retries still pending' signals the consequence of choosing it over waiting. There is no explicit when-to-use/when-not-to-use guidance or reference to update_webhook-style alternatives.

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

get_analyticsHow posts are doingA
Read-onlyIdempotent
Inspect

How a workspace's posts did in a period: views, reach, likes, comments, shares, saves, engagement (likes + comments + shares + saves) and engagement rate, clicks on Shager's tracked links, and followers — in total, compared with the previous period of the same length, day by day, by network, by account, and the top posts. Numbers come from each network's own API and refresh every few hours (often in a post's first day, then less). A post counts in the period it was published in, with its latest numbers. Totals add up what the networks report: Facebook views appear once Meta approves read_insights, LinkedIn shares numbers only for company Pages (impressions as views, unique impressions as reach, likes, comments, shares; followers) and none for personal profiles, and a TikTok account counts only after it is reconnected with the video-reading permission and only for its public videos (otherwise by_network.measured=false, coverage.notes) — only their link clicks count. get_post shows one post per account, with null for a number the network doesn't report. Use it to answer 'what worked this week', to pick the best time or format, or to report to a client. Filter with channel_ids or group_ids.

NameRequiredDescriptionDefault
toNoDate (2026-10-31, inclusive) or ISO datetime. Default: now
topNoHow many top posts to return (default 10)
fromNoDate (2026-10-01) or ISO datetime. Default: 30 days ago
group_idsNoOnly the accounts in these groups (from list_groups)
channel_idsNoOnly these accounts (from list_channels)
workspace_idYesWorkspace id from list_workspaces

TDQS

A4.6/5.0
Behavior5/5

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

Annotations already establish a safe read-only, idempotent operation, yet the description adds substantial context the annotations cannot: refresh cadence ('every few hours, often in a post's first day'), attribution rule (a post counts in the period it was published, with its latest numbers), and per-network measurement gaps including the explicit by_network.measured=false / coverage.notes signal. That is exactly the caveat-level disclosure this dimension rewards.

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-loaded correctly: metrics and breakdowns first, then freshness, then the caveats, then use cases and filters. The network-caveat parenthetical about LinkedIn/TikTok is dense and back-loaded, but each clause carries real behavioral information rather than restating the schema.

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?

There is no output schema, so the description must carry the return shape itself — and it does: totals with prior-period comparison, day-by-day, by network, by account, top posts, and the null/measured-flag conventions. For a six-parameter read tool this is as complete as an agent needs to call it and interpret the response.

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 100% and each parameter is self-documented, so the baseline is 3; the description earns above baseline by explaining the period semantics that give from/to their meaning (the previous comparison window is 'the same length', and posts are attributed by publication date). It does not explain how the 'top' posts are ranked or selected, which is the one semantic the schema leaves open.

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 names the exact resource (a workspace's posts over a period) and enumerates every metric returned — views, reach, likes, comments, shares, saves, engagement, engagement rate, link clicks, followers — plus the comparison and breakdown dimensions. It also explicitly separates itself from the sibling get_post, which shows one post at a time with nulls for unreported numbers.

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 gives concrete use cases ('what worked this week', choosing best time or format, client reporting) and routes single-post lookups to get_post. What it lacks is a clear when-NOT-to-use or a statement about which sibling to pick for other reporting needs (e.g. list_posts vs this), so the agent must still infer some routing.

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

get_approvalGet the approval state of a postB
Read-onlyIdempotent
Inspect

The latest approval request for a post: decision (PENDING, APPROVED, CHANGES_REQUESTED, REJECTED), the reviewer, when it was opened and decided, and the reviewer's comment.

NameRequiredDescriptionDefault
post_idYes
workspace_idYesWorkspace id from list_workspaces

TDQS

B3.2/5.0
Behavior3/5

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

Annotations already declare readOnlyHint, idempotentHint and non-destructive, so safety is covered. The description adds one genuine behavioral fact beyond that: only the LATEST approval is returned, not the full history. It does not say what happens when no approval request exists (empty vs error), which is a real ambiguity for the caller.

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?

A single sentence that front-loads the scope ('latest approval request for a post') and then enumerates the returned fields, including the full decision enum. Nothing is redundant and nothing is padding.

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?

With no output schema, the description correctly shouldered the return-value burden and does so by listing decision values, reviewer, timestamps and comment. The only material omission is behavior when no approval request exists, plus no hint about post_id sourcing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

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

Schema coverage is 50%: workspace_id is documented ('from list_workspaces') but post_id has no description at all. The description mentions 'a post' but adds no format, source, or constraint detail for either parameter, so it does not compensate for the gap as low-coverage schemas require.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description identifies a specific resource ('the latest approval request for a post') and enumerates exactly what state it exposes (decision, reviewer, timestamps, comment), which lets an agent tell it apart from request_approval or get_post. It lacks an explicit verb and never names the sibling it differs from, keeping it just short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to call this versus request_approval, get_post, or validate_post, and no prerequisites stated. The agent must infer usage from the name and field list alone.

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

get_holidaysHolidays and posting guidanceA
Read-onlyIdempotent
Inspect

Holidays of every major tradition (Jewish/Israeli, Muslim, Christian, Orthodox, Druze, Bahá'í, Hindu, Buddhist, Sikh, Jain, Chinese, Persian, international and commercial days) with advice per day: avoid (no promotional posts to that audience), sensitive (respectful only), opportunity (greeting or themed post), normal. Check this before scheduling, and match the traditions to the audience of each account.

NameRequiredDescriptionDefault
toNoLast day, YYYY-MM-DD (default: from + 60 days, max 400 days)
fromNoFirst day, YYYY-MM-DD (default: today)
languageNoen
traditionsNoLimit to some traditions: jewish, muslim, christian, orthodox, druze, bahai, hindu, buddhist, sikh, jain, chinese, persian, international (array, or comma separated in a query string)

TDQS

A4.1/5.0
Behavior4/5

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

Annotations already declare readOnlyHint/idempotent/openWorld=false, so safety is covered; the description adds genuinely new behavioral meaning by defining the four advice categories and what each implies for posting (no promotional posts, respectful only, greeting allowed). It does not mention the 60-day default window, the 400-day cap, or that omitting traditions returns all of them, leaving some behavioral gaps.

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 resource scope is front-loaded in the first clause, followed by the advice taxonomy and then the actionable directive. The long parenthetical tradition list is bulky but earns its place by scoping the tool; a single wasted clause would be easy to find, but overall it is tight.

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?

With zero required params, no output schema, and mid-level schema coverage, the description carries the burden of explaining what comes back — and it does, via the per-day advice categories. It omits the default range (today to +60 days) and language behavior, but the schema covers those, so nothing critical for correct invocation 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 coverage is 75% and the schema already documents from, to, and traditions (including the enum list). The description's tradition enumeration largely restates the schema, and it adds nothing about the `language` parameter or the default date window, so it is at the baseline for a well-covered schema.

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 resource (holidays across enumerated traditions) plus a distinctive value-add: per-day posting advice classified as avoid/sensitive/opportunity/normal. An agent immediately knows what comes back and that it is not a generic calendar lookup; no sibling tool covers this territory.

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?

"Check this before scheduling" gives an explicit workflow trigger that ties this tool to schedule_post/create_post, and "match the traditions to the audience of each account" tells the agent how to parameterize by audience. It stops short of naming the specific sibling tools or stating when not to call it, so it is clear context rather than full when/when-not guidance.

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

get_postGet a postA
Read-onlyIdempotent
Inspect

Status of a post and of every account it goes to: state, dispatch and publish time, live URL or error, and once published its results (views, likes, comments, shares, saves, link clicks; null = not reported by that network) — plus the remaining validation issues while it is still a draft, and next_steps.

NameRequiredDescriptionDefault
post_idYes
workspace_idYesWorkspace id from list_workspaces

TDQS

A3.5/5.0
Behavior4/5

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

Annotations already establish that this is a safe, idempotent read operation. The description adds meaningful behavioral context beyond annotations: per-account state, dispatch and publish timing, live URL/error, null metric semantics, draft validation issues, and next_steps. It stops short of describing auth or rate-limit behavior, but with annotations present this is still strong.

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 the core purpose and packs substantial return-value detail into a single dense sentence. It avoids fluff, though the density and parenthetical metric list make it slightly harder to scan.

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?

There is no output schema, so the description carries the return-value burden and does so well by explaining statuses, metrics, errors, validation issues, and next_steps. It is less complete on parameter semantics and sibling routing, but the output-side coverage is strong.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

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

The schema documents workspace_id but not post_id, giving only 50% schema description coverage. The description does not explain either parameter's meaning or format, so it fails to compensate for the undocumented post_id.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states that this retrieves a post's status across all destination accounts, including dispatch/publish details, metrics, validation issues, and next steps. It is a specific verb+resource definition, but it does not explicitly distinguish itself from siblings like list_posts, get_analytics, or validate_post.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied: use it to inspect a specific post's status and results. However, there is no explicit guidance on when to choose this over list_posts, get_analytics, or validate_post, and no exclusions or prerequisites are stated.

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

get_structureSee the whole account: clients, accounts and groupsA
Read-onlyIdempotent
Inspect

How a Shager account is organized:

  • Organization: the whole account, with one plan and one team. Your key belongs to exactly one organization.

  • Workspaces: inside the organization. In the app a workspace is called a client when the organization is an agency (one workspace per client business) and a brand or simply "my accounts" when a person or business posts for itself (usually one workspace). Everything below lives inside one workspace and never crosses into another.

    • Channels: the connected social accounts of that workspace — one Facebook Page, one Instagram account, one YouTube channel, one X account, one LinkedIn profile or company Page, one TikTok account, one Bluesky account, one Telegram channel, one Mastodon account, one Threads profile, one Pinterest business account, one Google Business Profile location each. A channel belongs to exactly one workspace.

    • Groups: named sets of that workspace's channels (for example "Hebrew pages" or "North branches"). A channel can be in several groups or in none. Targeting a group posts to all of its ACTIVE channels.

    • Media, posts, tracked links, webhooks and the client-approval setting also belong to the workspace.

  • A post belongs to one workspace and targets channel_ids and/or group_ids from that same workspace. Call get_structure (GET /structure) to see the whole tree in one call: every workspace with its channels and groups. When you talk to the person, use their words: "client" (agency) or "your accounts" (one business), and "group".

Returns the organization, then every workspace (client or brand) with its connected channels and its groups (each group lists its channel_ids; each channel lists the groups it is in). Use it before posting to pick the right workspace, channel_ids and group_ids.

NameRequiredDescriptionDefault

No parameters

TDQS

A4/5.0
Behavior4/5

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

The annotations already declare this as a read-only, idempotent, non-destructive operation, so safety behavior is covered. The description adds useful behavioral context about the returned hierarchy and workspace isolation, though it does not discuss auth, rate limits, or pagination.

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 structured with bullets, but it is long and front-loads a domain-model explanation before stating the tool action. Much of the hierarchy detail is useful, yet the core purpose could be stated more concisely and earlier.

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?

There is no output schema, so the description carries the burden of explaining what is returned. It does so clearly: the organization, every workspace, each workspace's channels and groups, and the channel/group relationships needed for posting.

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?

The tool has zero parameters, so there is no parameter semantics for the description to clarify. The baseline for a parameterless tool is 4, and nothing in the description undermines that.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific action and resource: call get_structure to see the whole tree of workspaces, channels, and groups in one call. It implies differentiation from sibling list tools by emphasizing the whole tree in one call, but it does not explicitly name alternatives like list_workspaces or list_groups.

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 gives a clear usage context: use it before posting to pick the right workspace, channel_ids, and group_ids. It does not explicitly state when not to use it or name sibling alternatives, so the guidance is strong but not exhaustive.

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

hide_commentHide or show a commentA
DestructiveIdempotent
Inspect

Hides a comment from everyone but the account (hidden=true), or shows it again (hidden=false). Changes what the public sees: act on your human's request. YouTube, Facebook and Instagram; the account's own comments can't be hidden.

NameRequiredDescriptionDefault
hiddenNo
post_idYes
channel_idYes
comment_idYes
workspace_idYesWorkspace id from list_workspaces

TDQS

A4.1/5.0
Behavior4/5

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

Annotations already declare destructiveHint=true and idempotentHint=true, so the description earns credit for adding what those hints do not say: the change affects what the public sees, it is reversible via hidden=false, and an account's own comments cannot be hidden. It does not mention permission/scope requirements or how failures surface, which keeps it below a 5.

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?

Two compact sentences with the effect and the true/false mapping front-loaded, followed by platform scope and the one hard exclusion. The platform list is slightly compressed but nothing is wasted.

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 destructive, idempotent toggle with no output schema and 5 parameters, the description covers effect, reversibility, scope and one key constraint. The remaining gap is how the identifier parameters relate to each other (e.g. whether comment_id is scoped to post_id), which neither schema nor description resolves.

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 only 20% (just workspace_id), but the description does supply the meaning of the one truly ambiguous parameter, hidden, including its true/false direction. The identifier parameters post_id, channel_id and comment_id are left entirely to the schema, so the description does not fully compensate for the coverage gap.

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+resource and explicitly covers both directions of the toggle (hidden=true hides, hidden=false restores), plus the platform scope. An agent can distinguish this from delete_comment or reply_to_comment purely from the description.

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 a clear operating condition: 'act on your human's request', which tells the agent this is a human-initiated moderation action rather than something to do autonomously. It also names the supported platforms and the own-comment exclusion, but never points to a sibling alternative (e.g. delete_comment) for permanent removal.

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

invite_memberInvite someone to the teamA
Destructive
Inspect

Emails a person an invitation to join this organization's team as a viewer (read only), for every workspace (scope "all") or only some (workspace ids from list_workspaces). The invitation link works for 7 days; inviting an address that already has an open invitation updates and resends it. Sends email to a person, so it needs the publish scope and a key whose human manages the team. Agents can't invite editors or managers, so a misled agent can't hand someone write access: the human does that in the app (Team page). At most 30 invitation emails per organization per day. (Not available in an unclaimed sandbox.)

NameRequiredDescriptionDefault
roleNoviewer: read only. Editors and managers are invited by a person in the app.viewer
emailYes
scopeNo"all", or the workspace ids they may openall

TDQS

A4.8/5.0
Behavior5/5

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

Annotations mark this as a non-readonly, non-idempotent, open-world mutation, and the description adds consequences the annotations cannot: the invite link expires in 7 days, re-inviting an existing open invitation updates and resends it, emails go out as a side effect, and there is a hard limit of 30 invitation emails per organization per day. It also discloses the security posture (viewer-only for agents), which is exactly the context an agent needs before writing.

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?

Every sentence carries real information and the primary action plus role constraint is front-loaded. It is a dense single paragraph with stacked parentheticals (sandbox note, list_workspaces pointer), which is slightly heavier to parse than necessary but not wasteful.

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 3-parameter email-sending mutation with no output schema, the description covers side effects, expiry, resend/update behavior, rate limits, required permissions, and unavailability conditions. An agent has everything it needs to decide whether and how to call it.

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 67% and the description fills the important remaining gap by explaining that scope is either 'all' or explicit workspace ids obtained from list_workspaces, and that role is constrained to viewer. It does not add format detail for email beyond the schema, but that parameter is already well constrained.

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 ('Emails a person an invitation to join this organization's team') and pins the effect down to a viewer role, all/partial workspace scope. It is clearly distinguishable from siblings like list_members and list_workspaces, which are read-only listing tools.

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?

It states when to use it (invite a viewer), where to get scope values ('workspace ids from list_workspaces'), and explicitly says what it cannot do (agents can't invite editors/managers; the human does that in the app's Team page). Prerequisites (publish scope, a key whose human manages the team) and exclusions (unclaimed sandbox) are spelled out.

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

list_auto_repliesList auto-repliesA
Read-onlyIdempotent
Inspect

The workspace's automatic-reply rules, oldest first — the first enabled rule that matches a comment or direct message answers it — each with its last-30-days numbers, plus what every account can do: comments (public replies, a private message to the commenter) and direct messages. Instagram: comments and private replies work; answering direct messages needs a reconnect after Shager added the messages permission. Facebook Pages: comments, public replies and private replies work (comments are read every 5 minutes until Meta delivers them instantly); Messenger messages are answered once Meta delivers them to Shager (after Meta's app review). YouTube and LinkedIn company Pages: public replies to comments only (no private messages; LinkedIn has no messaging API for Pages, and Page comments are checked every 2 hours). X: public replies and DMs, billed to the workspace's monthly X limit. LinkedIn profiles and TikTok: not available.

NameRequiredDescriptionDefault
workspace_idYesWorkspace id from list_workspaces

TDQS

A3.6/5.0
Behavior4/5

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

Annotations already cover the read-only/idempotent/non-destructive profile, and the description adds genuine behavior beyond them: deterministic ordering, the first-enabled-match rule semantics, a 30-day metric window, and channel-specific caveats (Instagram DM reconnect, Facebook 5-minute comment polling, LinkedIn 2-hour polling, X billing to the monthly limit). The gaps are pagination/result-size behavior and whether disabled rules are included — neither is stated.

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 purpose is correctly front-loaded in the first clause, but the bulk of the text is a channel-by-channel capability matrix whose details (polling intervals, Meta app review, availability of TikTok) are tangential to invoking a list tool. It is informative but heavily weighted toward background rather than what an agent needs for this specific call.

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 read-only single-parameter list with a fully documented schema and no output schema, the definition is more than sufficient — it explains what each rule looks like and why a given channel might be absent. Minor omissions are whether disabled rules are returned and any result-size limits.

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?

Only workspace_id exists and the schema documents it fully at 100% coverage ('Workspace id from list_workspaces'), so the baseline is 3. The description adds nothing about the parameter — it only refers to 'the workspace's' rules — which is acceptable given the schema but leaves no extra value.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening clause names the resource precisely ('the workspace's automatic-reply rules') and specifies ordering ('oldest first') plus the returned payload (last-30-days numbers). That is enough to separate it from create_auto_reply/delete_auto_reply, but it never explicitly contrasts with the closest sibling list_auto_reply_activity, leaving the agent to infer that this returns rule definitions rather than rule firings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied: the ordering and 'first enabled rule that matches' explanation tell the agent what the data means, but nothing says when to call this versus list_auto_reply_activity, update_auto_reply, or get_analytics. The long per-channel support matrix helps judge whether a workspace can even have rules on a channel, but that is contextual background, not selection guidance.

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

list_auto_reply_activityAuto-reply activityA
Read-onlyIdempotent
Inspect

The latest comments and direct messages that reached the workspace's auto-replies, newest first: who wrote what, which rule answered, the public reply and private message sent, or why nothing was sent (status SENT, SKIPPED, FAILED or PENDING). Comments no rule was meant for are left out. Kept 90 days.

NameRequiredDescriptionDefault
limitNo
statusNo
rule_idNoOnly this rule's activity
workspace_idYesWorkspace id from list_workspaces

TDQS

A3.7/5.0
Behavior4/5

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

Annotations already declare readOnly, idempotent and non-destructive, so the safety profile is covered. The description adds genuinely useful behavior beyond that: newest-first ordering, a 90-day retention window, and the SENT/SKIPPED/FAILED/PENDING outcome vocabulary. It does not mention pagination limits that bound how much history can be pulled per call.

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?

A single dense sentence that front-loads the resource and then unpacks the payload fields, then closes with the exclusion rule and retention window. Every clause carries information; it is long but not padded.

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?

With no output schema, the description does the work of explaining what a record contains and why some records are absent, which is the right burden for a read-only list tool. The remaining gap is guidance on the two undocumented filter parameters (status, limit).

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 coverage is 50%: workspace_id and rule_id are documented in the schema, while limit and status are not. The description gives the status values meaning in the return payload but does not clarify that status acts as a filter on results, and says nothing about the limit parameter. It partially compensates but not fully.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names the specific resource (comments and DMs that reached the workspace's auto-replies) and enumerates what each record contains: author, triggering rule, public reply, private message, and outcome status. It implicitly separates this activity log from the rules-listing sibling list_auto_replies, though it never names that sibling explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Inclusion/exclusion scope is stated ('Comments no rule was meant for are left out'), which implies this is a debugging/audit view of auto-reply outcomes. However, there is no explicit guidance on when to reach for this versus list_auto_replies or list_comments, and no hint that the status parameter can be used to isolate failures.

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

list_channelsList connected accountsA
Read-onlyIdempotent
Inspect

The connected social accounts (channels) of one workspace (client or brand). A channel is one social destination: a Facebook Page, an Instagram professional account, a YouTube channel, an X account, a LinkedIn profile, a LinkedIn company Page (account_kind "company"), a TikTok account, a Bluesky account, a Telegram channel, a Mastodon account (handle @name@server), a Threads profile, a Pinterest business account or a Google Business Profile location (account_kind "location"; each location is its own channel). Only status ACTIVE accounts can receive posts; NEEDS_RECONNECT means the human must reconnect it. Each row tells you the network's rules: formats, caption_limit, whether a first_comment exists (per account: LinkedIn company Pages yes, LinkedIn profiles no), whether links in the caption are clickable, requires_media, and paid_links (X: every post comes from the monthly allowance in x_posts_this_month, and a post with a link also from x_link_posts_this_month). TikTok rows carry tiktok.privacy_options — the only values allowed in per_channel.tiktok_privacy — or null with a note when TikTok could not be asked. Pinterest rows carry pinterest.boards ({id, name, privacy}) — per_channel.pinterest_board_id must be one of them — or null with a note (pinterest.reason "business": Pinterest refuses a non-business account's boards to apps, so the human must switch it to a business account and reconnect). Live: YouTube channels, X (Twitter) accounts, LinkedIn personal profiles, Bluesky accounts, Telegram channels and Mastodon accounts. Facebook: Awaiting Meta's approval: until then, only people we gave early access can connect. Pages only: Facebook lets no app publish to personal profiles. Posts, photos, video, Reels and Stories, with your own cover image for videos. First comment with a clickable link. Instagram: Awaiting Meta's approval: until then, only people we gave early access can connect. Connected directly with Instagram Login or through a Facebook Page. Your own cover image for Reels. Links in captions and comments aren't clickable on Instagram: the tracked link goes in the first comment as text, and a clickable link can only go in the profile. TikTok: Pending TikTok's app review: until approved, posts can only go to private accounts and are published as private ("only me"). Privacy, interactions and commercial-content disclosure are chosen per post. TikTok takes no cover image and applies a chosen cover moment to public posts only, so Shager can put your cover image at the start of the video. Threads: Awaiting Meta's approval: until then, only people we gave early access can connect. Up to 500 characters (an emoji counts as several). Text, up to 20 images and videos in one carousel, or a video up to 5 minutes. Text posts can carry a link card, and any post can get a topic and a choice of who can reply. The first comment is posted as a reply, and replies, views and likes show up in Shager. You sign in on Threads' own screen and never give us your password. Pinterest: Awaiting Pinterest's approval: until then, only people we gave early access can connect. Business accounts only (switching is free on Pinterest). Each Pin is an image, a carousel of up to 5 images or a video, with a title, a description up to 800 characters and a link, on a board you pick for each account. No first comment, and comments can't be read through Shager. Impressions, saves and comments per Pin show up in Shager. You sign in on Pinterest's own screen and never give us your password. Google Business Profile: Awaiting Google's approval: until then, only people we gave early access can connect. Each location is its own profile, and you choose which locations to connect. A post is an update, an event or an offer, with up to 1,500 characters, one photo and a button such as Book, Order or Learn more. No video and no first comment. Reviews can be read and answered in Shager, by hand only, when you decide. Profile views, calls, website clicks and direction requests show up in Shager. You sign in on Google's own screen and never give us your password.

NameRequiredDescriptionDefault
networkNoOnly accounts on this network.
workspace_idYesWorkspace id from list_workspaces

Output Schema

NameRequiredDescription
itemsYes
next_cursorYes

TDQS

A3.7/5.0
Behavior5/5

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

Annotations already declare readOnly/idempotent/non-destructive, yet the description adds substantial context beyond them: account status meanings, per-network approval gating, which networks are live vs awaiting approval, requires_media, caption limits, and fields like x_posts_this_month and tiktok.privacy_options. This is rich behavioral disclosure an agent could not get from 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.

Conciseness2/5

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

After a useful opening sentence, the description becomes a wall of per-network publishing rules (cover images, character limits, link clickability, approval statuses) that are largely irrelevant to invoking a list operation. The essential invocation information is buried and the structure is not front-loaded toward what an agent needs to call the tool.

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?

Given an output schema exists, return values needn't be explained, and the description errs on the side of over-supplying context. It is more than complete for calling the tool, though much of the detail pertains to downstream publishing rather than this list operation.

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 coverage is 100% with the single enum (network) documented inline, so the schema already carries parameter meaning. The description adds no syntax or filtering detail beyond what the schema states, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening sentence states a specific verb and resource (connected social accounts/channels of one workspace) and thoroughly defines what a channel is, including account_kind variants. It is clear enough to distinguish from most siblings, though it never explicitly contrasts with list_workspaces or get_structure, which also surface account/structure data.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied: status semantics (ACTIVE can receive posts, NEEDS_RECONNECT requires human action) and per-network rules hint that this tool is the prerequisite for posting, but there is no explicit 'use this when…' or 'use X instead' routing. The agent must infer its role in the workflow.

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

list_commentsComments on a published postAInspect

Reads the comments (newest first, each with its replies) on a post Shager published, on one account. YouTube, Facebook Pages, Instagram and X (X: replies from the last 7 days, up to 20, and every read and reply is billed to the workspace's monthly X limit); LinkedIn company Pages (reply as the Page, delete the Page's own comments; no hiding, and commenters come without names); Bluesky (replies two levels deep, answer them, delete the account's own; no hiding); Mastodon (replies, including followers-only ones the account can see, answer them with the same visibility, delete the account's own; no hiding); a Facebook Page connected before Shager asked for its comment permissions needs a reconnect; LinkedIn profiles and TikTok don't let apps manage comments; Telegram channel comments aren't offered yet. Read live from the network, never stored. Use it to answer questions, spot spam, or draft replies for a human to approve.

NameRequiredDescriptionDefault
post_idYes
channel_idYesThe account the post went to (destinations[].channel_id in get_post)
workspace_idYesWorkspace id from list_workspaces

TDQS

A4.2/5.0
Behavior5/5

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

Beyond the annotations, the description discloses platform-specific behavior, billing implications on X, reconnect requirements for older Facebook Pages, no-hiding constraints, LinkedIn name omissions, and that comments are read live and never stored. This is unusually rich behavioral context for an agent.

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 purpose is front-loaded, but the description is a very long, dense sentence with many semicolon-separated platform caveats. Most details are useful, though some reply/delete/hiding capability notes may exceed the scope of a list_comments tool.

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 multi-platform comment-reading tool, the description covers ordering, replies, billing, reconnects, and platform limitations well. Without an output schema, it could say more about the returned comment structure, but it is largely complete.

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 coverage is 67%, and the schema already explains channel_id and workspace_id. The description implies the post and account scope but does not add parameter syntax or mapping beyond what the schema provides, so the baseline of 3 is appropriate.

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 immediately states a specific verb and resource: it reads comments on a published post, for one account, newest first with replies. That is enough for an agent to distinguish it from reply_to_comment, delete_comment, and hide_comment.

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 gives concrete usage scenarios—answering questions, spotting spam, drafting replies for human approval—and details platform-specific conditions and limitations. It does not explicitly name sibling alternatives, so it falls short of the top guideline score.

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

list_groupsList account groupsB
Read-onlyIdempotent
Inspect

Groups of one workspace: named sets of its channels (by region, language, branch, campaign…). A channel can be in several groups or none, and a group never includes another workspace's channels. Target a group in create_post with group_ids to post to all its ACTIVE channels.

NameRequiredDescriptionDefault
workspace_idYesWorkspace id from list_workspaces

Output Schema

NameRequiredDescription
itemsYes
next_cursorYes

TDQS

B3.4/5.0
Behavior4/5

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

Annotations already establish readOnly/idempotent/non-destructive, so the safety profile is covered. The description adds context the annotations cannot: channels may belong to several groups or none, groups never cross workspace boundaries, and posting via group_ids only hits ACTIVE channels. That last detail is a real behavioral caveat an agent would otherwise get wrong.

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?

Two tight sentences with no filler, and each clause carries information (membership rules, workspace isolation, downstream use). The one structural weakness is that it leads with a definition of the object rather than with what the call does, so the agent reads a glossary entry before learning the action.

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?

With an output schema present, return shape need not be explained, and the description covers the semantics an agent actually needs: intra-workspace scope, multi-membership, and ACTIVE-only posting. For a one-parameter read tool this is close to sufficient; only an explicit statement of what the call returns 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?

There is a single parameter and the schema documents it fully (100% coverage, "Workspace id from list_workspaces"), so the schema is doing all the work. The description says "Groups of one workspace" but adds nothing about the parameter itself — no format, no source, no scoping caveat beyond what the schema states. Baseline 3 for high schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description defines the resource precisely ("named sets of its channels", scoped to one workspace) but never states the tool's own action — it never says it returns/lists the groups of a workspace. The verb lives only in the name and title, so an agent must infer that this is a read-list call rather than, say, a lookup of group metadata. Useful conceptual framing, but the purpose statement itself is implied rather than asserted.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The closing clause routes the agent forward — "Target a group in create_post with group_ids" — which is a genuine usage hint about what the output is for. However, there is no guidance on when to choose this over list_channels or get_structure, and no statement of the prerequisite that workspace_id must come from list_workspaces (that lives only in the schema).

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

list_membersList team membersB
Read-onlyIdempotent
Inspect

The people on this organization's team and the invitations still waiting for an answer. role: manager (everything; with scope "all" also the team and plan), editor (writes and schedules posts, answers comments; doesn't connect accounts or change settings) or viewer (read only). scope: "all" (every workspace, including ones added later) or the workspace ids they can open. owner: the team's owner, whose role never changes.

NameRequiredDescriptionDefault

No parameters

TDQS

B3/5.0
Behavior3/5

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

Annotations already establish that this is a safe, read-only, idempotent, closed-world operation. The description adds useful context that pending invitations are included and defines role/scope/owner semantics, but it omits behavior such as ordering, pagination, or what member fields are returned.

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 compact and avoids filler, but it opens with a noun phrase instead of a clear action statement and reads as a fragment. The role and scope definitions are useful but could be structured more clearly for fast scanning.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema and no input parameters, the description carries some burden for explaining return content. It covers role, scope, owner, and pending invitations, but does not describe the shape of member records or invitation details, leaving meaningful gaps.

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?

There are zero input parameters, so the baseline is 4. The description's role/scope/owner text describes return-value semantics rather than input parameters, which is appropriate given the empty schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names the resource—people on the team and pending invitations—but never uses an explicit action verb such as 'list' or 'return'. It is understandable from the title and content, but it does not sharply distinguish itself from siblings like invite_member or whoami.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no when-to-use guidance, no alternatives, and no exclusions. The role and scope text explains return-field meanings, not when an agent should call this tool instead of another sibling.

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

list_notificationsList notificationsA
Read-onlyIdempotent
Inspect

What happened lately that the humans were told about (in the app and by email): posts that failed (fully or on some accounts, or only their first comment), accounts that need reconnecting, the X monthly limit reached, auto-reply rules failing repeatedly, accounts a client connected through a connect link, approvals given or changes requested, and team members who joined. Newest first. Each item has a type, an English title and text, the facts in payload, and the app link. Useful to check on posts after scheduling them, or to tell the human what needs them.

NameRequiredDescriptionDefault
typeNoOnly this kind
limitNoDefault 30
sinceNoOnly notifications after this time (ISO datetime)
workspace_idNoOnly this workspace (from list_workspaces)

Output Schema

NameRequiredDescription
itemsYes
next_cursorYes

TDQS

A3.9/5.0
Behavior4/5

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

Annotations already cover the safety profile (readOnly, idempotent, non-destructive, closed-world), so the description is freed to add non-structured behavior: results are ordered newest first and each item carries a type, an English title/text, a `payload` of facts, and an app link. That ordering and item-shape disclosure is genuinely useful beyond 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 purpose and the newest-first ordering are front-loaded, and the trailing sentence about usage is short and earns its place. The long middle enumeration is dense but justified, since it translates terse enum codes like 'x_limit' into plain-English meanings the agent can match against a user request.

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?

With an output schema present and a fully documented schema plus rich annotations, the description need only cover purpose, when-to-use, and ordering/shape, all of which it does. Nothing an agent needs in order 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.

Parameters3/5

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

Schema description coverage is 100% and all four parameters (type, limit, since, workspace_id) are documented in the schema, including the enum values and the default of 30. The description adds nothing about filtering semantics, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description concretely states what the tool returns: a newest-first feed of human-facing notifications, enumerated by category (post failures, reconnect needs, X limit, rule failures, client connections, approvals, member joins). That enumeration makes it unmistakably distinct from list_posts, list_comments, or get_analytics. The only shortfall is that the verb is implicit ('What happened lately...') rather than an explicit 'Lists'.

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 gives concrete usage contexts: 'check on posts after scheduling them' and 'tell the human what needs them', which tells the agent when this tool is the right retrieval. It does not name an alternative or state when not to use it, so it stops short of the top of the scale.

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

list_postsList postsA
Read-onlyIdempotent
Inspect

Posts in a workspace, newest first, with cursor pagination: pass next_cursor as cursor. Filters combine: status, network, channel_id (one account), group_id (posts to any account in that group), query (words in the caption or internal label), and from/to on the scheduled time. Date-only from/to filters use inclusive UTC days, not workspace-local days. Offset timestamps filter exact instants. Posts without a date (unscheduled drafts) only appear without from/to.

NameRequiredDescriptionDefault
toNoOnly posts scheduled at or before this date (inclusive) or instant.
fromNoOnly posts scheduled at or after this date (2026-10-01) or instant.
limitNo
queryNoWords to find in the caption or the internal label (case-insensitive).
cursorNonext_cursor from the previous page.
statusNo
networkNoOnly posts going to at least one account on this network.
group_idNoOnly posts going to at least one account in this group (from list_groups).
channel_idNoOnly posts going to this account (from list_channels).
workspace_idYesWorkspace id from list_workspaces

Output Schema

NameRequiredDescription
itemsYes
next_cursorYes

TDQS

A4.4/5.0
Behavior5/5

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

Annotations already declare readOnly/idempotent, so the description is free to disclose the behavior that matters: result ordering (newest first), the pagination contract ('pass next_cursor as cursor'), how from/to filter semantics differ by input type, and the filter-combination rule. These are behavioral facts the agent cannot infer from the schema or annotations.

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?

Three dense sentences with zero filler; the retrieval shape and pagination come first, then filters, then the caveat about undated drafts. Each clause carries information an agent needs to call the tool correctly.

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?

With 10 parameters, an output schema, and strong annotations, the description covers the pieces that structured fields cannot: ordering, pagination loop, filter conjunction, and the undated-drafts edge case. Nothing needed 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.

Parameters4/5

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

Schema coverage is 80%, so the baseline is 3, but the description adds genuine meaning: channel_id targets one account while group_id targets any account in a group, query searches caption or internal label, and date-only vs offset timestamps filter different units. The inclusive-UTC-day rule is stated only in the description, not the schema, making it a load-bearing addition.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb+resource+scope ('Posts in a workspace, newest first, with cursor pagination'), so the agent knows exactly what it retrieves and in what order. It does not explicitly differentiate from siblings such as get_post or list_channels, leaving the single-vs-many distinction implicit.

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?

States that filters combine and gives a concrete usage rule for the edge case: 'Posts without a date (unscheduled drafts) only appear without from/to.' That is real when-to-use guidance. It stops short of naming alternatives (e.g. get_post for a single record) or exclusion conditions beyond the draft case.

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

list_webhooksList webhook endpointsB
Read-onlyIdempotent
Inspect

The workspace's webhook endpoints: URL, events, whether it is on (and why it was turned off), the secret's last 4 characters, and the last delivery attempt (time, event type, HTTP status, error).

NameRequiredDescriptionDefault
workspace_idYesWorkspace id from list_workspaces

Output Schema

NameRequiredDescription
itemsYes
next_cursorYes

TDQS

B3.2/5.0
Behavior3/5

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

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds useful context about what is surfaced — the enabled/disabled state with the reason, the masked secret suffix, and last delivery outcome — but says nothing about pagination, result limits, or whether listing requires elevated permissions.

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?

A single dense sentence with zero filler, front-loaded on the resource. It is a sentence fragment without a leading verb, which slightly weakens orientation but wastes no words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so the return-value enumeration in the description is largely redundant and the description need not explain the payload shape. What remains missing is operational context: result size/pagination, permission requirements, and behavior when the workspace has no webhooks.

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?

Only one parameter (workspace_id) and schema description coverage is 100%, with the schema itself pointing to list_workspaces for the value. The description adds no additional semantics about the identifier, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names the specific resource (the workspace's webhook endpoints) and enumerates exactly which fields come back, so an agent knows it is a read/list of webhooks. It lacks an explicit verb and does not distinguish itself from create_webhook, delete_webhook, or send_test_webhook, leaving differentiation to the tool name and title.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no when-to-use guidance, no prerequisites (e.g. workspace membership or admin rights), and no mention of the sibling alternatives such as send_test_webhook or delete_webhook. Usage is only inferable from the resource name.

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

list_workspacesList workspacesA
Read-onlyIdempotent
Inspect

A workspace is what the app calls a client (for an agency) or a brand (for a person or business posting for itself; usually just one). Its connected accounts (channels), groups, media, posts and tracked links live in it and never cross into another workspace. approval_required means a client reviewer must approve each post before it can be scheduled (request_approval). For every workspace with its channels and groups in one call, use get_structure.

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription
itemsYes
next_cursorYes

TDQS

A4/5.0
Behavior4/5

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

Annotations already cover readOnly, idempotent and non-destructive, so the bar is lower; the description still adds real behavioral context by declaring the data-isolation boundary ('never cross into another workspace') and explaining what approval_required means operationally. It does not mention result volume, ordering, or pagination, but the presence of an output schema covers return shape.

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?

Three dense sentences with no filler, and the sibling-routing rule is stated up front in the final sentence position. Slight weakness: it leads with a glossary definition of 'workspace' rather than front-loading what the call returns, which delays the actionable 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 zero-param, read-only, idempotent list tool with full annotations and an output schema, the description supplies the domain vocabulary and the routing to get_structure that an agent needs. It stops short of stating scope explicitly (e.g. all workspaces the caller can access), but nothing essential is missing.

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?

Zero parameters, so the baseline is 4. The description goes slightly beyond by explaining the semantics of a response field (approval_required) that drives the request_approval workflow, though the output schema already documents return fields.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description never states the action in a verb+object sentence, but it does define the resource precisely ('A workspace is what the app calls a client ... or a brand') and implies the listing scope by contrasting with get_structure. Sibling differentiation against get_structure is explicit.

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 gives a concrete routing rule: use get_structure when you need every workspace with its channels and groups in one call, implying this tool is for the lighter workspace-level listing. It also explains that approval_required implies the request_approval flow. No explicit when-not, but the alternative is named clearly.

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

reply_to_commentReply to a commentA
Destructive
Inspect

Publishes a reply, as the account, to a comment on a post Shager published (YouTube, Facebook, Instagram, X or a LinkedIn company Page). It is public at once and can't be unsent here: send only a text your human approved. Up to 2,200 characters. (Not available in an unclaimed sandbox.)

NameRequiredDescriptionDefault
textYes
post_idYes
channel_idYes
comment_idYes
workspace_idYesWorkspace id from list_workspaces

TDQS

A4.2/5.0
Behavior5/5

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

Annotations already mark this as non-read-only, open-world, non-idempotent, and destructive. The description adds concrete behavioral context beyond those hints: the reply is public at once, cannot be unsent here, requires human-approved text, is capped at 2,200 characters, and is unavailable in an unclaimed sandbox. These details align with the destructive/non-idempotent annotations rather than contradicting them.

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?

The description is front-loaded with the action and resource, then adds the most important constraints without padding. Every sentence contributes either platform scope, safety guidance, length limit, or sandbox availability.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

It covers the main behavioral risks for this mutation: immediacy, irreversibility, approval requirements, platform scope, length limit, and sandbox restriction. However, with four of five parameters lacking schema descriptions and no output schema, it still leaves ID provenance and failure behavior unaddressed.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

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

Schema description coverage is only 20%, with only workspace_id documented as coming from list_workspaces. The description repeats the 2,200-character limit for text and implies the reply relates to a post and comment, but it does not explain how to obtain or format post_id, channel_id, or comment_id, leaving most required parameters semantically thin.

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 gives a specific verb and resource: 'Publishes a reply ... to a comment on a post Shager published,' and it names the supported platforms. That is enough to distinguish it from siblings such as delete_comment, hide_comment, list_comments, and create_auto_reply without opening another schema.

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 clearly states relevant usage conditions: the reply is public immediately, cannot be unsent here, must use human-approved text, and is unavailable in an unclaimed sandbox. It does not explicitly compare itself with alternatives like create_auto_reply or hide_comment, so it stops short of full when-to-use guidance.

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

request_approvalSend a post for client approvalA
Destructive
Inspect

The approval flow: a client reviewer (not a Shager user) gets a link, opens it on their phone without logging in, sees the post per account and approves, asks for changes (with a comment) or rejects. The post moves to IN_REVIEW; get_approval shows the decision; an APPROVED post can be scheduled as long as its content is unchanged. Returns the link to send (and a WhatsApp link when the reviewer has a phone); send_email emails it. When the workspace has approval_required, Shager emails the link to the reviewer itself (reviewer_email and send_email: true are required) and the link is not returned, so the agent can't approve its own post. Useful anyway when a human should look first. (Not available in an unclaimed sandbox.)

NameRequiredDescriptionDefault
post_idYes
send_emailNo
workspace_idYesWorkspace id from list_workspaces
reviewer_nameYes
reviewer_emailNo
reviewer_phoneNo
idempotency_keyNoAny unique string you choose (REST: the Idempotency-Key header works too). Retrying with the same key and body returns the first result instead of creating a second one. Kept 24 hours.

TDQS

A4.8/5.0
Behavior5/5

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

Goes well beyond the annotations: the post moves to IN_REVIEW, an APPROVED post can be scheduled only if content is unchanged, emails may be sent on the agent's behalf, and in approval_required workspaces the link is not returned so the agent can't self-approve. This is exactly the side-effect disclosure a destructive, open-world mutation needs.

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 core flow in the first sentence and keeps every subsequent sentence informative (side effects, return value, sandbox restriction). It is a dense single paragraph, so the conditional approval_required branch is slightly buried, but there is no filler.

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?

With no output schema, the description still explains the return value (the link, plus a WhatsApp link) and the exception case where no link is returned. Combined with the disclosed side effects and sandbox restriction, an agent has everything needed to call it correctly.

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 low (29%) and the description compensates for several gaps: it explains that reviewer_email and send_email: true become required when the workspace has approval_required, and that a phone yields a WhatsApp link. It still doesn't clarify send_email's default or the reviewer_phone/reviewer_name semantics, but the conditional requirements are the highest-value information.

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 (send a post for client approval), then details the full reviewer flow: link opened without login, per-account view, approve/request-changes/reject. It distinguishes itself from siblings by naming get_approval as the tool that shows the decision and by explaining how send_email interacts here.

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 says when to use it ('useful anyway when a human should look first'), what the alternative is ('send_email emails it'), and when it is unavailable ('Not available in an unclaimed sandbox'). It also states the special approval_required workspace path that changes required parameters and withholds the link.

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

schedule_postSchedule a postA
Destructive
Inspect

Give an existing draft (or approved post) a time. The post is validated for every account (all issues at once), checked against the key's caps and the X link allowance, and — when the workspace requires approval — must be APPROVED with unchanged content. schedule_at is ISO 8601 with an offset; the workspace timezone is used for display. Each account then publishes at its own staggered time (stagger_min/max_seconds on the post), plus its per_channel.delay_minutes when the post gives a network a later time. More than 10 accounts or a start within 60 minutes needs confirmation_token from the returned plan: without it you get needs_confirmation and details.plan (accounts by network, first and estimated last dispatch, X link-post cost, TikTok notes) to show your human. The post then goes out publicly on the person's real accounts: only schedule when your human asked to publish it. Scheduling needs the publish scope and a claimed sandbox. To move a scheduled post, call schedule_post again with the new time; cancel_post stops it.

NameRequiredDescriptionDefault
confirmNoDeprecated boolean; does not bypass confirmation. A confirmation_token is required when a schedule goes to more than 10 accounts, starts within 60 minutes, or includes a Pinterest account. Without it you get needs_confirmation with the dispatch plan; show it to your human, then resend with confirmation_token from the returned plan.
post_idYes
schedule_atYes
workspace_idYesWorkspace id from list_workspaces
idempotency_keyNoAny unique string you choose (REST: the Idempotency-Key header works too). Retrying with the same key and body returns the first result instead of creating a second one. Kept 24 hours.
confirmation_tokenNoToken returned by needs_confirmation or validate_post for this exact plan; expires after 15 minutes.

TDQS

A4.8/5.0
Behavior5/5

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

Well beyond annotations, it discloses that the post publishes publicly on real accounts, that validation runs across all accounts at once, approval requirements, per-account staggering and per_channel.delay_minutes, and the confirmation_token gate for >10 accounts / <60 min. This is exactly the consequence/side-effect context destructiveHint implies but cannot articulate.

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-loaded with the core action and scope, then consequences and the confirmation path. It is dense and a couple of sentences pack multiple facts, but nearly every clause carries actionable information; only minor tightening would help.

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?

With no output schema, the description still explains the needs_confirmation return and the contents of details.plan (accounts by network, first/estimated last dispatch, X link cost, TikTok notes), so the agent knows what comes back and how to proceed. Nothing essential for correct invocation is missing.

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 67%, and the description adds real meaning: schedule_at is ISO 8601 with offset and displayed in workspace timezone, and confirmation_token must come from the returned plan. The deprecated confirm flag is only explained in the schema, leaving one gap where description and schema diverge.

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 (give an existing draft/approved post a time) and clearly separates it from create_post, update_post, and cancel_post by describing the exact operation. The final sentence maps the move vs. cancel distinction explicitly, so the agent can pick the right sibling without opening schemas.

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?

Explicit when-to-use ('only schedule when your human asked to publish it'), when-not (drafts that aren't human-approved), and alternatives ('To move a scheduled post, call schedule_post again...; cancel_post stops it'). It also states prerequisites (publish scope, claimed sandbox) needed before calling.

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

send_test_webhookSend a test webhook eventAInspect

Sends a signed webhook.test event to the endpoint now and returns what happened (delivered, HTTP status, error, time taken). Tried once, no retries. A turned-off endpoint that answers 2xx is turned back on. (Not available in an unclaimed sandbox.)

NameRequiredDescriptionDefault
webhook_idYes
workspace_idYesWorkspace id from list_workspaces

TDQS

A4.3/5.0
Behavior5/5

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

Adds substantial behavior beyond the annotations: the event is signed, it is tried exactly once with no retries (reinforcing the non-idempotent hint), it returns delivery outcome, HTTP status, error and elapsed time, and it silently re-enables a disabled endpoint that answers 2xx. That last side effect is exactly the kind of detail annotations cannot convey.

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?

Three tight sentences, front-loaded with the action and result, followed by the retry policy, the side effect, and the precondition. Every clause carries 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?

With no output schema, the description usefully enumerates what comes back, and it covers side effects and availability constraints for a simple 2-parameter tool. The only gap is the undocumented webhook_id parameter.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

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

Schema coverage is only 50% and the description says nothing about either parameter. workspace_id is documented in-schema, but webhook_id has no description anywhere, so the agent gets no help on what a valid webhook_id is or where to obtain one.

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 ('sends a signed webhook.test event to the endpoint') and makes clear this is the test path rather than create_webhook/list_webhooks. An agent can distinguish it from every sibling webhook tool without opening the schema.

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?

The word 'now' plus 'Not available in an unclaimed sandbox' tells the agent this is an immediate, live-fire test with a stated precondition. It lacks an explicit pointer to alternatives (e.g. create_webhook for setting one up), but the context is clear enough to select it correctly.

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

set_x_budgetSet the monthly X spending limitA
DestructiveIdempotent
Inspect

X bills Shager for every read, reply and DM. This sets the most, in US dollars, that this workspace may use on X per calendar month (UTC) for comments and auto-replies; 0 turns X comments and auto-replies off. Default 5. Confirm the amount with your human. (Not available in an unclaimed sandbox.)

NameRequiredDescriptionDefault
workspace_idYesWorkspace id from list_workspaces
monthly_limit_usdYesUS dollars per month, e.g. 5

TDQS

A4.6/5.0
Behavior5/5

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

Annotations only flag destructive/idempotent/not-readOnly; the description goes well beyond them by disclosing the billing model that motivates the setting, the exact scope affected (comments and auto-replies), the meaning of the zero value (feature shutdown, which explains the destructive hint), the default of 5, the human-confirmation requirement, and the unclaimed-sandbox restriction. This is precisely the added context the annotations cannot carry.

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?

Four compact sentences that front-load the billing rationale before the operational detail, with no filler. Slightly dense in the first two sentences, but every clause carries information an agent needs before calling a spend-affecting tool.

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?

Both required parameters are fully documented in the schema and reinforced in prose, annotations carry the safety profile, and no output schema exists to explain. The description closes the remaining gaps an agent would otherwise hit: cost implications, the zero-value behavior, the confirmation requirement, and the sandbox availability limit.

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 100%, so the baseline is 3, but the description adds real meaning: the limit is in US dollars, applies per calendar month in UTC, and a value of 0 has the special semantics of disabling X comments and auto-replies. It also frames monthly_limit_usd's default as 5, which the schema does not state.

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: sets the maximum monthly USD spend for this workspace on X, scoped explicitly to comments and auto-replies. The cost model sentence (X bills per read, reply and DM) plus the '0 turns X comments and auto-replies off' clause makes the tool's effect unmistakable and distinguishes it from every sibling, none of which touch spend.

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 operational guidance: 'Confirm the amount with your human' establishes an approval precondition, the default of 5 gives a fallback, and '(Not available in an unclaimed sandbox.)' names an environment where the call will fail. It stops short of naming an alternative tool or explicitly stating when not to use it, which is why it isn't a 5.

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

update_auto_replyChange an auto-replyA
DestructiveIdempotent
Inspect

Changes a rule: send only the fields to change (enabled=false pauses it). The same rules as create_auto_reply apply. (Not available in an unclaimed sandbox.)

NameRequiredDescriptionDefault
nameNoA short name the person will recognize, e.g. "Link in DM"
enabledNo
messageNoThe private message (to the commenter, or the answer to a direct message)
rule_idYes
triggerNoCOMMENT: someone comments on a post. MESSAGE: someone sends a direct message
keywordsNoWhole words or phrases, any case; empty = every comment or message
link_urlNoAdded at the end of the private message as a tracked short link
post_idsNoCOMMENT only: only comments on these Shager posts; empty = every post
channel_idsNoOnly these accounts; empty = every account that supports the trigger
workspace_idYesWorkspace id from list_workspaces
public_repliesNoCOMMENT only: public answers under the comment, one picked at random
once_per_personNoAnswer each person once per rule (30 days)

TDQS

A4/5.0
Behavior4/5

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

Annotations already declare destructiveHint=true, idempotentHint=true and readOnlyHint=false; the description adds real value beyond that by disclosing PATCH semantics, the pause-via-enabled=false behavior, inheritance of create rules, and an environment restriction. It does not spell out why the operation is flagged destructive, but nothing contradicts the hints.

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?

Three short sentences, zero filler, with the most decision-relevant fact (send only the fields to change) front-loaded. The parenthetical environment caveat is placed last where it belongs.

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 12-parameter mutation with no output schema, the description does most of the work by offloading field validation to create_auto_reply and explaining the patch contract. The remaining gap is that it never says where rule_id comes from (list_auto_replies) and does not indicate what the call returns.

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 coverage is 83%, so the schema already documents nearly all 12 parameters. The description adds the meaningful partial-update convention and the semantics of enabled=false, but says nothing about the undocumented rule_id or about omitting versus nulling fields (message and link_url accept null). Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Changes a rule') and immediately clarifies that it is a partial-update operation ('send only the fields to change'). A reader can distinguish it from create_auto_reply and delete_auto_reply, though the term 'rule' rather than 'auto-reply' requires the title/sibling list to disambiguate.

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 concrete usage conditions: send only changed fields, enabled=false pauses rather than deletes, and the create_auto_reply field rules carry over. It also flags an exclusion ('Not available in an unclaimed sandbox'). It does not explicitly route to delete_auto_reply when removal is intended, but the pause-versus-delete hint covers the main confusion.

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

update_postUpdate a draftA
DestructiveIdempotent
Inspect

Change any field of a post that is not scheduled or published (DRAFT, IN_REVIEW, CHANGES_REQUESTED, APPROVED). Send only the fields to change; channel_ids/group_ids replace the account list, per_channel entries are merged field by field into each named account's overrides, media_ids replace the media. Use null to clear cta_url, cta_text, first_comment, label, campaign, cover_media_id, tiktok_cover_ms, cover_first_frame, or a per_channel caption/first_comment override; an empty first_comment suppresses inheritance for that account. Changing content after a client approval sends the post back to DRAFT (approve again). A SCHEDULED post must be cancel_post-ed first. The response lists the remaining issues.

NameRequiredDescriptionDefault
pollNoA poll on X, LinkedIn and Mastodon. A poll post carries no media.
labelNoInternal name for the post (never published).
formatNoFormat for every account. Default per network: Facebook/Instagram FEED (REEL with a video), YouTube SHORT, TikTok VIDEO, LinkedIn FEED (VIDEO with a video), X FEED. Unsupported on a network = an issue, not a silent change.
captionNoMaster text. Goes to every account unless per_channel overrides it. X: 280 characters; Bluesky: 300; Mastodon: 500 (links count as 23); Instagram and TikTok: 2,200; Telegram: 4,096 for text, 1,024 under photos, a video or a file.
cta_urlNoLink to track. Each account gets its own short link with UTM tags, placed in the caption or the first comment per network. Never added on X (paid links).
gbp_endNoGoogle Business Profile event or offer: when it ends (not before gbp_start), same format.
post_idYes
campaignNoutm_campaign value for the tracked links.
cta_textNo
draft_idNoReserved post ID returned by validate_post or needs_confirmation. Pass it unchanged to create_post so previewed tracked URLs and the confirmation plan remain exact.
gbp_linkNoGoogle Business Profile: where the button (or an offer's "redeem online") leads, https. Omitted: cta_url. Either way it becomes a tracked short link; links in the post's text aren't clickable on Google.
gbp_typeNoGoogle Business Profile: STANDARD (an update, the default), EVENT or OFFER. Events and offers need gbp_title, gbp_start and gbp_end.
x_threadNoX: up to 5 follow-up posts that continue the post as a thread (each is a paid X post).
alt_textsNoImage descriptions for screen readers, by media id (images in media_ids). Sent to Instagram, Facebook, X, LinkedIn, Bluesky and Mastodon. Stored on the image, so later posts reuse it; an empty string clears it.
gbp_startNoGoogle Business Profile event or offer: when it starts, in the location's own time, "2026-11-05" (the whole day) or "2026-11-05T18:30". No time zone.
gbp_termsNoGoogle Business Profile offer: terms and conditions (optional).
gbp_titleNoGoogle Business Profile event or offer: its title (required there, up to 58 characters).
group_idsNoAccount groups — every active account in them is added to channel_ids.
media_idsNoMedia from upload_media_from_url, in display order. Instagram, TikTok and YouTube need media; Reels/Shorts/Video need a video file.
gbp_buttonNoGoogle Business Profile update or event: the button. CALL dials the profile's phone number (no link); the others lead to gbp_link or cta_url. Omitted with a link: LEARN_MORE. Offers get Google's own button instead.
gbp_couponNoGoogle Business Profile offer: a coupon code (optional).
channel_idsNoAccounts to publish to (ids from list_channels).
per_channelNoPer-account overrides and network fields. TikTok accounts need tiktok_privacy here.
video_titleNoVideo title on Facebook and LinkedIn videos (YouTube uses youtube_title).
ai_generatedNoMade or meaningfully altered with AI. Sent as each network's AI label: Instagram, Facebook Reels, YouTube (altered or synthetic content), TikTok (AI-generated), X (made with AI), Pinterest (AI-modified disclosure).
workspace_idYesWorkspace id from list_workspaces
youtube_tagsNoYouTube tags, 500 characters in total.
first_commentNoPosted right after the post as its first comment (the usual place for a lead link). Facebook, Instagram, YouTube: a comment. X: a reply (a link in it counts against the X link allowance). LinkedIn company Pages: a comment as the Page. LinkedIn profiles and TikTok: skipped (list_channels first_comment=false).
post_languageNoMastodon: the post's language as an ISO 639-1 code (he, en, es…); omitted = the account's default.
threads_topicNoThreads: the post's topic, 1–50 characters, no period or ampersand (e.g. Recipes).
youtube_titleNoYouTube video title (default: first line of the caption). Overridable per channel.
cover_media_idNoCover image for the post's video: an IMAGE id from upload_media_from_url (not in media_ids). A cover the network refuses never fails the post: the result carries a notice. null removes it. Per network ("Cover at the start of the video" is cover_first_frame): Facebook: The image becomes the thumbnail of the video or Reel. Stories have no cover. Instagram: The image becomes the Reel's cover, in the feed and on the profile. Stories have no cover. YouTube: The image becomes the video's thumbnail. YouTube allows this only for phone-verified channels (youtube.com/verify); without that, the video goes up with a thumbnail YouTube picks. X: X has no cover setting: it shows the video's first frame. To show your cover, turn on "Cover at the start of the video". LinkedIn: The image becomes the video's thumbnail. TikTok: TikTok takes no cover image through its API, only a moment of the video, and applies even that only to public posts (a private post shows the first frame). To always show your cover, private posts included, turn on "Cover at the start of the video". Bluesky: Bluesky has no cover setting: it shows the video's first frame. To show your cover, turn on "Cover at the start of the video". Telegram: The image becomes the video's cover in the channel. Mastodon: The image is shown on the video on Mastodon until it's played. Threads: Threads has no cover setting: it shows the video's first frame. To show your cover, turn on "Cover at the start of the video". Pinterest: The image becomes the video Pin's cover on Pinterest. Google Business Profile: Google Business Profile posts take no video, so there is no cover.
paid_promotionNoPaid promotion or partnership disclosure: YouTube (paid product placement), X (paid partnership). TikTok uses tiktok_commercial.
pinterest_linkNoPinterest: where the Pin leads (https). Omitted: cta_url. Either way it becomes a tracked short link; links in the description aren't clickable on Pinterest.
content_warningNoMastodon: a content warning shown before the post (readers tap to see it; it also hides images). Counts toward the 500 characters.
pinterest_titleNoPinterest: the Pin's title, up to 100 characters (feeds show about the first 40). The caption is the Pin's description (≤800).
stagger_secondsNoDeprecated: [min, max] — use stagger_min_seconds and stagger_max_seconds.
telegram_silentNoTelegram: send without a sound, so channel subscribers get no notification.
tiktok_cover_msNoTikTok: which frame of the video becomes the cover, in milliseconds from the start (TikTok can't take a cover image). TikTok applies it to public posts only; private posts show the first frame. To show your cover image on every TikTok post, public or private, use cover_media_id with cover_first_frame instead. Default: the first frame.
youtube_licenseNoYouTube license (default youtube).
youtube_privacyNoYouTube: public (default), unlisted or private.
x_reply_settingsNoX: who can reply (default everyone): following, mentionedUsers, subscribers or verified.
cover_first_frameNoPut the cover image (cover_media_id) at the start of the video, as its first two frames (~1/15 s), so networks that show the video's first frame show your cover: true = only where the network can't take a cover image (TikTok, X, Bluesky, Stories), "all" = on every network, false = never. The original video isn't changed; Shager publishes a copy. Default when omitted: true if the post has a cover and goes to TikTok, X or Bluesky, else false.
threads_link_cardNoThreads text post (no media): an https link shown as a card under the text (link_attachment). Without it, Threads previews the first link in the text.
pinterest_board_idNoREQUIRED for a Pinterest account (per_channel, since each account has its own boards): the board the Pin goes to, one of that account's pinterest.boards from list_channels.
youtube_embeddableNoYouTube: allow embedding on other sites (default true).
facebook_pin_to_topNoFacebook: pin the post to the top of the Page (feed posts).
instagram_user_tagsNoInstagram single photo: people tagged on it, x/y from 0 to 1 measured from the top-left.
linkedin_visibilityNoLinkedIn: PUBLIC (default), CONNECTIONS or LOGGED_IN.
mastodon_visibilityNoMastodon: who sees the post: public (default), unlisted (quiet public: not in public timelines or hashtags) or private (followers only).
stagger_max_secondsNoLongest pause between two accounts of the same network (default 90).
stagger_min_secondsNoShortest pause between two accounts of the same network (default 30). Facebook and Instagram share one lane.
youtube_category_idNoYouTube category id (default 22, People & Blogs).
youtube_playlist_idNoYouTube: add the video to this playlist of the channel (per_channel, since each channel has its own playlists).
facebook_link_buttonNoFacebook text post: a button (e.g. LEARN_MORE, SHOP_NOW, SIGN_UP, BOOK_NOW) that opens the post's link, usually cta_url. If Facebook refuses the button, the post goes without it.
instagram_trial_reelNoInstagram trial Reel, shown to non-followers first: MANUAL (you share it later from the app) or SS_PERFORMANCE (shared automatically if it performs well).
instagram_location_idNoInstagram: the location shown on the post, as the numeric id of a Facebook Page for that place (Meta's location_id; Shager has no place search yet, so pass an id you already know). Feed photos, carousels and Reels; per_channel to vary it per account.
threads_reply_controlNoThreads: who can reply: everyone (default), accounts_you_follow, mentioned_only or followers_only.
youtube_made_for_kidsNoYouTube's made-for-kids declaration (COPPA). Required explicitly when targeting YouTube; declare whether the video is made for children.
instagram_comments_offNoInstagram: turn comments off right after publishing.
instagram_collaboratorsNoInstagram: up to 3 usernames invited as collaborators (feed, carousel, Reel). The post appears on their profile once they accept in the app.
instagram_share_to_feedNoInstagram Reel: also show it in the profile's main grid (default true).
linkedin_disable_reshareNoLinkedIn: stop others from resharing the post.
youtube_notify_subscribersNoYouTube: notify subscribers about the upload (default true).

TDQS

A4.6/5.0
Behavior4/5

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

Annotations already declare destructiveHint=true and idempotentHint=true, but the description adds substantive behavior beyond them: channel_ids/group_ids replace the account list, media_ids replace media, per_channel merges field by field, null clears named fields, and approval-reset consequences. It doesn't say whether omitted fields are untouched (implied by 'send only the fields to change') or what the response body contains beyond 'remaining issues'.

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-loaded with the eligibility scope, then merge/clear semantics, then the approval-reset consequence. Every sentence carries information, but the block is dense with no separation, making the null-clearing list and the per_channel merge rule easy to skim past.

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 64-parameter mutation tool with no output schema, the description covers the critical gaps: allowed states, merge vs. replace semantics, clearing via null, approval re-triggering, and the sibling to call for scheduled posts. It also notes the response reports remaining issues, which suffices since no output schema exists.

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 97%, so the schema already documents nearly every parameter and a baseline of 3 would be defensible. The description earns a bump by explaining merge versus replace semantics across the 64 parameters — the single most error-prone aspect of this tool — which the per-parameter schema text does not state collectively.

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 (change any field) on a specific resource (a post) and defines the eligible states (DRAFT, IN_REVIEW, CHANGES_REQUESTED, APPROVED) while excluding scheduled/published. An agent can distinguish this immediately from create_post, schedule_post, and cancel_post.

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 names the blocking condition and the alternative: 'A SCHEDULED post must be cancel_post-ed first.' It also names the eligible states and warns that content changes after client approval send the post back to DRAFT, which is precisely the when-to-use nuance an agent needs.

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

upload_media_from_urlUpload media from a URLAInspect

Downloads a public image (JPEG, PNG, WebP, GIF), video (MP4, MOV, WebM) or PDF into the workspace and returns a media id to put in create_post.media_ids. Media is per workspace and reusable across posts. Shager measures every video itself: width and height as displayed (a rotated phone video counts as portrait) and duration_ms come back in the response, and validate_post checks Reels, Shorts, Stories and TikTok length and shape rules with them (Shorts: vertical or square, up to 3 minutes; Instagram Reels 3 s–15 min; Stories up to 60 s). width, height and duration_ms are optional and only used when a file can't be measured; measured values win. A video that comes back with null width, height or duration_ms couldn't be measured: pass them and upload again before scheduling it. Private, local and credentialed URLs are refused. Size limit: 2 GB.

NameRequiredDescriptionDefault
urlYes
widthNoFallback only: used when the video can't be measured.
heightNoFallback only: used when the video can't be measured.
file_nameNo
duration_msNoFallback only: used when the video can't be measured.
workspace_idYesWorkspace id from list_workspaces
idempotency_keyNoAny unique string you choose (REST: the Idempotency-Key header works too). Retrying with the same key and body returns the first result instead of creating a second one. Kept 24 hours.

TDQS

A4.6/5.0
Behavior5/5

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

Annotations declare openWorldHint=true, idempotentHint=false and destructiveHint=false but say nothing about constraints. The description adds what matters in practice: private/local/credentialed URLs are refused, a 2 GB size cap, per-workspace scoping and reuse, and the fact that null measurement fields mean the file must be re-uploaded with fallback values. That is real behavioral context beyond structured data.

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 purpose and return value, then layers constraints. The embedded platform limits (Shorts up to 3 min, Reels 3 s–15 min, Stories 60 s) are somewhat tangential to an upload tool, but they justify why duration_ms matters, so the length is defensible.

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?

No output schema exists, and the description compensates fully by describing what comes back (media id, measured width/height/duration_ms) and what a null means. Combined with format, size and URL-access constraints, an agent has everything needed to call it correctly.

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 a solid 71%, with width/height/duration_ms already labelled 'Fallback only' in the schema. The description reinforces the precedence rule ('optional and only used when a file can't be measured; measured values win') and explains the null-measurement retry loop, which the schema does not. It leaves file_name and idempotency_key unmentioned in prose, so not a perfect score.

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 ('Downloads a public image... video... or PDF into the workspace'), lists supported formats, and names the downstream consumer: the returned media id goes into create_post.media_ids. That routing line distinguishes it from create_post, schedule_post and validate_post without needing the schema.

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?

Clearly frames the workflow (upload here, then pass the id to create_post, and validate_post applies length/shape rules), and gives explicit recovery guidance for unmeasured videos. It stops short of a true 'don't use this when…' rule or naming an alternative upload path, which is why it isn't a 5.

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

validate_postValidate a post (dry run)A
Read-onlyIdempotent
Inspect

Checks a post against every account's network rules without saving anything and returns ALL issues at once. It approves nothing by itself: read next_step, which says in plain words what to do (fix issues, ask the human to confirm and pass confirmation_token, or create_post) (caption length, format support, media requirements, video length and shape, YouTube title, TikTok privacy and commercial fields, disconnected accounts). With schedule_at it also reports the X link allowance, the key's caps and whether the send would need confirmation_token from the returned plan, plus the dispatch plan. Run it before create_post when in doubt; it needs only the read scope and works in a sandbox.

NameRequiredDescriptionDefault
pollNoA poll on X, LinkedIn and Mastodon. A poll post carries no media.
labelNoInternal name for the post (never published).
formatNoFormat for every account. Default per network: Facebook/Instagram FEED (REEL with a video), YouTube SHORT, TikTok VIDEO, LinkedIn FEED (VIDEO with a video), X FEED. Unsupported on a network = an issue, not a silent change.
captionYesMaster text. Goes to every account unless per_channel overrides it. X: 280 characters; Bluesky: 300; Mastodon: 500 (links count as 23); Instagram and TikTok: 2,200; Telegram: 4,096 for text, 1,024 under photos, a video or a file.
cta_urlNoLink to track. Each account gets its own short link with UTM tags, placed in the caption or the first comment per network. Never added on X (paid links).
gbp_endNoGoogle Business Profile event or offer: when it ends (not before gbp_start), same format.
post_idNoExisting draft or approved post; enables checking its approval state and preserving its tracked URLs.
campaignNoutm_campaign value for the tracked links.
cta_textNo
draft_idNoReserved post ID returned by validate_post or needs_confirmation. Pass it unchanged to create_post so previewed tracked URLs and the confirmation plan remain exact.
gbp_linkNoGoogle Business Profile: where the button (or an offer's "redeem online") leads, https. Omitted: cta_url. Either way it becomes a tracked short link; links in the post's text aren't clickable on Google.
gbp_typeNoGoogle Business Profile: STANDARD (an update, the default), EVENT or OFFER. Events and offers need gbp_title, gbp_start and gbp_end.
x_threadNoX: up to 5 follow-up posts that continue the post as a thread (each is a paid X post).
alt_textsNoImage descriptions for screen readers, by media id (images in media_ids). Sent to Instagram, Facebook, X, LinkedIn, Bluesky and Mastodon. Stored on the image, so later posts reuse it; an empty string clears it.
gbp_startNoGoogle Business Profile event or offer: when it starts, in the location's own time, "2026-11-05" (the whole day) or "2026-11-05T18:30". No time zone.
gbp_termsNoGoogle Business Profile offer: terms and conditions (optional).
gbp_titleNoGoogle Business Profile event or offer: its title (required there, up to 58 characters).
group_idsNoAccount groups — every active account in them is added to channel_ids.
media_idsNoMedia from upload_media_from_url, in display order. Instagram, TikTok and YouTube need media; Reels/Shorts/Video need a video file.
gbp_buttonNoGoogle Business Profile update or event: the button. CALL dials the profile's phone number (no link); the others lead to gbp_link or cta_url. Omitted with a link: LEARN_MORE. Offers get Google's own button instead.
gbp_couponNoGoogle Business Profile offer: a coupon code (optional).
channel_idsNoAccounts to publish to (ids from list_channels).
per_channelNoPer-account overrides and network fields. TikTok accounts need tiktok_privacy here.
schedule_atNoOptional: also check allowances, caps and confirmation for this time.
video_titleNoVideo title on Facebook and LinkedIn videos (YouTube uses youtube_title).
ai_generatedNoMade or meaningfully altered with AI. Sent as each network's AI label: Instagram, Facebook Reels, YouTube (altered or synthetic content), TikTok (AI-generated), X (made with AI), Pinterest (AI-modified disclosure).
workspace_idYesWorkspace id from list_workspaces
youtube_tagsNoYouTube tags, 500 characters in total.
first_commentNoPosted right after the post as its first comment (the usual place for a lead link). Facebook, Instagram, YouTube: a comment. X: a reply (a link in it counts against the X link allowance). LinkedIn company Pages: a comment as the Page. LinkedIn profiles and TikTok: skipped (list_channels first_comment=false).
post_languageNoMastodon: the post's language as an ISO 639-1 code (he, en, es…); omitted = the account's default.
threads_topicNoThreads: the post's topic, 1–50 characters, no period or ampersand (e.g. Recipes).
youtube_titleNoYouTube video title (default: first line of the caption). Overridable per channel.
cover_media_idNoCover image for the post's video: an IMAGE id from upload_media_from_url (not in media_ids). A cover the network refuses never fails the post: the result carries a notice. null removes it. Per network ("Cover at the start of the video" is cover_first_frame): Facebook: The image becomes the thumbnail of the video or Reel. Stories have no cover. Instagram: The image becomes the Reel's cover, in the feed and on the profile. Stories have no cover. YouTube: The image becomes the video's thumbnail. YouTube allows this only for phone-verified channels (youtube.com/verify); without that, the video goes up with a thumbnail YouTube picks. X: X has no cover setting: it shows the video's first frame. To show your cover, turn on "Cover at the start of the video". LinkedIn: The image becomes the video's thumbnail. TikTok: TikTok takes no cover image through its API, only a moment of the video, and applies even that only to public posts (a private post shows the first frame). To always show your cover, private posts included, turn on "Cover at the start of the video". Bluesky: Bluesky has no cover setting: it shows the video's first frame. To show your cover, turn on "Cover at the start of the video". Telegram: The image becomes the video's cover in the channel. Mastodon: The image is shown on the video on Mastodon until it's played. Threads: Threads has no cover setting: it shows the video's first frame. To show your cover, turn on "Cover at the start of the video". Pinterest: The image becomes the video Pin's cover on Pinterest. Google Business Profile: Google Business Profile posts take no video, so there is no cover.
paid_promotionNoPaid promotion or partnership disclosure: YouTube (paid product placement), X (paid partnership). TikTok uses tiktok_commercial.
pinterest_linkNoPinterest: where the Pin leads (https). Omitted: cta_url. Either way it becomes a tracked short link; links in the description aren't clickable on Pinterest.
content_warningNoMastodon: a content warning shown before the post (readers tap to see it; it also hides images). Counts toward the 500 characters.
pinterest_titleNoPinterest: the Pin's title, up to 100 characters (feeds show about the first 40). The caption is the Pin's description (≤800).
stagger_secondsNoDeprecated: [min, max] — use stagger_min_seconds and stagger_max_seconds.
telegram_silentNoTelegram: send without a sound, so channel subscribers get no notification.
tiktok_cover_msNoTikTok: which frame of the video becomes the cover, in milliseconds from the start (TikTok can't take a cover image). TikTok applies it to public posts only; private posts show the first frame. To show your cover image on every TikTok post, public or private, use cover_media_id with cover_first_frame instead. Default: the first frame.
youtube_licenseNoYouTube license (default youtube).
youtube_privacyNoYouTube: public (default), unlisted or private.
x_reply_settingsNoX: who can reply (default everyone): following, mentionedUsers, subscribers or verified.
cover_first_frameNoPut the cover image (cover_media_id) at the start of the video, as its first two frames (~1/15 s), so networks that show the video's first frame show your cover: true = only where the network can't take a cover image (TikTok, X, Bluesky, Stories), "all" = on every network, false = never. The original video isn't changed; Shager publishes a copy. Default when omitted: true if the post has a cover and goes to TikTok, X or Bluesky, else false.
threads_link_cardNoThreads text post (no media): an https link shown as a card under the text (link_attachment). Without it, Threads previews the first link in the text.
pinterest_board_idNoREQUIRED for a Pinterest account (per_channel, since each account has its own boards): the board the Pin goes to, one of that account's pinterest.boards from list_channels.
youtube_embeddableNoYouTube: allow embedding on other sites (default true).
facebook_pin_to_topNoFacebook: pin the post to the top of the Page (feed posts).
instagram_user_tagsNoInstagram single photo: people tagged on it, x/y from 0 to 1 measured from the top-left.
linkedin_visibilityNoLinkedIn: PUBLIC (default), CONNECTIONS or LOGGED_IN.
mastodon_visibilityNoMastodon: who sees the post: public (default), unlisted (quiet public: not in public timelines or hashtags) or private (followers only).
stagger_max_secondsNoLongest pause between two accounts of the same network (default 90).
stagger_min_secondsNoShortest pause between two accounts of the same network (default 30). Facebook and Instagram share one lane.
youtube_category_idNoYouTube category id (default 22, People & Blogs).
youtube_playlist_idNoYouTube: add the video to this playlist of the channel (per_channel, since each channel has its own playlists).
facebook_link_buttonNoFacebook text post: a button (e.g. LEARN_MORE, SHOP_NOW, SIGN_UP, BOOK_NOW) that opens the post's link, usually cta_url. If Facebook refuses the button, the post goes without it.
instagram_trial_reelNoInstagram trial Reel, shown to non-followers first: MANUAL (you share it later from the app) or SS_PERFORMANCE (shared automatically if it performs well).
instagram_location_idNoInstagram: the location shown on the post, as the numeric id of a Facebook Page for that place (Meta's location_id; Shager has no place search yet, so pass an id you already know). Feed photos, carousels and Reels; per_channel to vary it per account.
threads_reply_controlNoThreads: who can reply: everyone (default), accounts_you_follow, mentioned_only or followers_only.
youtube_made_for_kidsNoYouTube's made-for-kids declaration (COPPA). Required explicitly when targeting YouTube; declare whether the video is made for children.
instagram_comments_offNoInstagram: turn comments off right after publishing.
instagram_collaboratorsNoInstagram: up to 3 usernames invited as collaborators (feed, carousel, Reel). The post appears on their profile once they accept in the app.
instagram_share_to_feedNoInstagram Reel: also show it in the profile's main grid (default true).
linkedin_disable_reshareNoLinkedIn: stop others from resharing the post.
youtube_notify_subscribersNoYouTube: notify subscribers about the upload (default true).

TDQS

A4.5/5.0
Behavior5/5

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

Annotations already declare readOnly/idempotent/non-destructive, and the description still adds substantive context: nothing is persisted, ALL issues are returned at once rather than failing on the first, the tool never approves anything itself, it needs only the read scope, and it works in a sandbox. The schedule_at paragraph discloses extra outputs (X link allowance, key caps, confirmation need, dispatch plan) that no structured field conveys.

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-loaded with the core behavior and free of filler. The long parenthetical listing the checked rule categories is awkwardly spliced into the middle of the next_step sentence, forcing a re-read, but the overall length is justified for a tool this complex.

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 65-parameter tool with no output schema, the description carries the essential return semantics: an issue list, a next_step string, and a confirmation/dispatch plan when schedule_at is given. It does not describe the shape of individual issue objects or how post_id/draft_id affect the check beyond what per-parameter schema text already says.

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 98% schema coverage the schema already documents nearly all 65 params, so the baseline is met. The description adds real value on top by explaining what schedule_at unlocks (allowances, caps, confirmation_token, dispatch plan) and by naming the validation categories (caption length, format support, media requirements, video shape, TikTok privacy/commercial, disconnected accounts), which tells the agent which inputs the check exercises.

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 ('Checks a post against every account's network rules') and pins down the dry-run nature immediately ('without saving anything'). It also names the sibling it complements ('Run it before create_post'), so an agent can distinguish it from create_post/schedule_post without reading a schema.

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 a clear usage rule ('Run it before create_post when in doubt') and an explicit follow-up protocol via next_step (fix issues, request confirmation, or create). It does not cover when not to bother calling it (e.g. trivial single-account posts) or alternatives beyond create_post, so it falls short of a full 5.

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

whoamiWho am IA
Read-onlyIdempotent
Inspect

Start here. The organization this key belongs to, its plan and usage (accounts and posts this month, X posts and X link posts left), whether the key may publish (scope, claimed sandbox and a plan in force; why_not says what is missing, and without publishing only drafts work), the key's caps, and — in a sandbox — the claim state. Use can_publish to decide between drafting and scheduling.

NameRequiredDescriptionDefault

No parameters

TDQS

A4.1/5.0
Behavior4/5

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

The annotations already declare read-only, idempotent, non-destructive, closed-world behavior, so the description is not burdened with safety disclosure. It adds useful behavioral context beyond the annotations, including publishability conditions, the meaning of why_not, sandbox claim state, and the consequence that without publishing only drafts work.

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 compact and front-loads “Start here,” then packs the return context and decision guidance into a dense but purposeful block. It contains no filler, though the long parenthetical sentence is somewhat harder to scan than it could be.

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 zero-parameter, read-only introspection tool with no output schema, the description gives enough context to understand what information will be returned and how to use it. It covers organization identity, plan usage, publish eligibility, caps, and sandbox state, leaving no material gap for correct invocation.

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?

The tool takes zero parameters, so there are no parameter semantics to explain; per the rubric this establishes a baseline of 4. The description appropriately does not waste space documenting inputs.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states that this is the starting-point identity/context tool and enumerates what it returns: organization, plan, usage, publish eligibility, caps, and sandbox claim state. It is specific enough to distinguish it from the sibling tools, though it does not explicitly name or contrast any sibling.

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?

“Start here” gives explicit guidance that this should be called before other operations, and “Use can_publish to decide between drafting and scheduling” ties the output to a concrete decision. It does not state when not to use it or name alternative tools, but the primary usage context is clear.

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

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 5 tool updates
    • Changedcreate_post17 fields changed
      • changedInput schema / properties / cover_media_id / description
        Previous value: -"Cover image for the post's video: an IMAGE id from upload_media_from_url (not in media_ids). A cover the network refuses never fails the post: the result carries a notice. null removes it. Per network (\"Cover at the start of the video\" is cover_first_frame): Facebook: The image becomes the thumbnail of the video or Reel. Stories have no cover. Instagram: The image becomes the Reel's cover, in the feed and on the profile. Stories have no cover. YouTube: The image becomes the video's thumbnail. YouTube allows this only for phone-verified channels (youtube.com/verify); without that, the video goes up with a thumbnail YouTube picks. X: X has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\". LinkedIn: The image becomes the video's thumbnail. TikTok: TikTok takes no cover image through its API, only a moment of the video, and applies even that only to public posts (a private post shows the first frame). To always show your cover, private posts included, turn on \"Cover at the start of the video\". Bluesky: Bluesky has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\". Telegram: The image becomes the video's cover in the channel. Mastodon: The image is shown on the video on Mastodon until it's played. Threads: Threads has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\". Pinterest: The image becomes the video Pin's cover on Pinterest."New value: +"Cover image for the post's video: an IMAGE id from upload_media_from_url (not in media_ids). A cover the network refuses never fails the post: the result carries a notice. null removes it. Per network (\"Cover at the start of the video\" is cover_first_frame): Facebook: The image becomes the thumbnail of the video or Reel. Stories have no cover. Instagram: The image becomes the Reel's cover, in the feed and on the profile. Stories have no cover. YouTube: The image becomes the video's thumbnail. YouTube allows this only for phone-verified channels (youtube.com/verify); without that, the video goes up with a thumbnail YouTube picks. X: X has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\". LinkedIn: The image becomes the video's thumbnail. TikTok: TikTok takes no cover image through its API, only a moment of the video, and applies even that only to public posts (a private post shows the first frame). To always show your cover, private posts included, turn on \"Cover at the start of the video\". Bluesky: Bluesky has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\". Telegram: The image becomes the video's cover in the channel. Mastodon: The image is shown on the video on Mastodon until it's played. Threads: Threads has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\". Pinterest: The image becomes the video Pin's cover on Pinterest. Google Business Profile: Google Business Profile posts take no video, so there is no cover."
      • addedInput schema / properties / gbp_button
        Added value: +{
        +  "description": "Google Business Profile update or event: the button. CALL dials the profile's phone number (no link); the others lead to gbp_link or cta_url. Omitted with a link: LEARN_MORE. Offers get Google's own button instead.",
        +  "enum": [
        +    "LEARN_MORE",
        +    "BOOK",
        +    "ORDER",
        +    "SHOP",
        +    "SIGN_UP",
        +    "CALL"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / gbp_coupon
        Added value: +{
        +  "description": "Google Business Profile offer: a coupon code (optional).",
        +  "maxLength": 58,
        +  "type": "string"
        +}
      • addedInput schema / properties / gbp_end
        Added value: +{
        +  "description": "Google Business Profile event or offer: when it ends (not before gbp_start), same format.",
        +  "pattern": "^\\d{4}-\\d{2}-\\d{2}(T\\d{2}:\\d{2})?$",
        +  "type": "string"
        +}
      • addedInput schema / properties / gbp_link
        Added value: +{
        +  "description": "Google Business Profile: where the button (or an offer's \"redeem online\") leads, https. Omitted: cta_url. Either way it becomes a tracked short link; links in the post's text aren't clickable on Google.",
        +  "maxLength": 2048,
        +  "type": "string"
        +}
      • addedInput schema / properties / gbp_start
        Added value: +{
        +  "description": "Google Business Profile event or offer: when it starts, in the location's own time, \"2026-11-05\" (the whole day) or \"2026-11-05T18:30\". No time zone.",
        +  "pattern": "^\\d{4}-\\d{2}-\\d{2}(T\\d{2}:\\d{2})?$",
        +  "type": "string"
        +}
      • addedInput schema / properties / gbp_terms
        Added value: +{
        +  "description": "Google Business Profile offer: terms and conditions (optional).",
        +  "maxLength": 1500,
        +  "type": "string"
        +}
      • addedInput schema / properties / gbp_title
        Added value: +{
        +  "description": "Google Business Profile event or offer: its title (required there, up to 58 characters).",
        +  "maxLength": 58,
        +  "type": "string"
        +}
      • addedInput schema / properties / gbp_type
        Added value: +{
        +  "description": "Google Business Profile: STANDARD (an update, the default), EVENT or OFFER. Events and offers need gbp_title, gbp_start and gbp_end.",
        +  "enum": [
        +    "STANDARD",
        +    "EVENT",
        +    "OFFER"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / per_channel / items / properties / gbp_button
        Added value: +{
        +  "description": "Google Business Profile update or event: the button. CALL dials the profile's phone number (no link); the others lead to gbp_link or cta_url. Omitted with a link: LEARN_MORE. Offers get Google's own button instead.",
        +  "enum": [
        +    "LEARN_MORE",
        +    "BOOK",
        +    "ORDER",
        +    "SHOP",
        +    "SIGN_UP",
        +    "CALL"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / per_channel / items / properties / gbp_coupon
        Added value: +{
        +  "description": "Google Business Profile offer: a coupon code (optional).",
        +  "maxLength": 58,
        +  "type": "string"
        +}
      • addedInput schema / properties / per_channel / items / properties / gbp_end
        Added value: +{
        +  "description": "Google Business Profile event or offer: when it ends (not before gbp_start), same format.",
        +  "pattern": "^\\d{4}-\\d{2}-\\d{2}(T\\d{2}:\\d{2})?$",
        +  "type": "string"
        +}
      • addedInput schema / properties / per_channel / items / properties / gbp_link
        Added value: +{
        +  "description": "Google Business Profile: where the button (or an offer's \"redeem online\") leads, https. Omitted: cta_url. Either way it becomes a tracked short link; links in the post's text aren't clickable on Google.",
        +  "maxLength": 2048,
        +  "type": "string"
        +}
      • addedInput schema / properties / per_channel / items / properties / gbp_start
        Added value: +{
        +  "description": "Google Business Profile event or offer: when it starts, in the location's own time, \"2026-11-05\" (the whole day) or \"2026-11-05T18:30\". No time zone.",
        +  "pattern": "^\\d{4}-\\d{2}-\\d{2}(T\\d{2}:\\d{2})?$",
        +  "type": "string"
        +}
      • addedInput schema / properties / per_channel / items / properties / gbp_terms
        Added value: +{
        +  "description": "Google Business Profile offer: terms and conditions (optional).",
        +  "maxLength": 1500,
        +  "type": "string"
        +}
      • addedInput schema / properties / per_channel / items / properties / gbp_title
        Added value: +{
        +  "description": "Google Business Profile event or offer: its title (required there, up to 58 characters).",
        +  "maxLength": 58,
        +  "type": "string"
        +}
      • addedInput schema / properties / per_channel / items / properties / gbp_type
        Added value: +{
        +  "description": "Google Business Profile: STANDARD (an update, the default), EVENT or OFFER. Events and offers need gbp_title, gbp_start and gbp_end.",
        +  "enum": [
        +    "STANDARD",
        +    "EVENT",
        +    "OFFER"
        +  ],
        +  "type": "string"
        +}
    • Changedlist_channels1 field changed
      • changedInput schema / properties / network / enum
        Previous value: -[
        -  "FACEBOOK",
        -  "INSTAGRAM",
        -  "LINKEDIN",
        -  "TIKTOK",
        -  "YOUTUBE",
        -  "X",
        -  "BLUESKY",
        -  "TELEGRAM",
        -  "MASTODON",
        -  "THREADS",
        -  "PINTEREST",
        -  "WHATSAPP"
        -]New value: +[
        +  "FACEBOOK",
        +  "INSTAGRAM",
        +  "LINKEDIN",
        +  "TIKTOK",
        +  "YOUTUBE",
        +  "X",
        +  "BLUESKY",
        +  "TELEGRAM",
        +  "MASTODON",
        +  "THREADS",
        +  "PINTEREST",
        +  "GOOGLE_BUSINESS",
        +  "WHATSAPP"
        +]
    • Changedlist_posts1 field changed
      • changedInput schema / properties / network / enum
        Previous value: -[
        -  "FACEBOOK",
        -  "INSTAGRAM",
        -  "LINKEDIN",
        -  "TIKTOK",
        -  "YOUTUBE",
        -  "X",
        -  "BLUESKY",
        -  "TELEGRAM",
        -  "MASTODON",
        -  "THREADS",
        -  "PINTEREST",
        -  "WHATSAPP"
        -]New value: +[
        +  "FACEBOOK",
        +  "INSTAGRAM",
        +  "LINKEDIN",
        +  "TIKTOK",
        +  "YOUTUBE",
        +  "X",
        +  "BLUESKY",
        +  "TELEGRAM",
        +  "MASTODON",
        +  "THREADS",
        +  "PINTEREST",
        +  "GOOGLE_BUSINESS",
        +  "WHATSAPP"
        +]
    • Changedupdate_post17 fields changed
      • changedInput schema / properties / cover_media_id / description
        Previous value: -"Cover image for the post's video: an IMAGE id from upload_media_from_url (not in media_ids). A cover the network refuses never fails the post: the result carries a notice. null removes it. Per network (\"Cover at the start of the video\" is cover_first_frame): Facebook: The image becomes the thumbnail of the video or Reel. Stories have no cover. Instagram: The image becomes the Reel's cover, in the feed and on the profile. Stories have no cover. YouTube: The image becomes the video's thumbnail. YouTube allows this only for phone-verified channels (youtube.com/verify); without that, the video goes up with a thumbnail YouTube picks. X: X has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\". LinkedIn: The image becomes the video's thumbnail. TikTok: TikTok takes no cover image through its API, only a moment of the video, and applies even that only to public posts (a private post shows the first frame). To always show your cover, private posts included, turn on \"Cover at the start of the video\". Bluesky: Bluesky has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\". Telegram: The image becomes the video's cover in the channel. Mastodon: The image is shown on the video on Mastodon until it's played. Threads: Threads has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\". Pinterest: The image becomes the video Pin's cover on Pinterest."New value: +"Cover image for the post's video: an IMAGE id from upload_media_from_url (not in media_ids). A cover the network refuses never fails the post: the result carries a notice. null removes it. Per network (\"Cover at the start of the video\" is cover_first_frame): Facebook: The image becomes the thumbnail of the video or Reel. Stories have no cover. Instagram: The image becomes the Reel's cover, in the feed and on the profile. Stories have no cover. YouTube: The image becomes the video's thumbnail. YouTube allows this only for phone-verified channels (youtube.com/verify); without that, the video goes up with a thumbnail YouTube picks. X: X has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\". LinkedIn: The image becomes the video's thumbnail. TikTok: TikTok takes no cover image through its API, only a moment of the video, and applies even that only to public posts (a private post shows the first frame). To always show your cover, private posts included, turn on \"Cover at the start of the video\". Bluesky: Bluesky has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\". Telegram: The image becomes the video's cover in the channel. Mastodon: The image is shown on the video on Mastodon until it's played. Threads: Threads has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\". Pinterest: The image becomes the video Pin's cover on Pinterest. Google Business Profile: Google Business Profile posts take no video, so there is no cover."
      • addedInput schema / properties / gbp_button
        Added value: +{
        +  "description": "Google Business Profile update or event: the button. CALL dials the profile's phone number (no link); the others lead to gbp_link or cta_url. Omitted with a link: LEARN_MORE. Offers get Google's own button instead.",
        +  "enum": [
        +    "LEARN_MORE",
        +    "BOOK",
        +    "ORDER",
        +    "SHOP",
        +    "SIGN_UP",
        +    "CALL"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / gbp_coupon
        Added value: +{
        +  "description": "Google Business Profile offer: a coupon code (optional).",
        +  "maxLength": 58,
        +  "type": "string"
        +}
      • addedInput schema / properties / gbp_end
        Added value: +{
        +  "description": "Google Business Profile event or offer: when it ends (not before gbp_start), same format.",
        +  "pattern": "^\\d{4}-\\d{2}-\\d{2}(T\\d{2}:\\d{2})?$",
        +  "type": "string"
        +}
      • addedInput schema / properties / gbp_link
        Added value: +{
        +  "description": "Google Business Profile: where the button (or an offer's \"redeem online\") leads, https. Omitted: cta_url. Either way it becomes a tracked short link; links in the post's text aren't clickable on Google.",
        +  "maxLength": 2048,
        +  "type": "string"
        +}
      • addedInput schema / properties / gbp_start
        Added value: +{
        +  "description": "Google Business Profile event or offer: when it starts, in the location's own time, \"2026-11-05\" (the whole day) or \"2026-11-05T18:30\". No time zone.",
        +  "pattern": "^\\d{4}-\\d{2}-\\d{2}(T\\d{2}:\\d{2})?$",
        +  "type": "string"
        +}
      • addedInput schema / properties / gbp_terms
        Added value: +{
        +  "description": "Google Business Profile offer: terms and conditions (optional).",
        +  "maxLength": 1500,
        +  "type": "string"
        +}
      • addedInput schema / properties / gbp_title
        Added value: +{
        +  "description": "Google Business Profile event or offer: its title (required there, up to 58 characters).",
        +  "maxLength": 58,
        +  "type": "string"
        +}
      • addedInput schema / properties / gbp_type
        Added value: +{
        +  "description": "Google Business Profile: STANDARD (an update, the default), EVENT or OFFER. Events and offers need gbp_title, gbp_start and gbp_end.",
        +  "enum": [
        +    "STANDARD",
        +    "EVENT",
        +    "OFFER"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / per_channel / items / properties / gbp_button
        Added value: +{
        +  "description": "Google Business Profile update or event: the button. CALL dials the profile's phone number (no link); the others lead to gbp_link or cta_url. Omitted with a link: LEARN_MORE. Offers get Google's own button instead.",
        +  "enum": [
        +    "LEARN_MORE",
        +    "BOOK",
        +    "ORDER",
        +    "SHOP",
        +    "SIGN_UP",
        +    "CALL"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / per_channel / items / properties / gbp_coupon
        Added value: +{
        +  "description": "Google Business Profile offer: a coupon code (optional).",
        +  "maxLength": 58,
        +  "type": "string"
        +}
      • addedInput schema / properties / per_channel / items / properties / gbp_end
        Added value: +{
        +  "description": "Google Business Profile event or offer: when it ends (not before gbp_start), same format.",
        +  "pattern": "^\\d{4}-\\d{2}-\\d{2}(T\\d{2}:\\d{2})?$",
        +  "type": "string"
        +}
      • addedInput schema / properties / per_channel / items / properties / gbp_link
        Added value: +{
        +  "description": "Google Business Profile: where the button (or an offer's \"redeem online\") leads, https. Omitted: cta_url. Either way it becomes a tracked short link; links in the post's text aren't clickable on Google.",
        +  "maxLength": 2048,
        +  "type": "string"
        +}
      • addedInput schema / properties / per_channel / items / properties / gbp_start
        Added value: +{
        +  "description": "Google Business Profile event or offer: when it starts, in the location's own time, \"2026-11-05\" (the whole day) or \"2026-11-05T18:30\". No time zone.",
        +  "pattern": "^\\d{4}-\\d{2}-\\d{2}(T\\d{2}:\\d{2})?$",
        +  "type": "string"
        +}
      • addedInput schema / properties / per_channel / items / properties / gbp_terms
        Added value: +{
        +  "description": "Google Business Profile offer: terms and conditions (optional).",
        +  "maxLength": 1500,
        +  "type": "string"
        +}
      • addedInput schema / properties / per_channel / items / properties / gbp_title
        Added value: +{
        +  "description": "Google Business Profile event or offer: its title (required there, up to 58 characters).",
        +  "maxLength": 58,
        +  "type": "string"
        +}
      • addedInput schema / properties / per_channel / items / properties / gbp_type
        Added value: +{
        +  "description": "Google Business Profile: STANDARD (an update, the default), EVENT or OFFER. Events and offers need gbp_title, gbp_start and gbp_end.",
        +  "enum": [
        +    "STANDARD",
        +    "EVENT",
        +    "OFFER"
        +  ],
        +  "type": "string"
        +}
    • Changedvalidate_post17 fields changed
      • changedInput schema / properties / cover_media_id / description
        Previous value: -"Cover image for the post's video: an IMAGE id from upload_media_from_url (not in media_ids). A cover the network refuses never fails the post: the result carries a notice. null removes it. Per network (\"Cover at the start of the video\" is cover_first_frame): Facebook: The image becomes the thumbnail of the video or Reel. Stories have no cover. Instagram: The image becomes the Reel's cover, in the feed and on the profile. Stories have no cover. YouTube: The image becomes the video's thumbnail. YouTube allows this only for phone-verified channels (youtube.com/verify); without that, the video goes up with a thumbnail YouTube picks. X: X has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\". LinkedIn: The image becomes the video's thumbnail. TikTok: TikTok takes no cover image through its API, only a moment of the video, and applies even that only to public posts (a private post shows the first frame). To always show your cover, private posts included, turn on \"Cover at the start of the video\". Bluesky: Bluesky has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\". Telegram: The image becomes the video's cover in the channel. Mastodon: The image is shown on the video on Mastodon until it's played. Threads: Threads has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\". Pinterest: The image becomes the video Pin's cover on Pinterest."New value: +"Cover image for the post's video: an IMAGE id from upload_media_from_url (not in media_ids). A cover the network refuses never fails the post: the result carries a notice. null removes it. Per network (\"Cover at the start of the video\" is cover_first_frame): Facebook: The image becomes the thumbnail of the video or Reel. Stories have no cover. Instagram: The image becomes the Reel's cover, in the feed and on the profile. Stories have no cover. YouTube: The image becomes the video's thumbnail. YouTube allows this only for phone-verified channels (youtube.com/verify); without that, the video goes up with a thumbnail YouTube picks. X: X has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\". LinkedIn: The image becomes the video's thumbnail. TikTok: TikTok takes no cover image through its API, only a moment of the video, and applies even that only to public posts (a private post shows the first frame). To always show your cover, private posts included, turn on \"Cover at the start of the video\". Bluesky: Bluesky has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\". Telegram: The image becomes the video's cover in the channel. Mastodon: The image is shown on the video on Mastodon until it's played. Threads: Threads has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\". Pinterest: The image becomes the video Pin's cover on Pinterest. Google Business Profile: Google Business Profile posts take no video, so there is no cover."
      • addedInput schema / properties / gbp_button
        Added value: +{
        +  "description": "Google Business Profile update or event: the button. CALL dials the profile's phone number (no link); the others lead to gbp_link or cta_url. Omitted with a link: LEARN_MORE. Offers get Google's own button instead.",
        +  "enum": [
        +    "LEARN_MORE",
        +    "BOOK",
        +    "ORDER",
        +    "SHOP",
        +    "SIGN_UP",
        +    "CALL"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / gbp_coupon
        Added value: +{
        +  "description": "Google Business Profile offer: a coupon code (optional).",
        +  "maxLength": 58,
        +  "type": "string"
        +}
      • addedInput schema / properties / gbp_end
        Added value: +{
        +  "description": "Google Business Profile event or offer: when it ends (not before gbp_start), same format.",
        +  "pattern": "^\\d{4}-\\d{2}-\\d{2}(T\\d{2}:\\d{2})?$",
        +  "type": "string"
        +}
      • addedInput schema / properties / gbp_link
        Added value: +{
        +  "description": "Google Business Profile: where the button (or an offer's \"redeem online\") leads, https. Omitted: cta_url. Either way it becomes a tracked short link; links in the post's text aren't clickable on Google.",
        +  "maxLength": 2048,
        +  "type": "string"
        +}
      • addedInput schema / properties / gbp_start
        Added value: +{
        +  "description": "Google Business Profile event or offer: when it starts, in the location's own time, \"2026-11-05\" (the whole day) or \"2026-11-05T18:30\". No time zone.",
        +  "pattern": "^\\d{4}-\\d{2}-\\d{2}(T\\d{2}:\\d{2})?$",
        +  "type": "string"
        +}
      • addedInput schema / properties / gbp_terms
        Added value: +{
        +  "description": "Google Business Profile offer: terms and conditions (optional).",
        +  "maxLength": 1500,
        +  "type": "string"
        +}
      • addedInput schema / properties / gbp_title
        Added value: +{
        +  "description": "Google Business Profile event or offer: its title (required there, up to 58 characters).",
        +  "maxLength": 58,
        +  "type": "string"
        +}
      • addedInput schema / properties / gbp_type
        Added value: +{
        +  "description": "Google Business Profile: STANDARD (an update, the default), EVENT or OFFER. Events and offers need gbp_title, gbp_start and gbp_end.",
        +  "enum": [
        +    "STANDARD",
        +    "EVENT",
        +    "OFFER"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / per_channel / items / properties / gbp_button
        Added value: +{
        +  "description": "Google Business Profile update or event: the button. CALL dials the profile's phone number (no link); the others lead to gbp_link or cta_url. Omitted with a link: LEARN_MORE. Offers get Google's own button instead.",
        +  "enum": [
        +    "LEARN_MORE",
        +    "BOOK",
        +    "ORDER",
        +    "SHOP",
        +    "SIGN_UP",
        +    "CALL"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / per_channel / items / properties / gbp_coupon
        Added value: +{
        +  "description": "Google Business Profile offer: a coupon code (optional).",
        +  "maxLength": 58,
        +  "type": "string"
        +}
      • addedInput schema / properties / per_channel / items / properties / gbp_end
        Added value: +{
        +  "description": "Google Business Profile event or offer: when it ends (not before gbp_start), same format.",
        +  "pattern": "^\\d{4}-\\d{2}-\\d{2}(T\\d{2}:\\d{2})?$",
        +  "type": "string"
        +}
      • addedInput schema / properties / per_channel / items / properties / gbp_link
        Added value: +{
        +  "description": "Google Business Profile: where the button (or an offer's \"redeem online\") leads, https. Omitted: cta_url. Either way it becomes a tracked short link; links in the post's text aren't clickable on Google.",
        +  "maxLength": 2048,
        +  "type": "string"
        +}
      • addedInput schema / properties / per_channel / items / properties / gbp_start
        Added value: +{
        +  "description": "Google Business Profile event or offer: when it starts, in the location's own time, \"2026-11-05\" (the whole day) or \"2026-11-05T18:30\". No time zone.",
        +  "pattern": "^\\d{4}-\\d{2}-\\d{2}(T\\d{2}:\\d{2})?$",
        +  "type": "string"
        +}
      • addedInput schema / properties / per_channel / items / properties / gbp_terms
        Added value: +{
        +  "description": "Google Business Profile offer: terms and conditions (optional).",
        +  "maxLength": 1500,
        +  "type": "string"
        +}
      • addedInput schema / properties / per_channel / items / properties / gbp_title
        Added value: +{
        +  "description": "Google Business Profile event or offer: its title (required there, up to 58 characters).",
        +  "maxLength": 58,
        +  "type": "string"
        +}
      • addedInput schema / properties / per_channel / items / properties / gbp_type
        Added value: +{
        +  "description": "Google Business Profile: STANDARD (an update, the default), EVENT or OFFER. Events and offers need gbp_title, gbp_start and gbp_end.",
        +  "enum": [
        +    "STANDARD",
        +    "EVENT",
        +    "OFFER"
        +  ],
        +  "type": "string"
        +}
  2. 6 tool updates
    • Changedcreate_post10 fields changed
      • changedInput schema / properties / ai_generated / description
        Previous value: -"Made or meaningfully altered with AI. Sent as each network's AI label: Instagram, Facebook Reels, YouTube (altered or synthetic content), TikTok (AI-generated), X (made with AI)."New value: +"Made or meaningfully altered with AI. Sent as each network's AI label: Instagram, Facebook Reels, YouTube (altered or synthetic content), TikTok (AI-generated), X (made with AI), Pinterest (AI-modified disclosure)."
      • changedInput schema / properties / confirm / description
        Previous value: -"Deprecated boolean; does not bypass confirmation. A confirmation_token is required when a schedule goes to more than 10 accounts or starts within 60 minutes. Without it you get needs_confirmation with the dispatch plan; show it to your human, then resend with confirmation_token from the returned plan."New value: +"Deprecated boolean; does not bypass confirmation. A confirmation_token is required when a schedule goes to more than 10 accounts, starts within 60 minutes, or includes a Pinterest account. Without it you get needs_confirmation with the dispatch plan; show it to your human, then resend with confirmation_token from the returned plan."
      • changedInput schema / properties / cover_media_id / description
        Previous value: -"Cover image for the post's video: an IMAGE id from upload_media_from_url (not in media_ids). A cover the network refuses never fails the post: the result carries a notice. null removes it. Per network (\"Cover at the start of the video\" is cover_first_frame): Facebook: The image becomes the thumbnail of the video or Reel. Stories have no cover. Instagram: The image becomes the Reel's cover, in the feed and on the profile. Stories have no cover. YouTube: The image becomes the video's thumbnail. YouTube allows this only for phone-verified channels (youtube.com/verify); without that, the video goes up with a thumbnail YouTube picks. X: X has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\". LinkedIn: The image becomes the video's thumbnail. TikTok: TikTok takes no cover image through its API, only a moment of the video, and applies even that only to public posts (a private post shows the first frame). To always show your cover, private posts included, turn on \"Cover at the start of the video\". Bluesky: Bluesky has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\". Telegram: The image becomes the video's cover in the channel. Mastodon: The image is shown on the video on Mastodon until it's played. Threads: Threads has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\"."New value: +"Cover image for the post's video: an IMAGE id from upload_media_from_url (not in media_ids). A cover the network refuses never fails the post: the result carries a notice. null removes it. Per network (\"Cover at the start of the video\" is cover_first_frame): Facebook: The image becomes the thumbnail of the video or Reel. Stories have no cover. Instagram: The image becomes the Reel's cover, in the feed and on the profile. Stories have no cover. YouTube: The image becomes the video's thumbnail. YouTube allows this only for phone-verified channels (youtube.com/verify); without that, the video goes up with a thumbnail YouTube picks. X: X has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\". LinkedIn: The image becomes the video's thumbnail. TikTok: TikTok takes no cover image through its API, only a moment of the video, and applies even that only to public posts (a private post shows the first frame). To always show your cover, private posts included, turn on \"Cover at the start of the video\". Bluesky: Bluesky has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\". Telegram: The image becomes the video's cover in the channel. Mastodon: The image is shown on the video on Mastodon until it's played. Threads: Threads has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\". Pinterest: The image becomes the video Pin's cover on Pinterest."
      • changedInput schema / properties / per_channel / items / properties / ai_generated / description
        Previous value: -"Made or meaningfully altered with AI. Sent as each network's AI label: Instagram, Facebook Reels, YouTube (altered or synthetic content), TikTok (AI-generated), X (made with AI)."New value: +"Made or meaningfully altered with AI. Sent as each network's AI label: Instagram, Facebook Reels, YouTube (altered or synthetic content), TikTok (AI-generated), X (made with AI), Pinterest (AI-modified disclosure)."
      • addedInput schema / properties / per_channel / items / properties / pinterest_board_id
        Added value: +{
        +  "description": "REQUIRED for a Pinterest account (per_channel, since each account has its own boards): the board the Pin goes to, one of that account's pinterest.boards from list_channels.",
        +  "pattern": "^\\d{1,30}$",
        +  "type": "string"
        +}
      • addedInput schema / properties / per_channel / items / properties / pinterest_link
        Added value: +{
        +  "description": "Pinterest: where the Pin leads (https). Omitted: cta_url. Either way it becomes a tracked short link; links in the description aren't clickable on Pinterest.",
        +  "maxLength": 2048,
        +  "type": "string"
        +}
      • addedInput schema / properties / per_channel / items / properties / pinterest_title
        Added value: +{
        +  "description": "Pinterest: the Pin's title, up to 100 characters (feeds show about the first 40). The caption is the Pin's description (≤800).",
        +  "maxLength": 100,
        +  "type": "string"
        +}
      • addedInput schema / properties / pinterest_board_id
        Added value: +{
        +  "description": "REQUIRED for a Pinterest account (per_channel, since each account has its own boards): the board the Pin goes to, one of that account's pinterest.boards from list_channels.",
        +  "pattern": "^\\d{1,30}$",
        +  "type": "string"
        +}
      • addedInput schema / properties / pinterest_link
        Added value: +{
        +  "description": "Pinterest: where the Pin leads (https). Omitted: cta_url. Either way it becomes a tracked short link; links in the description aren't clickable on Pinterest.",
        +  "maxLength": 2048,
        +  "type": "string"
        +}
      • addedInput schema / properties / pinterest_title
        Added value: +{
        +  "description": "Pinterest: the Pin's title, up to 100 characters (feeds show about the first 40). The caption is the Pin's description (≤800).",
        +  "maxLength": 100,
        +  "type": "string"
        +}
    • Changedlist_channels1 field changed
      • changedInput schema / properties / network / enum
        Previous value: -[
        -  "FACEBOOK",
        -  "INSTAGRAM",
        -  "LINKEDIN",
        -  "TIKTOK",
        -  "YOUTUBE",
        -  "X",
        -  "BLUESKY",
        -  "TELEGRAM",
        -  "MASTODON",
        -  "THREADS",
        -  "WHATSAPP"
        -]New value: +[
        +  "FACEBOOK",
        +  "INSTAGRAM",
        +  "LINKEDIN",
        +  "TIKTOK",
        +  "YOUTUBE",
        +  "X",
        +  "BLUESKY",
        +  "TELEGRAM",
        +  "MASTODON",
        +  "THREADS",
        +  "PINTEREST",
        +  "WHATSAPP"
        +]
    • Changedlist_posts1 field changed
      • changedInput schema / properties / network / enum
        Previous value: -[
        -  "FACEBOOK",
        -  "INSTAGRAM",
        -  "LINKEDIN",
        -  "TIKTOK",
        -  "YOUTUBE",
        -  "X",
        -  "BLUESKY",
        -  "TELEGRAM",
        -  "MASTODON",
        -  "THREADS",
        -  "WHATSAPP"
        -]New value: +[
        +  "FACEBOOK",
        +  "INSTAGRAM",
        +  "LINKEDIN",
        +  "TIKTOK",
        +  "YOUTUBE",
        +  "X",
        +  "BLUESKY",
        +  "TELEGRAM",
        +  "MASTODON",
        +  "THREADS",
        +  "PINTEREST",
        +  "WHATSAPP"
        +]
    • Changedschedule_post1 field changed
      • changedInput schema / properties / confirm / description
        Previous value: -"Deprecated boolean; does not bypass confirmation. A confirmation_token is required when a schedule goes to more than 10 accounts or starts within 60 minutes. Without it you get needs_confirmation with the dispatch plan; show it to your human, then resend with confirmation_token from the returned plan."New value: +"Deprecated boolean; does not bypass confirmation. A confirmation_token is required when a schedule goes to more than 10 accounts, starts within 60 minutes, or includes a Pinterest account. Without it you get needs_confirmation with the dispatch plan; show it to your human, then resend with confirmation_token from the returned plan."
    • Changedupdate_post9 fields changed
      • changedInput schema / properties / ai_generated / description
        Previous value: -"Made or meaningfully altered with AI. Sent as each network's AI label: Instagram, Facebook Reels, YouTube (altered or synthetic content), TikTok (AI-generated), X (made with AI)."New value: +"Made or meaningfully altered with AI. Sent as each network's AI label: Instagram, Facebook Reels, YouTube (altered or synthetic content), TikTok (AI-generated), X (made with AI), Pinterest (AI-modified disclosure)."
      • changedInput schema / properties / cover_media_id / description
        Previous value: -"Cover image for the post's video: an IMAGE id from upload_media_from_url (not in media_ids). A cover the network refuses never fails the post: the result carries a notice. null removes it. Per network (\"Cover at the start of the video\" is cover_first_frame): Facebook: The image becomes the thumbnail of the video or Reel. Stories have no cover. Instagram: The image becomes the Reel's cover, in the feed and on the profile. Stories have no cover. YouTube: The image becomes the video's thumbnail. YouTube allows this only for phone-verified channels (youtube.com/verify); without that, the video goes up with a thumbnail YouTube picks. X: X has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\". LinkedIn: The image becomes the video's thumbnail. TikTok: TikTok takes no cover image through its API, only a moment of the video, and applies even that only to public posts (a private post shows the first frame). To always show your cover, private posts included, turn on \"Cover at the start of the video\". Bluesky: Bluesky has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\". Telegram: The image becomes the video's cover in the channel. Mastodon: The image is shown on the video on Mastodon until it's played. Threads: Threads has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\"."New value: +"Cover image for the post's video: an IMAGE id from upload_media_from_url (not in media_ids). A cover the network refuses never fails the post: the result carries a notice. null removes it. Per network (\"Cover at the start of the video\" is cover_first_frame): Facebook: The image becomes the thumbnail of the video or Reel. Stories have no cover. Instagram: The image becomes the Reel's cover, in the feed and on the profile. Stories have no cover. YouTube: The image becomes the video's thumbnail. YouTube allows this only for phone-verified channels (youtube.com/verify); without that, the video goes up with a thumbnail YouTube picks. X: X has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\". LinkedIn: The image becomes the video's thumbnail. TikTok: TikTok takes no cover image through its API, only a moment of the video, and applies even that only to public posts (a private post shows the first frame). To always show your cover, private posts included, turn on \"Cover at the start of the video\". Bluesky: Bluesky has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\". Telegram: The image becomes the video's cover in the channel. Mastodon: The image is shown on the video on Mastodon until it's played. Threads: Threads has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\". Pinterest: The image becomes the video Pin's cover on Pinterest."
      • changedInput schema / properties / per_channel / items / properties / ai_generated / description
        Previous value: -"Made or meaningfully altered with AI. Sent as each network's AI label: Instagram, Facebook Reels, YouTube (altered or synthetic content), TikTok (AI-generated), X (made with AI)."New value: +"Made or meaningfully altered with AI. Sent as each network's AI label: Instagram, Facebook Reels, YouTube (altered or synthetic content), TikTok (AI-generated), X (made with AI), Pinterest (AI-modified disclosure)."
      • addedInput schema / properties / per_channel / items / properties / pinterest_board_id
        Added value: +{
        +  "description": "REQUIRED for a Pinterest account (per_channel, since each account has its own boards): the board the Pin goes to, one of that account's pinterest.boards from list_channels.",
        +  "pattern": "^\\d{1,30}$",
        +  "type": "string"
        +}
      • addedInput schema / properties / per_channel / items / properties / pinterest_link
        Added value: +{
        +  "description": "Pinterest: where the Pin leads (https). Omitted: cta_url. Either way it becomes a tracked short link; links in the description aren't clickable on Pinterest.",
        +  "maxLength": 2048,
        +  "type": "string"
        +}
      • addedInput schema / properties / per_channel / items / properties / pinterest_title
        Added value: +{
        +  "description": "Pinterest: the Pin's title, up to 100 characters (feeds show about the first 40). The caption is the Pin's description (≤800).",
        +  "maxLength": 100,
        +  "type": "string"
        +}
      • addedInput schema / properties / pinterest_board_id
        Added value: +{
        +  "description": "REQUIRED for a Pinterest account (per_channel, since each account has its own boards): the board the Pin goes to, one of that account's pinterest.boards from list_channels.",
        +  "pattern": "^\\d{1,30}$",
        +  "type": "string"
        +}
      • addedInput schema / properties / pinterest_link
        Added value: +{
        +  "description": "Pinterest: where the Pin leads (https). Omitted: cta_url. Either way it becomes a tracked short link; links in the description aren't clickable on Pinterest.",
        +  "maxLength": 2048,
        +  "type": "string"
        +}
      • addedInput schema / properties / pinterest_title
        Added value: +{
        +  "description": "Pinterest: the Pin's title, up to 100 characters (feeds show about the first 40). The caption is the Pin's description (≤800).",
        +  "maxLength": 100,
        +  "type": "string"
        +}
    • Changedvalidate_post9 fields changed
      • changedInput schema / properties / ai_generated / description
        Previous value: -"Made or meaningfully altered with AI. Sent as each network's AI label: Instagram, Facebook Reels, YouTube (altered or synthetic content), TikTok (AI-generated), X (made with AI)."New value: +"Made or meaningfully altered with AI. Sent as each network's AI label: Instagram, Facebook Reels, YouTube (altered or synthetic content), TikTok (AI-generated), X (made with AI), Pinterest (AI-modified disclosure)."
      • changedInput schema / properties / cover_media_id / description
        Previous value: -"Cover image for the post's video: an IMAGE id from upload_media_from_url (not in media_ids). A cover the network refuses never fails the post: the result carries a notice. null removes it. Per network (\"Cover at the start of the video\" is cover_first_frame): Facebook: The image becomes the thumbnail of the video or Reel. Stories have no cover. Instagram: The image becomes the Reel's cover, in the feed and on the profile. Stories have no cover. YouTube: The image becomes the video's thumbnail. YouTube allows this only for phone-verified channels (youtube.com/verify); without that, the video goes up with a thumbnail YouTube picks. X: X has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\". LinkedIn: The image becomes the video's thumbnail. TikTok: TikTok takes no cover image through its API, only a moment of the video, and applies even that only to public posts (a private post shows the first frame). To always show your cover, private posts included, turn on \"Cover at the start of the video\". Bluesky: Bluesky has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\". Telegram: The image becomes the video's cover in the channel. Mastodon: The image is shown on the video on Mastodon until it's played. Threads: Threads has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\"."New value: +"Cover image for the post's video: an IMAGE id from upload_media_from_url (not in media_ids). A cover the network refuses never fails the post: the result carries a notice. null removes it. Per network (\"Cover at the start of the video\" is cover_first_frame): Facebook: The image becomes the thumbnail of the video or Reel. Stories have no cover. Instagram: The image becomes the Reel's cover, in the feed and on the profile. Stories have no cover. YouTube: The image becomes the video's thumbnail. YouTube allows this only for phone-verified channels (youtube.com/verify); without that, the video goes up with a thumbnail YouTube picks. X: X has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\". LinkedIn: The image becomes the video's thumbnail. TikTok: TikTok takes no cover image through its API, only a moment of the video, and applies even that only to public posts (a private post shows the first frame). To always show your cover, private posts included, turn on \"Cover at the start of the video\". Bluesky: Bluesky has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\". Telegram: The image becomes the video's cover in the channel. Mastodon: The image is shown on the video on Mastodon until it's played. Threads: Threads has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\". Pinterest: The image becomes the video Pin's cover on Pinterest."
      • changedInput schema / properties / per_channel / items / properties / ai_generated / description
        Previous value: -"Made or meaningfully altered with AI. Sent as each network's AI label: Instagram, Facebook Reels, YouTube (altered or synthetic content), TikTok (AI-generated), X (made with AI)."New value: +"Made or meaningfully altered with AI. Sent as each network's AI label: Instagram, Facebook Reels, YouTube (altered or synthetic content), TikTok (AI-generated), X (made with AI), Pinterest (AI-modified disclosure)."
      • addedInput schema / properties / per_channel / items / properties / pinterest_board_id
        Added value: +{
        +  "description": "REQUIRED for a Pinterest account (per_channel, since each account has its own boards): the board the Pin goes to, one of that account's pinterest.boards from list_channels.",
        +  "pattern": "^\\d{1,30}$",
        +  "type": "string"
        +}
      • addedInput schema / properties / per_channel / items / properties / pinterest_link
        Added value: +{
        +  "description": "Pinterest: where the Pin leads (https). Omitted: cta_url. Either way it becomes a tracked short link; links in the description aren't clickable on Pinterest.",
        +  "maxLength": 2048,
        +  "type": "string"
        +}
      • addedInput schema / properties / per_channel / items / properties / pinterest_title
        Added value: +{
        +  "description": "Pinterest: the Pin's title, up to 100 characters (feeds show about the first 40). The caption is the Pin's description (≤800).",
        +  "maxLength": 100,
        +  "type": "string"
        +}
      • addedInput schema / properties / pinterest_board_id
        Added value: +{
        +  "description": "REQUIRED for a Pinterest account (per_channel, since each account has its own boards): the board the Pin goes to, one of that account's pinterest.boards from list_channels.",
        +  "pattern": "^\\d{1,30}$",
        +  "type": "string"
        +}
      • addedInput schema / properties / pinterest_link
        Added value: +{
        +  "description": "Pinterest: where the Pin leads (https). Omitted: cta_url. Either way it becomes a tracked short link; links in the description aren't clickable on Pinterest.",
        +  "maxLength": 2048,
        +  "type": "string"
        +}
      • addedInput schema / properties / pinterest_title
        Added value: +{
        +  "description": "Pinterest: the Pin's title, up to 100 characters (feeds show about the first 40). The caption is the Pin's description (≤800).",
        +  "maxLength": 100,
        +  "type": "string"
        +}
  3. 5 tool updates
    • Changedcreate_post23 fields changed
      • changedInput schema / properties / alt_texts / description
        Previous value: -"Image descriptions for screen readers, by media id (images in media_ids). Sent to Instagram, Facebook, X, LinkedIn and Bluesky. Stored on the image, so later posts reuse it; an empty string clears it."New value: +"Image descriptions for screen readers, by media id (images in media_ids). Sent to Instagram, Facebook, X, LinkedIn, Bluesky and Mastodon. Stored on the image, so later posts reuse it; an empty string clears it."
      • changedInput schema / properties / caption / description
        Previous value: -"Master text. Goes to every account unless per_channel overrides it. X: 280 characters; Bluesky: 300; Instagram and TikTok: 2,200; Telegram: 4,096 for text, 1,024 under photos, a video or a file."New value: +"Master text. Goes to every account unless per_channel overrides it. X: 280 characters; Bluesky: 300; Mastodon: 500 (links count as 23); Instagram and TikTok: 2,200; Telegram: 4,096 for text, 1,024 under photos, a video or a file."
      • addedInput schema / properties / content_warning
        Added value: +{
        +  "description": "Mastodon: a content warning shown before the post (readers tap to see it; it also hides images). Counts toward the 500 characters.",
        +  "maxLength": 500,
        +  "type": "string"
        +}
      • changedInput schema / properties / cover_media_id / description
        Previous value: -"Cover image for the post's video: an IMAGE id from upload_media_from_url (not in media_ids). A cover the network refuses never fails the post: the result carries a notice. null removes it. Per network (\"Cover at the start of the video\" is cover_first_frame): Facebook: The image becomes the thumbnail of the video or Reel. Stories have no cover. Instagram: The image becomes the Reel's cover, in the feed and on the profile. Stories have no cover. YouTube: The image becomes the video's thumbnail. YouTube allows this only for phone-verified channels (youtube.com/verify); without that, the video goes up with a thumbnail YouTube picks. X: X has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\". LinkedIn: The image becomes the video's thumbnail. TikTok: TikTok takes no cover image through its API, only a moment of the video, and applies even that only to public posts (a private post shows the first frame). To always show your cover, private posts included, turn on \"Cover at the start of the video\". Bluesky: Bluesky has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\". Telegram: The image becomes the video's cover in the channel."New value: +"Cover image for the post's video: an IMAGE id from upload_media_from_url (not in media_ids). A cover the network refuses never fails the post: the result carries a notice. null removes it. Per network (\"Cover at the start of the video\" is cover_first_frame): Facebook: The image becomes the thumbnail of the video or Reel. Stories have no cover. Instagram: The image becomes the Reel's cover, in the feed and on the profile. Stories have no cover. YouTube: The image becomes the video's thumbnail. YouTube allows this only for phone-verified channels (youtube.com/verify); without that, the video goes up with a thumbnail YouTube picks. X: X has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\". LinkedIn: The image becomes the video's thumbnail. TikTok: TikTok takes no cover image through its API, only a moment of the video, and applies even that only to public posts (a private post shows the first frame). To always show your cover, private posts included, turn on \"Cover at the start of the video\". Bluesky: Bluesky has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\". Telegram: The image becomes the video's cover in the channel. Mastodon: The image is shown on the video on Mastodon until it's played. Threads: Threads has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\"."
      • addedInput schema / properties / mastodon_visibility
        Added value: +{
        +  "description": "Mastodon: who sees the post: public (default), unlisted (quiet public: not in public timelines or hashtags) or private (followers only).",
        +  "enum": [
        +    "public",
        +    "unlisted",
        +    "private"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / per_channel / items / properties / content_warning
        Added value: +{
        +  "description": "Mastodon: a content warning shown before the post (readers tap to see it; it also hides images). Counts toward the 500 characters.",
        +  "maxLength": 500,
        +  "type": "string"
        +}
      • addedInput schema / properties / per_channel / items / properties / mastodon_visibility
        Added value: +{
        +  "description": "Mastodon: who sees the post: public (default), unlisted (quiet public: not in public timelines or hashtags) or private (followers only).",
        +  "enum": [
        +    "public",
        +    "unlisted",
        +    "private"
        +  ],
        +  "type": "string"
        +}
      • changedInput schema / properties / per_channel / items / properties / poll / description
        Previous value: -"A poll on X and LinkedIn. A poll post carries no media."New value: +"A poll on X, LinkedIn and Mastodon. A poll post carries no media."
      • changedInput schema / properties / per_channel / items / properties / poll / properties / options / description
        Previous value: -"2–4 answers: X ≤25 characters each, LinkedIn ≤30."New value: +"2–4 answers: X ≤25 characters each, LinkedIn ≤30, Mastodon ≤50."
      • changedInput schema / properties / per_channel / items / properties / poll / properties / options / items / maxLength
        Previous value: -30New value: +50
      • changedInput schema / properties / per_channel / items / properties / poll / properties / question / description
        Previous value: -"LinkedIn only (required there, ≤140). On X the post text is the question."New value: +"LinkedIn only (required there, ≤140). On X and Mastodon the post text is the question."
      • addedInput schema / properties / per_channel / items / properties / post_language
        Added value: +{
        +  "description": "Mastodon: the post's language as an ISO 639-1 code (he, en, es…); omitted = the account's default.",
        +  "pattern": "^[a-z]{2,3}$",
        +  "type": "string"
        +}
      • addedInput schema / properties / per_channel / items / properties / threads_link_card
        Added value: +{
        +  "description": "Threads text post (no media): an https link shown as a card under the text (link_attachment). Without it, Threads previews the first link in the text.",
        +  "maxLength": 2048,
        +  "type": "string"
        +}
      • addedInput schema / properties / per_channel / items / properties / threads_reply_control
        Added value: +{
        +  "description": "Threads: who can reply: everyone (default), accounts_you_follow, mentioned_only or followers_only.",
        +  "enum": [
        +    "everyone",
        +    "accounts_you_follow",
        +    "mentioned_only",
        +    "followers_only"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / per_channel / items / properties / threads_topic
        Added value: +{
        +  "description": "Threads: the post's topic, 1–50 characters, no period or ampersand (e.g. Recipes).",
        +  "maxLength": 50,
        +  "type": "string"
        +}
      • changedInput schema / properties / poll / description
        Previous value: -"A poll on X and LinkedIn. A poll post carries no media."New value: +"A poll on X, LinkedIn and Mastodon. A poll post carries no media."
      • changedInput schema / properties / poll / properties / options / description
        Previous value: -"2–4 answers: X ≤25 characters each, LinkedIn ≤30."New value: +"2–4 answers: X ≤25 characters each, LinkedIn ≤30, Mastodon ≤50."
      • changedInput schema / properties / poll / properties / options / items / maxLength
        Previous value: -30New value: +50
      • changedInput schema / properties / poll / properties / question / description
        Previous value: -"LinkedIn only (required there, ≤140). On X the post text is the question."New value: +"LinkedIn only (required there, ≤140). On X and Mastodon the post text is the question."
      • addedInput schema / properties / post_language
        Added value: +{
        +  "description": "Mastodon: the post's language as an ISO 639-1 code (he, en, es…); omitted = the account's default.",
        +  "pattern": "^[a-z]{2,3}$",
        +  "type": "string"
        +}
      • addedInput schema / properties / threads_link_card
        Added value: +{
        +  "description": "Threads text post (no media): an https link shown as a card under the text (link_attachment). Without it, Threads previews the first link in the text.",
        +  "maxLength": 2048,
        +  "type": "string"
        +}
      • addedInput schema / properties / threads_reply_control
        Added value: +{
        +  "description": "Threads: who can reply: everyone (default), accounts_you_follow, mentioned_only or followers_only.",
        +  "enum": [
        +    "everyone",
        +    "accounts_you_follow",
        +    "mentioned_only",
        +    "followers_only"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / threads_topic
        Added value: +{
        +  "description": "Threads: the post's topic, 1–50 characters, no period or ampersand (e.g. Recipes).",
        +  "maxLength": 50,
        +  "type": "string"
        +}
    • Changedlist_channels1 field changed
      • changedInput schema / properties / network / enum
        Previous value: -[
        -  "FACEBOOK",
        -  "INSTAGRAM",
        -  "LINKEDIN",
        -  "TIKTOK",
        -  "YOUTUBE",
        -  "X",
        -  "BLUESKY",
        -  "TELEGRAM",
        -  "WHATSAPP"
        -]New value: +[
        +  "FACEBOOK",
        +  "INSTAGRAM",
        +  "LINKEDIN",
        +  "TIKTOK",
        +  "YOUTUBE",
        +  "X",
        +  "BLUESKY",
        +  "TELEGRAM",
        +  "MASTODON",
        +  "THREADS",
        +  "WHATSAPP"
        +]
    • Changedlist_posts1 field changed
      • changedInput schema / properties / network / enum
        Previous value: -[
        -  "FACEBOOK",
        -  "INSTAGRAM",
        -  "LINKEDIN",
        -  "TIKTOK",
        -  "YOUTUBE",
        -  "X",
        -  "BLUESKY",
        -  "TELEGRAM",
        -  "WHATSAPP"
        -]New value: +[
        +  "FACEBOOK",
        +  "INSTAGRAM",
        +  "LINKEDIN",
        +  "TIKTOK",
        +  "YOUTUBE",
        +  "X",
        +  "BLUESKY",
        +  "TELEGRAM",
        +  "MASTODON",
        +  "THREADS",
        +  "WHATSAPP"
        +]
    • Changedupdate_post23 fields changed
      • changedInput schema / properties / alt_texts / description
        Previous value: -"Image descriptions for screen readers, by media id (images in media_ids). Sent to Instagram, Facebook, X, LinkedIn and Bluesky. Stored on the image, so later posts reuse it; an empty string clears it."New value: +"Image descriptions for screen readers, by media id (images in media_ids). Sent to Instagram, Facebook, X, LinkedIn, Bluesky and Mastodon. Stored on the image, so later posts reuse it; an empty string clears it."
      • changedInput schema / properties / caption / description
        Previous value: -"Master text. Goes to every account unless per_channel overrides it. X: 280 characters; Bluesky: 300; Instagram and TikTok: 2,200; Telegram: 4,096 for text, 1,024 under photos, a video or a file."New value: +"Master text. Goes to every account unless per_channel overrides it. X: 280 characters; Bluesky: 300; Mastodon: 500 (links count as 23); Instagram and TikTok: 2,200; Telegram: 4,096 for text, 1,024 under photos, a video or a file."
      • addedInput schema / properties / content_warning
        Added value: +{
        +  "description": "Mastodon: a content warning shown before the post (readers tap to see it; it also hides images). Counts toward the 500 characters.",
        +  "maxLength": 500,
        +  "type": "string"
        +}
      • changedInput schema / properties / cover_media_id / description
        Previous value: -"Cover image for the post's video: an IMAGE id from upload_media_from_url (not in media_ids). A cover the network refuses never fails the post: the result carries a notice. null removes it. Per network (\"Cover at the start of the video\" is cover_first_frame): Facebook: The image becomes the thumbnail of the video or Reel. Stories have no cover. Instagram: The image becomes the Reel's cover, in the feed and on the profile. Stories have no cover. YouTube: The image becomes the video's thumbnail. YouTube allows this only for phone-verified channels (youtube.com/verify); without that, the video goes up with a thumbnail YouTube picks. X: X has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\". LinkedIn: The image becomes the video's thumbnail. TikTok: TikTok takes no cover image through its API, only a moment of the video, and applies even that only to public posts (a private post shows the first frame). To always show your cover, private posts included, turn on \"Cover at the start of the video\". Bluesky: Bluesky has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\". Telegram: The image becomes the video's cover in the channel."New value: +"Cover image for the post's video: an IMAGE id from upload_media_from_url (not in media_ids). A cover the network refuses never fails the post: the result carries a notice. null removes it. Per network (\"Cover at the start of the video\" is cover_first_frame): Facebook: The image becomes the thumbnail of the video or Reel. Stories have no cover. Instagram: The image becomes the Reel's cover, in the feed and on the profile. Stories have no cover. YouTube: The image becomes the video's thumbnail. YouTube allows this only for phone-verified channels (youtube.com/verify); without that, the video goes up with a thumbnail YouTube picks. X: X has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\". LinkedIn: The image becomes the video's thumbnail. TikTok: TikTok takes no cover image through its API, only a moment of the video, and applies even that only to public posts (a private post shows the first frame). To always show your cover, private posts included, turn on \"Cover at the start of the video\". Bluesky: Bluesky has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\". Telegram: The image becomes the video's cover in the channel. Mastodon: The image is shown on the video on Mastodon until it's played. Threads: Threads has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\"."
      • addedInput schema / properties / mastodon_visibility
        Added value: +{
        +  "description": "Mastodon: who sees the post: public (default), unlisted (quiet public: not in public timelines or hashtags) or private (followers only).",
        +  "enum": [
        +    "public",
        +    "unlisted",
        +    "private"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / per_channel / items / properties / content_warning
        Added value: +{
        +  "description": "Mastodon: a content warning shown before the post (readers tap to see it; it also hides images). Counts toward the 500 characters.",
        +  "maxLength": 500,
        +  "type": "string"
        +}
      • addedInput schema / properties / per_channel / items / properties / mastodon_visibility
        Added value: +{
        +  "description": "Mastodon: who sees the post: public (default), unlisted (quiet public: not in public timelines or hashtags) or private (followers only).",
        +  "enum": [
        +    "public",
        +    "unlisted",
        +    "private"
        +  ],
        +  "type": "string"
        +}
      • changedInput schema / properties / per_channel / items / properties / poll / description
        Previous value: -"A poll on X and LinkedIn. A poll post carries no media."New value: +"A poll on X, LinkedIn and Mastodon. A poll post carries no media."
      • changedInput schema / properties / per_channel / items / properties / poll / properties / options / description
        Previous value: -"2–4 answers: X ≤25 characters each, LinkedIn ≤30."New value: +"2–4 answers: X ≤25 characters each, LinkedIn ≤30, Mastodon ≤50."
      • changedInput schema / properties / per_channel / items / properties / poll / properties / options / items / maxLength
        Previous value: -30New value: +50
      • changedInput schema / properties / per_channel / items / properties / poll / properties / question / description
        Previous value: -"LinkedIn only (required there, ≤140). On X the post text is the question."New value: +"LinkedIn only (required there, ≤140). On X and Mastodon the post text is the question."
      • addedInput schema / properties / per_channel / items / properties / post_language
        Added value: +{
        +  "description": "Mastodon: the post's language as an ISO 639-1 code (he, en, es…); omitted = the account's default.",
        +  "pattern": "^[a-z]{2,3}$",
        +  "type": "string"
        +}
      • addedInput schema / properties / per_channel / items / properties / threads_link_card
        Added value: +{
        +  "description": "Threads text post (no media): an https link shown as a card under the text (link_attachment). Without it, Threads previews the first link in the text.",
        +  "maxLength": 2048,
        +  "type": "string"
        +}
      • addedInput schema / properties / per_channel / items / properties / threads_reply_control
        Added value: +{
        +  "description": "Threads: who can reply: everyone (default), accounts_you_follow, mentioned_only or followers_only.",
        +  "enum": [
        +    "everyone",
        +    "accounts_you_follow",
        +    "mentioned_only",
        +    "followers_only"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / per_channel / items / properties / threads_topic
        Added value: +{
        +  "description": "Threads: the post's topic, 1–50 characters, no period or ampersand (e.g. Recipes).",
        +  "maxLength": 50,
        +  "type": "string"
        +}
      • changedInput schema / properties / poll / description
        Previous value: -"A poll on X and LinkedIn. A poll post carries no media."New value: +"A poll on X, LinkedIn and Mastodon. A poll post carries no media."
      • changedInput schema / properties / poll / properties / options / description
        Previous value: -"2–4 answers: X ≤25 characters each, LinkedIn ≤30."New value: +"2–4 answers: X ≤25 characters each, LinkedIn ≤30, Mastodon ≤50."
      • changedInput schema / properties / poll / properties / options / items / maxLength
        Previous value: -30New value: +50
      • changedInput schema / properties / poll / properties / question / description
        Previous value: -"LinkedIn only (required there, ≤140). On X the post text is the question."New value: +"LinkedIn only (required there, ≤140). On X and Mastodon the post text is the question."
      • addedInput schema / properties / post_language
        Added value: +{
        +  "description": "Mastodon: the post's language as an ISO 639-1 code (he, en, es…); omitted = the account's default.",
        +  "pattern": "^[a-z]{2,3}$",
        +  "type": "string"
        +}
      • addedInput schema / properties / threads_link_card
        Added value: +{
        +  "description": "Threads text post (no media): an https link shown as a card under the text (link_attachment). Without it, Threads previews the first link in the text.",
        +  "maxLength": 2048,
        +  "type": "string"
        +}
      • addedInput schema / properties / threads_reply_control
        Added value: +{
        +  "description": "Threads: who can reply: everyone (default), accounts_you_follow, mentioned_only or followers_only.",
        +  "enum": [
        +    "everyone",
        +    "accounts_you_follow",
        +    "mentioned_only",
        +    "followers_only"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / threads_topic
        Added value: +{
        +  "description": "Threads: the post's topic, 1–50 characters, no period or ampersand (e.g. Recipes).",
        +  "maxLength": 50,
        +  "type": "string"
        +}
    • Changedvalidate_post23 fields changed
      • changedInput schema / properties / alt_texts / description
        Previous value: -"Image descriptions for screen readers, by media id (images in media_ids). Sent to Instagram, Facebook, X, LinkedIn and Bluesky. Stored on the image, so later posts reuse it; an empty string clears it."New value: +"Image descriptions for screen readers, by media id (images in media_ids). Sent to Instagram, Facebook, X, LinkedIn, Bluesky and Mastodon. Stored on the image, so later posts reuse it; an empty string clears it."
      • changedInput schema / properties / caption / description
        Previous value: -"Master text. Goes to every account unless per_channel overrides it. X: 280 characters; Bluesky: 300; Instagram and TikTok: 2,200; Telegram: 4,096 for text, 1,024 under photos, a video or a file."New value: +"Master text. Goes to every account unless per_channel overrides it. X: 280 characters; Bluesky: 300; Mastodon: 500 (links count as 23); Instagram and TikTok: 2,200; Telegram: 4,096 for text, 1,024 under photos, a video or a file."
      • addedInput schema / properties / content_warning
        Added value: +{
        +  "description": "Mastodon: a content warning shown before the post (readers tap to see it; it also hides images). Counts toward the 500 characters.",
        +  "maxLength": 500,
        +  "type": "string"
        +}
      • changedInput schema / properties / cover_media_id / description
        Previous value: -"Cover image for the post's video: an IMAGE id from upload_media_from_url (not in media_ids). A cover the network refuses never fails the post: the result carries a notice. null removes it. Per network (\"Cover at the start of the video\" is cover_first_frame): Facebook: The image becomes the thumbnail of the video or Reel. Stories have no cover. Instagram: The image becomes the Reel's cover, in the feed and on the profile. Stories have no cover. YouTube: The image becomes the video's thumbnail. YouTube allows this only for phone-verified channels (youtube.com/verify); without that, the video goes up with a thumbnail YouTube picks. X: X has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\". LinkedIn: The image becomes the video's thumbnail. TikTok: TikTok takes no cover image through its API, only a moment of the video, and applies even that only to public posts (a private post shows the first frame). To always show your cover, private posts included, turn on \"Cover at the start of the video\". Bluesky: Bluesky has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\". Telegram: The image becomes the video's cover in the channel."New value: +"Cover image for the post's video: an IMAGE id from upload_media_from_url (not in media_ids). A cover the network refuses never fails the post: the result carries a notice. null removes it. Per network (\"Cover at the start of the video\" is cover_first_frame): Facebook: The image becomes the thumbnail of the video or Reel. Stories have no cover. Instagram: The image becomes the Reel's cover, in the feed and on the profile. Stories have no cover. YouTube: The image becomes the video's thumbnail. YouTube allows this only for phone-verified channels (youtube.com/verify); without that, the video goes up with a thumbnail YouTube picks. X: X has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\". LinkedIn: The image becomes the video's thumbnail. TikTok: TikTok takes no cover image through its API, only a moment of the video, and applies even that only to public posts (a private post shows the first frame). To always show your cover, private posts included, turn on \"Cover at the start of the video\". Bluesky: Bluesky has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\". Telegram: The image becomes the video's cover in the channel. Mastodon: The image is shown on the video on Mastodon until it's played. Threads: Threads has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\"."
      • addedInput schema / properties / mastodon_visibility
        Added value: +{
        +  "description": "Mastodon: who sees the post: public (default), unlisted (quiet public: not in public timelines or hashtags) or private (followers only).",
        +  "enum": [
        +    "public",
        +    "unlisted",
        +    "private"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / per_channel / items / properties / content_warning
        Added value: +{
        +  "description": "Mastodon: a content warning shown before the post (readers tap to see it; it also hides images). Counts toward the 500 characters.",
        +  "maxLength": 500,
        +  "type": "string"
        +}
      • addedInput schema / properties / per_channel / items / properties / mastodon_visibility
        Added value: +{
        +  "description": "Mastodon: who sees the post: public (default), unlisted (quiet public: not in public timelines or hashtags) or private (followers only).",
        +  "enum": [
        +    "public",
        +    "unlisted",
        +    "private"
        +  ],
        +  "type": "string"
        +}
      • changedInput schema / properties / per_channel / items / properties / poll / description
        Previous value: -"A poll on X and LinkedIn. A poll post carries no media."New value: +"A poll on X, LinkedIn and Mastodon. A poll post carries no media."
      • changedInput schema / properties / per_channel / items / properties / poll / properties / options / description
        Previous value: -"2–4 answers: X ≤25 characters each, LinkedIn ≤30."New value: +"2–4 answers: X ≤25 characters each, LinkedIn ≤30, Mastodon ≤50."
      • changedInput schema / properties / per_channel / items / properties / poll / properties / options / items / maxLength
        Previous value: -30New value: +50
      • changedInput schema / properties / per_channel / items / properties / poll / properties / question / description
        Previous value: -"LinkedIn only (required there, ≤140). On X the post text is the question."New value: +"LinkedIn only (required there, ≤140). On X and Mastodon the post text is the question."
      • addedInput schema / properties / per_channel / items / properties / post_language
        Added value: +{
        +  "description": "Mastodon: the post's language as an ISO 639-1 code (he, en, es…); omitted = the account's default.",
        +  "pattern": "^[a-z]{2,3}$",
        +  "type": "string"
        +}
      • addedInput schema / properties / per_channel / items / properties / threads_link_card
        Added value: +{
        +  "description": "Threads text post (no media): an https link shown as a card under the text (link_attachment). Without it, Threads previews the first link in the text.",
        +  "maxLength": 2048,
        +  "type": "string"
        +}
      • addedInput schema / properties / per_channel / items / properties / threads_reply_control
        Added value: +{
        +  "description": "Threads: who can reply: everyone (default), accounts_you_follow, mentioned_only or followers_only.",
        +  "enum": [
        +    "everyone",
        +    "accounts_you_follow",
        +    "mentioned_only",
        +    "followers_only"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / per_channel / items / properties / threads_topic
        Added value: +{
        +  "description": "Threads: the post's topic, 1–50 characters, no period or ampersand (e.g. Recipes).",
        +  "maxLength": 50,
        +  "type": "string"
        +}
      • changedInput schema / properties / poll / description
        Previous value: -"A poll on X and LinkedIn. A poll post carries no media."New value: +"A poll on X, LinkedIn and Mastodon. A poll post carries no media."
      • changedInput schema / properties / poll / properties / options / description
        Previous value: -"2–4 answers: X ≤25 characters each, LinkedIn ≤30."New value: +"2–4 answers: X ≤25 characters each, LinkedIn ≤30, Mastodon ≤50."
      • changedInput schema / properties / poll / properties / options / items / maxLength
        Previous value: -30New value: +50
      • changedInput schema / properties / poll / properties / question / description
        Previous value: -"LinkedIn only (required there, ≤140). On X the post text is the question."New value: +"LinkedIn only (required there, ≤140). On X and Mastodon the post text is the question."
      • addedInput schema / properties / post_language
        Added value: +{
        +  "description": "Mastodon: the post's language as an ISO 639-1 code (he, en, es…); omitted = the account's default.",
        +  "pattern": "^[a-z]{2,3}$",
        +  "type": "string"
        +}
      • addedInput schema / properties / threads_link_card
        Added value: +{
        +  "description": "Threads text post (no media): an https link shown as a card under the text (link_attachment). Without it, Threads previews the first link in the text.",
        +  "maxLength": 2048,
        +  "type": "string"
        +}
      • addedInput schema / properties / threads_reply_control
        Added value: +{
        +  "description": "Threads: who can reply: everyone (default), accounts_you_follow, mentioned_only or followers_only.",
        +  "enum": [
        +    "everyone",
        +    "accounts_you_follow",
        +    "mentioned_only",
        +    "followers_only"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / threads_topic
        Added value: +{
        +  "description": "Threads: the post's topic, 1–50 characters, no period or ampersand (e.g. Recipes).",
        +  "maxLength": 50,
        +  "type": "string"
        +}
  4. 5 tool updates
    • Changedcreate_post4 fields changed
      • changedInput schema / properties / caption / description
        Previous value: -"Master text. Goes to every account unless per_channel overrides it. X: 280 characters; Bluesky: 300; Instagram and TikTok: 2,200."New value: +"Master text. Goes to every account unless per_channel overrides it. X: 280 characters; Bluesky: 300; Instagram and TikTok: 2,200; Telegram: 4,096 for text, 1,024 under photos, a video or a file."
      • changedInput schema / properties / cover_media_id / description
        Previous value: -"Cover image for the post's video: an IMAGE id from upload_media_from_url (not in media_ids). A cover the network refuses never fails the post: the result carries a notice. null removes it. Per network (\"Cover at the start of the video\" is cover_first_frame): Facebook: The image becomes the thumbnail of the video or Reel. Stories have no cover. Instagram: The image becomes the Reel's cover, in the feed and on the profile. Stories have no cover. YouTube: The image becomes the video's thumbnail. YouTube allows this only for phone-verified channels (youtube.com/verify); without that, the video goes up with a thumbnail YouTube picks. X: X has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\". LinkedIn: The image becomes the video's thumbnail. TikTok: TikTok takes no cover image through its API, only a moment of the video, and applies even that only to public posts (a private post shows the first frame). To always show your cover, private posts included, turn on \"Cover at the start of the video\". Bluesky: Bluesky has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\"."New value: +"Cover image for the post's video: an IMAGE id from upload_media_from_url (not in media_ids). A cover the network refuses never fails the post: the result carries a notice. null removes it. Per network (\"Cover at the start of the video\" is cover_first_frame): Facebook: The image becomes the thumbnail of the video or Reel. Stories have no cover. Instagram: The image becomes the Reel's cover, in the feed and on the profile. Stories have no cover. YouTube: The image becomes the video's thumbnail. YouTube allows this only for phone-verified channels (youtube.com/verify); without that, the video goes up with a thumbnail YouTube picks. X: X has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\". LinkedIn: The image becomes the video's thumbnail. TikTok: TikTok takes no cover image through its API, only a moment of the video, and applies even that only to public posts (a private post shows the first frame). To always show your cover, private posts included, turn on \"Cover at the start of the video\". Bluesky: Bluesky has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\". Telegram: The image becomes the video's cover in the channel."
      • addedInput schema / properties / per_channel / items / properties / telegram_silent
        Added value: +{
        +  "description": "Telegram: send without a sound, so channel subscribers get no notification.",
        +  "type": "boolean"
        +}
      • addedInput schema / properties / telegram_silent
        Added value: +{
        +  "description": "Telegram: send without a sound, so channel subscribers get no notification.",
        +  "type": "boolean"
        +}
    • Changedlist_channels1 field changed
      • changedInput schema / properties / network / enum
        Previous value: -[
        -  "FACEBOOK",
        -  "INSTAGRAM",
        -  "LINKEDIN",
        -  "TIKTOK",
        -  "YOUTUBE",
        -  "X",
        -  "BLUESKY",
        -  "WHATSAPP"
        -]New value: +[
        +  "FACEBOOK",
        +  "INSTAGRAM",
        +  "LINKEDIN",
        +  "TIKTOK",
        +  "YOUTUBE",
        +  "X",
        +  "BLUESKY",
        +  "TELEGRAM",
        +  "WHATSAPP"
        +]
    • Changedlist_posts1 field changed
      • changedInput schema / properties / network / enum
        Previous value: -[
        -  "FACEBOOK",
        -  "INSTAGRAM",
        -  "LINKEDIN",
        -  "TIKTOK",
        -  "YOUTUBE",
        -  "X",
        -  "BLUESKY",
        -  "WHATSAPP"
        -]New value: +[
        +  "FACEBOOK",
        +  "INSTAGRAM",
        +  "LINKEDIN",
        +  "TIKTOK",
        +  "YOUTUBE",
        +  "X",
        +  "BLUESKY",
        +  "TELEGRAM",
        +  "WHATSAPP"
        +]
    • Changedupdate_post4 fields changed
      • changedInput schema / properties / caption / description
        Previous value: -"Master text. Goes to every account unless per_channel overrides it. X: 280 characters; Bluesky: 300; Instagram and TikTok: 2,200."New value: +"Master text. Goes to every account unless per_channel overrides it. X: 280 characters; Bluesky: 300; Instagram and TikTok: 2,200; Telegram: 4,096 for text, 1,024 under photos, a video or a file."
      • changedInput schema / properties / cover_media_id / description
        Previous value: -"Cover image for the post's video: an IMAGE id from upload_media_from_url (not in media_ids). A cover the network refuses never fails the post: the result carries a notice. null removes it. Per network (\"Cover at the start of the video\" is cover_first_frame): Facebook: The image becomes the thumbnail of the video or Reel. Stories have no cover. Instagram: The image becomes the Reel's cover, in the feed and on the profile. Stories have no cover. YouTube: The image becomes the video's thumbnail. YouTube allows this only for phone-verified channels (youtube.com/verify); without that, the video goes up with a thumbnail YouTube picks. X: X has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\". LinkedIn: The image becomes the video's thumbnail. TikTok: TikTok takes no cover image through its API, only a moment of the video, and applies even that only to public posts (a private post shows the first frame). To always show your cover, private posts included, turn on \"Cover at the start of the video\". Bluesky: Bluesky has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\"."New value: +"Cover image for the post's video: an IMAGE id from upload_media_from_url (not in media_ids). A cover the network refuses never fails the post: the result carries a notice. null removes it. Per network (\"Cover at the start of the video\" is cover_first_frame): Facebook: The image becomes the thumbnail of the video or Reel. Stories have no cover. Instagram: The image becomes the Reel's cover, in the feed and on the profile. Stories have no cover. YouTube: The image becomes the video's thumbnail. YouTube allows this only for phone-verified channels (youtube.com/verify); without that, the video goes up with a thumbnail YouTube picks. X: X has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\". LinkedIn: The image becomes the video's thumbnail. TikTok: TikTok takes no cover image through its API, only a moment of the video, and applies even that only to public posts (a private post shows the first frame). To always show your cover, private posts included, turn on \"Cover at the start of the video\". Bluesky: Bluesky has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\". Telegram: The image becomes the video's cover in the channel."
      • addedInput schema / properties / per_channel / items / properties / telegram_silent
        Added value: +{
        +  "description": "Telegram: send without a sound, so channel subscribers get no notification.",
        +  "type": "boolean"
        +}
      • addedInput schema / properties / telegram_silent
        Added value: +{
        +  "description": "Telegram: send without a sound, so channel subscribers get no notification.",
        +  "type": "boolean"
        +}
    • Changedvalidate_post4 fields changed
      • changedInput schema / properties / caption / description
        Previous value: -"Master text. Goes to every account unless per_channel overrides it. X: 280 characters; Bluesky: 300; Instagram and TikTok: 2,200."New value: +"Master text. Goes to every account unless per_channel overrides it. X: 280 characters; Bluesky: 300; Instagram and TikTok: 2,200; Telegram: 4,096 for text, 1,024 under photos, a video or a file."
      • changedInput schema / properties / cover_media_id / description
        Previous value: -"Cover image for the post's video: an IMAGE id from upload_media_from_url (not in media_ids). A cover the network refuses never fails the post: the result carries a notice. null removes it. Per network (\"Cover at the start of the video\" is cover_first_frame): Facebook: The image becomes the thumbnail of the video or Reel. Stories have no cover. Instagram: The image becomes the Reel's cover, in the feed and on the profile. Stories have no cover. YouTube: The image becomes the video's thumbnail. YouTube allows this only for phone-verified channels (youtube.com/verify); without that, the video goes up with a thumbnail YouTube picks. X: X has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\". LinkedIn: The image becomes the video's thumbnail. TikTok: TikTok takes no cover image through its API, only a moment of the video, and applies even that only to public posts (a private post shows the first frame). To always show your cover, private posts included, turn on \"Cover at the start of the video\". Bluesky: Bluesky has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\"."New value: +"Cover image for the post's video: an IMAGE id from upload_media_from_url (not in media_ids). A cover the network refuses never fails the post: the result carries a notice. null removes it. Per network (\"Cover at the start of the video\" is cover_first_frame): Facebook: The image becomes the thumbnail of the video or Reel. Stories have no cover. Instagram: The image becomes the Reel's cover, in the feed and on the profile. Stories have no cover. YouTube: The image becomes the video's thumbnail. YouTube allows this only for phone-verified channels (youtube.com/verify); without that, the video goes up with a thumbnail YouTube picks. X: X has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\". LinkedIn: The image becomes the video's thumbnail. TikTok: TikTok takes no cover image through its API, only a moment of the video, and applies even that only to public posts (a private post shows the first frame). To always show your cover, private posts included, turn on \"Cover at the start of the video\". Bluesky: Bluesky has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\". Telegram: The image becomes the video's cover in the channel."
      • addedInput schema / properties / per_channel / items / properties / telegram_silent
        Added value: +{
        +  "description": "Telegram: send without a sound, so channel subscribers get no notification.",
        +  "type": "boolean"
        +}
      • addedInput schema / properties / telegram_silent
        Added value: +{
        +  "description": "Telegram: send without a sound, so channel subscribers get no notification.",
        +  "type": "boolean"
        +}
  5. 5 tool updates
    • Changedcreate_post4 fields changed
      • changedInput schema / properties / alt_texts / description
        Previous value: -"Image descriptions for screen readers, by media id (images in media_ids). Sent to Instagram, Facebook, X and LinkedIn. Stored on the image, so later posts reuse it; an empty string clears it."New value: +"Image descriptions for screen readers, by media id (images in media_ids). Sent to Instagram, Facebook, X, LinkedIn and Bluesky. Stored on the image, so later posts reuse it; an empty string clears it."
      • changedInput schema / properties / caption / description
        Previous value: -"Master text. Goes to every account unless per_channel overrides it. X: 280 characters; Instagram and TikTok: 2,200."New value: +"Master text. Goes to every account unless per_channel overrides it. X: 280 characters; Bluesky: 300; Instagram and TikTok: 2,200."
      • changedInput schema / properties / cover_first_frame / description
        Previous value: -"Put the cover image (cover_media_id) at the start of the video, as its first two frames (~1/15 s), so networks that show the video's first frame show your cover: true = only where the network can't take a cover image (TikTok, X, Stories), \"all\" = on every network, false = never. The original video isn't changed; Shager publishes a copy. Default when omitted: true if the post has a cover and goes to TikTok or X, else false."New value: +"Put the cover image (cover_media_id) at the start of the video, as its first two frames (~1/15 s), so networks that show the video's first frame show your cover: true = only where the network can't take a cover image (TikTok, X, Bluesky, Stories), \"all\" = on every network, false = never. The original video isn't changed; Shager publishes a copy. Default when omitted: true if the post has a cover and goes to TikTok, X or Bluesky, else false."
      • changedInput schema / properties / cover_media_id / description
        Previous value: -"Cover image for the post's video: an IMAGE id from upload_media_from_url (not in media_ids). A cover the network refuses never fails the post: the result carries a notice. null removes it. Per network (\"Cover at the start of the video\" is cover_first_frame): Facebook: The image becomes the thumbnail of the video or Reel. Stories have no cover. Instagram: The image becomes the Reel's cover, in the feed and on the profile. Stories have no cover. YouTube: The image becomes the video's thumbnail. YouTube allows this only for phone-verified channels (youtube.com/verify); without that, the video goes up with a thumbnail YouTube picks. X: X has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\". LinkedIn: The image becomes the video's thumbnail. TikTok: TikTok takes no cover image through its API, only a moment of the video, and applies even that only to public posts (a private post shows the first frame). To always show your cover, private posts included, turn on \"Cover at the start of the video\"."New value: +"Cover image for the post's video: an IMAGE id from upload_media_from_url (not in media_ids). A cover the network refuses never fails the post: the result carries a notice. null removes it. Per network (\"Cover at the start of the video\" is cover_first_frame): Facebook: The image becomes the thumbnail of the video or Reel. Stories have no cover. Instagram: The image becomes the Reel's cover, in the feed and on the profile. Stories have no cover. YouTube: The image becomes the video's thumbnail. YouTube allows this only for phone-verified channels (youtube.com/verify); without that, the video goes up with a thumbnail YouTube picks. X: X has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\". LinkedIn: The image becomes the video's thumbnail. TikTok: TikTok takes no cover image through its API, only a moment of the video, and applies even that only to public posts (a private post shows the first frame). To always show your cover, private posts included, turn on \"Cover at the start of the video\". Bluesky: Bluesky has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\"."
    • Changedlist_channels1 field changed
      • changedInput schema / properties / network / enum
        Previous value: -[
        -  "FACEBOOK",
        -  "INSTAGRAM",
        -  "LINKEDIN",
        -  "TIKTOK",
        -  "YOUTUBE",
        -  "X",
        -  "WHATSAPP"
        -]New value: +[
        +  "FACEBOOK",
        +  "INSTAGRAM",
        +  "LINKEDIN",
        +  "TIKTOK",
        +  "YOUTUBE",
        +  "X",
        +  "BLUESKY",
        +  "WHATSAPP"
        +]
    • Changedlist_posts1 field changed
      • changedInput schema / properties / network / enum
        Previous value: -[
        -  "FACEBOOK",
        -  "INSTAGRAM",
        -  "LINKEDIN",
        -  "TIKTOK",
        -  "YOUTUBE",
        -  "X",
        -  "WHATSAPP"
        -]New value: +[
        +  "FACEBOOK",
        +  "INSTAGRAM",
        +  "LINKEDIN",
        +  "TIKTOK",
        +  "YOUTUBE",
        +  "X",
        +  "BLUESKY",
        +  "WHATSAPP"
        +]
    • Changedupdate_post4 fields changed
      • changedInput schema / properties / alt_texts / description
        Previous value: -"Image descriptions for screen readers, by media id (images in media_ids). Sent to Instagram, Facebook, X and LinkedIn. Stored on the image, so later posts reuse it; an empty string clears it."New value: +"Image descriptions for screen readers, by media id (images in media_ids). Sent to Instagram, Facebook, X, LinkedIn and Bluesky. Stored on the image, so later posts reuse it; an empty string clears it."
      • changedInput schema / properties / caption / description
        Previous value: -"Master text. Goes to every account unless per_channel overrides it. X: 280 characters; Instagram and TikTok: 2,200."New value: +"Master text. Goes to every account unless per_channel overrides it. X: 280 characters; Bluesky: 300; Instagram and TikTok: 2,200."
      • changedInput schema / properties / cover_first_frame / description
        Previous value: -"Put the cover image (cover_media_id) at the start of the video, as its first two frames (~1/15 s), so networks that show the video's first frame show your cover: true = only where the network can't take a cover image (TikTok, X, Stories), \"all\" = on every network, false = never. The original video isn't changed; Shager publishes a copy. Default when omitted: true if the post has a cover and goes to TikTok or X, else false."New value: +"Put the cover image (cover_media_id) at the start of the video, as its first two frames (~1/15 s), so networks that show the video's first frame show your cover: true = only where the network can't take a cover image (TikTok, X, Bluesky, Stories), \"all\" = on every network, false = never. The original video isn't changed; Shager publishes a copy. Default when omitted: true if the post has a cover and goes to TikTok, X or Bluesky, else false."
      • changedInput schema / properties / cover_media_id / description
        Previous value: -"Cover image for the post's video: an IMAGE id from upload_media_from_url (not in media_ids). A cover the network refuses never fails the post: the result carries a notice. null removes it. Per network (\"Cover at the start of the video\" is cover_first_frame): Facebook: The image becomes the thumbnail of the video or Reel. Stories have no cover. Instagram: The image becomes the Reel's cover, in the feed and on the profile. Stories have no cover. YouTube: The image becomes the video's thumbnail. YouTube allows this only for phone-verified channels (youtube.com/verify); without that, the video goes up with a thumbnail YouTube picks. X: X has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\". LinkedIn: The image becomes the video's thumbnail. TikTok: TikTok takes no cover image through its API, only a moment of the video, and applies even that only to public posts (a private post shows the first frame). To always show your cover, private posts included, turn on \"Cover at the start of the video\"."New value: +"Cover image for the post's video: an IMAGE id from upload_media_from_url (not in media_ids). A cover the network refuses never fails the post: the result carries a notice. null removes it. Per network (\"Cover at the start of the video\" is cover_first_frame): Facebook: The image becomes the thumbnail of the video or Reel. Stories have no cover. Instagram: The image becomes the Reel's cover, in the feed and on the profile. Stories have no cover. YouTube: The image becomes the video's thumbnail. YouTube allows this only for phone-verified channels (youtube.com/verify); without that, the video goes up with a thumbnail YouTube picks. X: X has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\". LinkedIn: The image becomes the video's thumbnail. TikTok: TikTok takes no cover image through its API, only a moment of the video, and applies even that only to public posts (a private post shows the first frame). To always show your cover, private posts included, turn on \"Cover at the start of the video\". Bluesky: Bluesky has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\"."
    • Changedvalidate_post4 fields changed
      • changedInput schema / properties / alt_texts / description
        Previous value: -"Image descriptions for screen readers, by media id (images in media_ids). Sent to Instagram, Facebook, X and LinkedIn. Stored on the image, so later posts reuse it; an empty string clears it."New value: +"Image descriptions for screen readers, by media id (images in media_ids). Sent to Instagram, Facebook, X, LinkedIn and Bluesky. Stored on the image, so later posts reuse it; an empty string clears it."
      • changedInput schema / properties / caption / description
        Previous value: -"Master text. Goes to every account unless per_channel overrides it. X: 280 characters; Instagram and TikTok: 2,200."New value: +"Master text. Goes to every account unless per_channel overrides it. X: 280 characters; Bluesky: 300; Instagram and TikTok: 2,200."
      • changedInput schema / properties / cover_first_frame / description
        Previous value: -"Put the cover image (cover_media_id) at the start of the video, as its first two frames (~1/15 s), so networks that show the video's first frame show your cover: true = only where the network can't take a cover image (TikTok, X, Stories), \"all\" = on every network, false = never. The original video isn't changed; Shager publishes a copy. Default when omitted: true if the post has a cover and goes to TikTok or X, else false."New value: +"Put the cover image (cover_media_id) at the start of the video, as its first two frames (~1/15 s), so networks that show the video's first frame show your cover: true = only where the network can't take a cover image (TikTok, X, Bluesky, Stories), \"all\" = on every network, false = never. The original video isn't changed; Shager publishes a copy. Default when omitted: true if the post has a cover and goes to TikTok, X or Bluesky, else false."
      • changedInput schema / properties / cover_media_id / description
        Previous value: -"Cover image for the post's video: an IMAGE id from upload_media_from_url (not in media_ids). A cover the network refuses never fails the post: the result carries a notice. null removes it. Per network (\"Cover at the start of the video\" is cover_first_frame): Facebook: The image becomes the thumbnail of the video or Reel. Stories have no cover. Instagram: The image becomes the Reel's cover, in the feed and on the profile. Stories have no cover. YouTube: The image becomes the video's thumbnail. YouTube allows this only for phone-verified channels (youtube.com/verify); without that, the video goes up with a thumbnail YouTube picks. X: X has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\". LinkedIn: The image becomes the video's thumbnail. TikTok: TikTok takes no cover image through its API, only a moment of the video, and applies even that only to public posts (a private post shows the first frame). To always show your cover, private posts included, turn on \"Cover at the start of the video\"."New value: +"Cover image for the post's video: an IMAGE id from upload_media_from_url (not in media_ids). A cover the network refuses never fails the post: the result carries a notice. null removes it. Per network (\"Cover at the start of the video\" is cover_first_frame): Facebook: The image becomes the thumbnail of the video or Reel. Stories have no cover. Instagram: The image becomes the Reel's cover, in the feed and on the profile. Stories have no cover. YouTube: The image becomes the video's thumbnail. YouTube allows this only for phone-verified channels (youtube.com/verify); without that, the video goes up with a thumbnail YouTube picks. X: X has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\". LinkedIn: The image becomes the video's thumbnail. TikTok: TikTok takes no cover image through its API, only a moment of the video, and applies even that only to public posts (a private post shows the first frame). To always show your cover, private posts included, turn on \"Cover at the start of the video\". Bluesky: Bluesky has no cover setting: it shows the video's first frame. To show your cover, turn on \"Cover at the start of the video\"."
  6. 3 tool updates
    • Changedcreate_post1 field changed
      • addedInput schema / properties / per_channel / items / properties / delay_minutes
        Added value: +{
        +  "description": "A different time for this account: it gets the post this many minutes after schedule_at (0 = with the post, up to 7 days). For 'Instagram at 9:00, LinkedIn at 12:00', schedule_at is 9:00 and LinkedIn has 180. Give every account of a network the same value to move the whole network. Still one post: one approval, one entry in the plan's monthly count.",
        +  "maximum": 10080,
        +  "minimum": 0,
        +  "type": "integer"
        +}
    • Changedupdate_post1 field changed
      • addedInput schema / properties / per_channel / items / properties / delay_minutes
        Added value: +{
        +  "description": "A different time for this account: it gets the post this many minutes after schedule_at (0 = with the post, up to 7 days). For 'Instagram at 9:00, LinkedIn at 12:00', schedule_at is 9:00 and LinkedIn has 180. Give every account of a network the same value to move the whole network. Still one post: one approval, one entry in the plan's monthly count.",
        +  "maximum": 10080,
        +  "minimum": 0,
        +  "type": "integer"
        +}
    • Changedvalidate_post1 field changed
      • addedInput schema / properties / per_channel / items / properties / delay_minutes
        Added value: +{
        +  "description": "A different time for this account: it gets the post this many minutes after schedule_at (0 = with the post, up to 7 days). For 'Instagram at 9:00, LinkedIn at 12:00', schedule_at is 9:00 and LinkedIn has 180. Give every account of a network the same value to move the whole network. Still one post: one approval, one entry in the plan's monthly count.",
        +  "maximum": 10080,
        +  "minimum": 0,
        +  "type": "integer"
        +}
  7. 1 tool update
    • Changedinvite_member4 fields changed
      • addedInput schema / properties / role / default
        Added value: +"viewer"
      • changedInput schema / properties / role / description
        Previous value: -"editor: writes and schedules posts, answers comments. viewer: read only."New value: +"viewer: read only. Editors and managers are invited by a person in the app."
      • changedInput schema / properties / role / enum
        Previous value: -[
        -  "editor",
        -  "viewer"
        -]New value: +[
        +  "viewer"
        +]
      • changedInput schema / required
        Previous value: -[
        -  "email",
        -  "role"
        -]New value: +[
        +  "email"
        +]
  8. 39 tool updates
    • First observedcancel_post
    • First observedcreate_auto_reply
    • First observedcreate_connect_link
    • First observedcreate_group
    • First observedcreate_post
    • First observedcreate_webhook
    • First observedcreate_workspace
    • First observeddelete_auto_reply
    • First observeddelete_comment
    • First observeddelete_post
    • First observeddelete_webhook
    • First observedget_analytics
    • First observedget_approval
    • First observedget_claim_link
    • First observedget_holidays
    • First observedget_post
    • First observedget_structure
    • First observedhide_comment
    • First observedinvite_member
    • First observedlist_auto_replies
    • First observedlist_auto_reply_activity
    • First observedlist_channels
    • First observedlist_comments
    • First observedlist_groups
    • First observedlist_members
    • First observedlist_notifications
    • First observedlist_posts
    • First observedlist_webhooks
    • First observedlist_workspaces
    • First observedreply_to_comment
    • First observedrequest_approval
    • First observedschedule_post
    • First observedsend_test_webhook
    • First observedset_x_budget
    • First observedupdate_auto_reply
    • First observedupdate_post
    • First observedupload_media_from_url
    • First observedvalidate_post
    • First observedwhoami

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    B
    maintenance
    Schedule, publish, and measure social posts on Facebook, Instagram, TikTok, LinkedIn, Threads, Pinterest, and X for one brand or many.
    34
    MIT
  • A
    license
    A
    quality
    D
    maintenance
    AI-powered social media posting across 14 platforms. Post to Twitter, Instagram, TikTok, Facebook, LinkedIn, YouTube and more with one command. AI adapts content per platform, schedules posts, and generates 30-day content calendars.
    6
    MIT
Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources