Shager
Server Details
Schedule posts and videos to many social accounts at once, with a tracked link for each account.
- Status
- Healthy
- OAuth
- Works in Glama
- Last Tested
- Transport
- Streamable HTTP · MCP 2025-11-25
- URL
TDQS
Scored across 39 tools
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.
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.
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.
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 toolscancel_postCancel a scheduled postADestructiveIdempotentInspect
Unschedules a post that has not started publishing (it stays as an approved draft you can schedule again).
| Name | Required | Description | Default |
|---|---|---|---|
| post_id | Yes | ||
| workspace_id | Yes | Workspace id from list_workspaces |
TDQS
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.
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.
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.
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.
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.
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-replyADestructiveInspect
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.)
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | A short name the person will recognize, e.g. "Link in DM" | |
| enabled | No | ||
| message | No | The private message (to the commenter, or the answer to a direct message) | |
| trigger | Yes | COMMENT: someone comments on a post. MESSAGE: someone sends a direct message | |
| keywords | No | Whole words or phrases, any case; empty = every comment or message | |
| link_url | No | Added at the end of the private message as a tracked short link | |
| post_ids | No | COMMENT only: only comments on these Shager posts; empty = every post | |
| channel_ids | No | Only these accounts; empty = every account that supports the trigger | |
| workspace_id | Yes | Workspace id from list_workspaces | |
| public_replies | No | COMMENT only: public answers under the comment, one picked at random | |
| idempotency_key | No | Any 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_person | No | Answer each person once per rule (30 days) |
TDQS
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.
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.
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.
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.
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.
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_connect_linkCreate a client connect linkCInspect
A link to send the account owner (your client or your human). They open it, sign in to the network and pick their accounts — no Shager account needed. The accounts then appear in list_channels. 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. (Not available in an unclaimed sandbox.)
| Name | Required | Description | Default |
|---|---|---|---|
| label | No | Who the link is for (shown to the agency only). | |
| workspace_id | Yes | Workspace id from list_workspaces | |
| idempotency_key | No | Any 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
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare it as a non-read-only, non-destructive, non-idempotent, closed-world create. The description adds genuinely useful behavior — the client needs no Shager account, and connected accounts surface in list_channels — but omits the traits that matter for a link-minting tool: expiry, revocability, whether the link is single-use, and what the response contains. Instead it spends its length on downstream publishing capabilities.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Roughly 600 words, of which well over 80% is a per-platform feature brochure (TikTok cover moments, Instagram comment links, Pinterest carousels) that does not help an agent decide to call this tool or fill in its three parameters. The single useful sentence about the link's mechanics is buried at the very front and never developed.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a create tool with one required parameter, no output schema, and full schema coverage, the description should say what is returned (a URL?) and how the link behaves (expiry, revocation). It says none of that, while over-delivering on capability detail an agent does not need at call time.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so label, workspace_id and idempotency_key are already fully documented in the schema. The description contributes nothing about any of the three parameters, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening sentence describes the artifact ("A link to send the account owner... They open it, sign in and pick their accounts") rather than stating the action, but the purpose is inferable. It never distinguishes this from the similar sibling get_claim_link or from invite_member, leaving ambiguity about which link-generating tool to pick.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no explicit when-to-use guidance, no prerequisites beyond the incidental mention of list_channels, and no exclusions. The closest thing to routing is the implicit notion that you use it to let a client connect their own accounts, which an agent must infer.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | ||
| channel_ids | No | ||
| workspace_id | Yes | Workspace id from list_workspaces | |
| idempotency_key | No | Any 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
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.
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.
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.
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.
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.
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 postADestructiveInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| poll | No | A poll on X, LinkedIn and Mastodon. A poll post carries no media. | |
| label | No | Internal name for the post (never published). | |
| format | No | Format 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. | |
| caption | Yes | 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. | |
| confirm | No | 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. | |
| cta_url | No | Link 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_end | No | Google Business Profile event or offer: when it ends (not before gbp_start), same format. | |
| campaign | No | utm_campaign value for the tracked links. | |
| cta_text | No | ||
| draft_id | No | Reserved 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_link | No | 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. | |
| gbp_type | No | Google Business Profile: STANDARD (an update, the default), EVENT or OFFER. Events and offers need gbp_title, gbp_start and gbp_end. | |
| x_thread | No | X: up to 5 follow-up posts that continue the post as a thread (each is a paid X post). | |
| alt_texts | No | 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. | |
| gbp_start | No | 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. | |
| gbp_terms | No | Google Business Profile offer: terms and conditions (optional). | |
| gbp_title | No | Google Business Profile event or offer: its title (required there, up to 58 characters). | |
| group_ids | No | Account groups — every active account in them is added to channel_ids. | |
| media_ids | No | Media from upload_media_from_url, in display order. Instagram, TikTok and YouTube need media; Reels/Shorts/Video need a video file. | |
| gbp_button | No | 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. | |
| gbp_coupon | No | Google Business Profile offer: a coupon code (optional). | |
| channel_ids | No | Accounts to publish to (ids from list_channels). | |
| per_channel | No | Per-account overrides and network fields. TikTok accounts need tiktok_privacy here. | |
| schedule_at | No | ISO 8601 with offset, e.g. 2026-10-20T09:00:00+03:00. Omit to save a draft. | |
| video_title | No | Video title on Facebook and LinkedIn videos (YouTube uses youtube_title). | |
| ai_generated | No | 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). | |
| workspace_id | Yes | Workspace id from list_workspaces | |
| youtube_tags | No | YouTube tags, 500 characters in total. | |
| first_comment | No | Posted 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_language | No | Mastodon: the post's language as an ISO 639-1 code (he, en, es…); omitted = the account's default. | |
| threads_topic | No | Threads: the post's topic, 1–50 characters, no period or ampersand (e.g. Recipes). | |
| youtube_title | No | YouTube video title (default: first line of the caption). Overridable per channel. | |
| cover_media_id | No | 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. | |
| paid_promotion | No | Paid promotion or partnership disclosure: YouTube (paid product placement), X (paid partnership). TikTok uses tiktok_commercial. | |
| pinterest_link | No | 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. | |
| content_warning | No | Mastodon: a content warning shown before the post (readers tap to see it; it also hides images). Counts toward the 500 characters. | |
| idempotency_key | No | Any 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_title | No | Pinterest: the Pin's title, up to 100 characters (feeds show about the first 40). The caption is the Pin's description (≤800). | |
| stagger_seconds | No | Deprecated: [min, max] — use stagger_min_seconds and stagger_max_seconds. | |
| telegram_silent | No | Telegram: send without a sound, so channel subscribers get no notification. | |
| tiktok_cover_ms | No | TikTok: 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_license | No | YouTube license (default youtube). | |
| youtube_privacy | No | YouTube: public (default), unlisted or private. | |
| x_reply_settings | No | X: who can reply (default everyone): following, mentionedUsers, subscribers or verified. | |
| cover_first_frame | No | 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. | |
| threads_link_card | No | 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. | |
| confirmation_token | No | Token returned by needs_confirmation or validate_post for this exact plan; expires after 15 minutes. | |
| pinterest_board_id | No | 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. | |
| youtube_embeddable | No | YouTube: allow embedding on other sites (default true). | |
| facebook_pin_to_top | No | Facebook: pin the post to the top of the Page (feed posts). | |
| instagram_user_tags | No | Instagram single photo: people tagged on it, x/y from 0 to 1 measured from the top-left. | |
| linkedin_visibility | No | LinkedIn: PUBLIC (default), CONNECTIONS or LOGGED_IN. | |
| mastodon_visibility | No | Mastodon: who sees the post: public (default), unlisted (quiet public: not in public timelines or hashtags) or private (followers only). | |
| stagger_max_seconds | No | Longest pause between two accounts of the same network (default 90). | |
| stagger_min_seconds | No | Shortest pause between two accounts of the same network (default 30). Facebook and Instagram share one lane. | |
| youtube_category_id | No | YouTube category id (default 22, People & Blogs). | |
| youtube_playlist_id | No | YouTube: add the video to this playlist of the channel (per_channel, since each channel has its own playlists). | |
| facebook_link_button | No | Facebook 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_reel | No | Instagram 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_id | No | Instagram: 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_control | No | Threads: who can reply: everyone (default), accounts_you_follow, mentioned_only or followers_only. | |
| youtube_made_for_kids | No | YouTube's made-for-kids declaration (COPPA). Required explicitly when targeting YouTube; declare whether the video is made for children. | |
| instagram_comments_off | No | Instagram: turn comments off right after publishing. | |
| instagram_collaborators | No | Instagram: 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_feed | No | Instagram Reel: also show it in the profile's main grid (default true). | |
| linkedin_disable_reshare | No | LinkedIn: stop others from resharing the post. | |
| youtube_notify_subscribers | No | YouTube: notify subscribers about the upload (default true). |
TDQS
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.
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.
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.
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.
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.
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 endpointADestructiveInspect
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.)
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | https:// URL that receives the events. | |
| events | No | Event types to send. Omit for every event, including ones added later. | |
| description | No | What it is for (shown in the app). | |
| workspace_id | Yes | Workspace id from list_workspaces |
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | ||
| timezone | No | IANA zone, default Asia/Jerusalem | |
| idempotency_key | No | Any 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_required | No | Require client approval before scheduling (default false for agents). |
TDQS
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.
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.
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.
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.
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.
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-replyADestructiveIdempotentInspect
Deletes a rule; it stops answering at once. Its activity stays in list_auto_reply_activity (kept 90 days).
| Name | Required | Description | Default |
|---|---|---|---|
| rule_id | Yes | ||
| workspace_id | Yes | Workspace id from list_workspaces |
TDQS
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.
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.
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.
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.
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.
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 commentADestructiveIdempotentInspect
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.)
| Name | Required | Description | Default |
|---|---|---|---|
| post_id | Yes | ||
| channel_id | Yes | ||
| comment_id | Yes | ||
| workspace_id | Yes | Workspace id from list_workspaces |
TDQS
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.
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.
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.
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.
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.
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 draftADestructiveIdempotentInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| post_id | Yes | ||
| workspace_id | Yes | Workspace id from list_workspaces |
TDQS
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.
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.
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.
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.
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.
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 endpointADestructiveIdempotentInspect
Stops sending events to this endpoint, including retries still pending. Cannot be undone.
| Name | Required | Description | Default |
|---|---|---|---|
| webhook_id | Yes | ||
| workspace_id | Yes | Workspace id from list_workspaces |
TDQS
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.
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.
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.
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.
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.
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 doingARead-onlyIdempotentInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | Date (2026-10-31, inclusive) or ISO datetime. Default: now | |
| top | No | How many top posts to return (default 10) | |
| from | No | Date (2026-10-01) or ISO datetime. Default: 30 days ago | |
| group_ids | No | Only the accounts in these groups (from list_groups) | |
| channel_ids | No | Only these accounts (from list_channels) | |
| workspace_id | Yes | Workspace id from list_workspaces |
TDQS
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.
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.
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.
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.
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.
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 postBRead-onlyIdempotentInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| post_id | Yes | ||
| workspace_id | Yes | Workspace id from list_workspaces |
TDQS
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.
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.
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.
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.
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.
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_claim_linkGet a fresh claim linkADestructiveInspect
Sandbox only. Issues a new claim link for your human (the one from signup stops working) and emails it again to contact_email when there is one, at most once a day per address (emailed says whether it went). Call it when you lost the signup response.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds substantial behavior beyond the annotations: the prior signup link is invalidated, the email is re-sent to contact_email, sending is throttled to at most once per day per address, and the 'emailed' field reports whether delivery happened. This is exactly the kind of operational detail an agent needs before invoking a destructive, non-idempotent tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the 'Sandbox only' constraint and packs the trigger, side effects, and rate limit into compact prose with no filler. The grammar is slightly run-on ('emailed says whether it went'), but nothing is wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, and the description compensates by explaining the 'emailed' indicator and the email side effect. Combined with annotations covering destructiveness and idempotency, an agent has enough to call it correctly; only the full response shape is left implicit.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With zero parameters the baseline is 4, and the description adds value by naming the output field 'emailed' and explaining what it means. No further parameter detail is needed for a no-arg tool.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: "Issues a new claim link for your human." It also clarifies the lifecycle (the signup link stops working), which distinguishes it from a generic link creator. It does not, however, differentiate itself from the sibling create_connect_link, so an agent may still hesitate between the two.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit trigger: "Call it when you lost the signup response," which is clear context for use. It lacks an explicit when-not or a pointer to create_connect_link as the alternative for a different link type, so it stops short of full routing guidance.
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 guidanceARead-onlyIdempotentInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | Last day, YYYY-MM-DD (default: from + 60 days, max 400 days) | |
| from | No | First day, YYYY-MM-DD (default: today) | |
| language | No | en | |
| traditions | No | Limit 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
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.
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.
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.
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.
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.
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 postARead-onlyIdempotentInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| post_id | Yes | ||
| workspace_id | Yes | Workspace id from list_workspaces |
TDQS
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.
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.
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.
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.
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.
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 groupsARead-onlyIdempotentInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
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.
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.
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.
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.
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.
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 commentADestructiveIdempotentInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| hidden | No | ||
| post_id | Yes | ||
| channel_id | Yes | ||
| comment_id | Yes | ||
| workspace_id | Yes | Workspace id from list_workspaces |
TDQS
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.
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.
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.
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.
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.
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 teamADestructiveInspect
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.)
| Name | Required | Description | Default |
|---|---|---|---|
| role | No | viewer: read only. Editors and managers are invited by a person in the app. | viewer |
| Yes | |||
| scope | No | "all", or the workspace ids they may open | all |
TDQS
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.
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.
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.
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.
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.
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-repliesARead-onlyIdempotentInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| workspace_id | Yes | Workspace id from list_workspaces |
TDQS
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.
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.
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.
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.
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.
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 activityARead-onlyIdempotentInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| status | No | ||
| rule_id | No | Only this rule's activity | |
| workspace_id | Yes | Workspace id from list_workspaces |
TDQS
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.
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.
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.
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.
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.
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 accountsARead-onlyIdempotentInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| network | No | Only accounts on this network. | |
| workspace_id | Yes | Workspace id from list_workspaces |
Output Schema
| Name | Required | Description |
|---|---|---|
| items | Yes | |
| next_cursor | Yes |
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| post_id | Yes | ||
| channel_id | Yes | The account the post went to (destinations[].channel_id in get_post) | |
| workspace_id | Yes | Workspace id from list_workspaces |
TDQS
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.
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.
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.
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.
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.
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 groupsBRead-onlyIdempotentInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| workspace_id | Yes | Workspace id from list_workspaces |
Output Schema
| Name | Required | Description |
|---|---|---|
| items | Yes | |
| next_cursor | Yes |
TDQS
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.
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.
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.
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.
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.
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 membersBRead-onlyIdempotentInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
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.
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.
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.
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.
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.
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 notificationsARead-onlyIdempotentInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| type | No | Only this kind | |
| limit | No | Default 30 | |
| since | No | Only notifications after this time (ISO datetime) | |
| workspace_id | No | Only this workspace (from list_workspaces) |
Output Schema
| Name | Required | Description |
|---|---|---|
| items | Yes | |
| next_cursor | Yes |
TDQS
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.
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.
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.
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.
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.
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 postsARead-onlyIdempotentInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | Only posts scheduled at or before this date (inclusive) or instant. | |
| from | No | Only posts scheduled at or after this date (2026-10-01) or instant. | |
| limit | No | ||
| query | No | Words to find in the caption or the internal label (case-insensitive). | |
| cursor | No | next_cursor from the previous page. | |
| status | No | ||
| network | No | Only posts going to at least one account on this network. | |
| group_id | No | Only posts going to at least one account in this group (from list_groups). | |
| channel_id | No | Only posts going to this account (from list_channels). | |
| workspace_id | Yes | Workspace id from list_workspaces |
Output Schema
| Name | Required | Description |
|---|---|---|
| items | Yes | |
| next_cursor | Yes |
TDQS
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.
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.
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.
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.
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.
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 endpointsBRead-onlyIdempotentInspect
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).
| Name | Required | Description | Default |
|---|---|---|---|
| workspace_id | Yes | Workspace id from list_workspaces |
Output Schema
| Name | Required | Description |
|---|---|---|
| items | Yes | |
| next_cursor | Yes |
TDQS
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.
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.
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.
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.
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.
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 workspacesARead-onlyIdempotentInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| items | Yes | |
| next_cursor | Yes |
TDQS
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.
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.
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.
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.
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.
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 commentADestructiveInspect
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.)
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | ||
| post_id | Yes | ||
| channel_id | Yes | ||
| comment_id | Yes | ||
| workspace_id | Yes | Workspace id from list_workspaces |
TDQS
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.
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.
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.
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.
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.
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 approvalADestructiveInspect
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.)
| Name | Required | Description | Default |
|---|---|---|---|
| post_id | Yes | ||
| send_email | No | ||
| workspace_id | Yes | Workspace id from list_workspaces | |
| reviewer_name | Yes | ||
| reviewer_email | No | ||
| reviewer_phone | No | ||
| idempotency_key | No | Any 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
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.
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.
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.
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.
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.
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 postADestructiveInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| confirm | No | 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. | |
| post_id | Yes | ||
| schedule_at | Yes | ||
| workspace_id | Yes | Workspace id from list_workspaces | |
| idempotency_key | No | Any 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_token | No | Token returned by needs_confirmation or validate_post for this exact plan; expires after 15 minutes. |
TDQS
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.
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.
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.
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.
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.
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.)
| Name | Required | Description | Default |
|---|---|---|---|
| webhook_id | Yes | ||
| workspace_id | Yes | Workspace id from list_workspaces |
TDQS
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.
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.
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.
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.
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.
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 limitADestructiveIdempotentInspect
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.)
| Name | Required | Description | Default |
|---|---|---|---|
| workspace_id | Yes | Workspace id from list_workspaces | |
| monthly_limit_usd | Yes | US dollars per month, e.g. 5 |
TDQS
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.
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.
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.
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.
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.
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-replyADestructiveIdempotentInspect
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.)
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | A short name the person will recognize, e.g. "Link in DM" | |
| enabled | No | ||
| message | No | The private message (to the commenter, or the answer to a direct message) | |
| rule_id | Yes | ||
| trigger | No | COMMENT: someone comments on a post. MESSAGE: someone sends a direct message | |
| keywords | No | Whole words or phrases, any case; empty = every comment or message | |
| link_url | No | Added at the end of the private message as a tracked short link | |
| post_ids | No | COMMENT only: only comments on these Shager posts; empty = every post | |
| channel_ids | No | Only these accounts; empty = every account that supports the trigger | |
| workspace_id | Yes | Workspace id from list_workspaces | |
| public_replies | No | COMMENT only: public answers under the comment, one picked at random | |
| once_per_person | No | Answer each person once per rule (30 days) |
TDQS
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.
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.
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.
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.
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.
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 draftADestructiveIdempotentInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| poll | No | A poll on X, LinkedIn and Mastodon. A poll post carries no media. | |
| label | No | Internal name for the post (never published). | |
| format | No | Format 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. | |
| caption | No | 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. | |
| cta_url | No | Link 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_end | No | Google Business Profile event or offer: when it ends (not before gbp_start), same format. | |
| post_id | Yes | ||
| campaign | No | utm_campaign value for the tracked links. | |
| cta_text | No | ||
| draft_id | No | Reserved 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_link | No | 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. | |
| gbp_type | No | Google Business Profile: STANDARD (an update, the default), EVENT or OFFER. Events and offers need gbp_title, gbp_start and gbp_end. | |
| x_thread | No | X: up to 5 follow-up posts that continue the post as a thread (each is a paid X post). | |
| alt_texts | No | 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. | |
| gbp_start | No | 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. | |
| gbp_terms | No | Google Business Profile offer: terms and conditions (optional). | |
| gbp_title | No | Google Business Profile event or offer: its title (required there, up to 58 characters). | |
| group_ids | No | Account groups — every active account in them is added to channel_ids. | |
| media_ids | No | Media from upload_media_from_url, in display order. Instagram, TikTok and YouTube need media; Reels/Shorts/Video need a video file. | |
| gbp_button | No | 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. | |
| gbp_coupon | No | Google Business Profile offer: a coupon code (optional). | |
| channel_ids | No | Accounts to publish to (ids from list_channels). | |
| per_channel | No | Per-account overrides and network fields. TikTok accounts need tiktok_privacy here. | |
| video_title | No | Video title on Facebook and LinkedIn videos (YouTube uses youtube_title). | |
| ai_generated | No | 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). | |
| workspace_id | Yes | Workspace id from list_workspaces | |
| youtube_tags | No | YouTube tags, 500 characters in total. | |
| first_comment | No | Posted 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_language | No | Mastodon: the post's language as an ISO 639-1 code (he, en, es…); omitted = the account's default. | |
| threads_topic | No | Threads: the post's topic, 1–50 characters, no period or ampersand (e.g. Recipes). | |
| youtube_title | No | YouTube video title (default: first line of the caption). Overridable per channel. | |
| cover_media_id | No | 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. | |
| paid_promotion | No | Paid promotion or partnership disclosure: YouTube (paid product placement), X (paid partnership). TikTok uses tiktok_commercial. | |
| pinterest_link | No | 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. | |
| content_warning | No | Mastodon: a content warning shown before the post (readers tap to see it; it also hides images). Counts toward the 500 characters. | |
| pinterest_title | No | Pinterest: the Pin's title, up to 100 characters (feeds show about the first 40). The caption is the Pin's description (≤800). | |
| stagger_seconds | No | Deprecated: [min, max] — use stagger_min_seconds and stagger_max_seconds. | |
| telegram_silent | No | Telegram: send without a sound, so channel subscribers get no notification. | |
| tiktok_cover_ms | No | TikTok: 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_license | No | YouTube license (default youtube). | |
| youtube_privacy | No | YouTube: public (default), unlisted or private. | |
| x_reply_settings | No | X: who can reply (default everyone): following, mentionedUsers, subscribers or verified. | |
| cover_first_frame | No | 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. | |
| threads_link_card | No | 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. | |
| pinterest_board_id | No | 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. | |
| youtube_embeddable | No | YouTube: allow embedding on other sites (default true). | |
| facebook_pin_to_top | No | Facebook: pin the post to the top of the Page (feed posts). | |
| instagram_user_tags | No | Instagram single photo: people tagged on it, x/y from 0 to 1 measured from the top-left. | |
| linkedin_visibility | No | LinkedIn: PUBLIC (default), CONNECTIONS or LOGGED_IN. | |
| mastodon_visibility | No | Mastodon: who sees the post: public (default), unlisted (quiet public: not in public timelines or hashtags) or private (followers only). | |
| stagger_max_seconds | No | Longest pause between two accounts of the same network (default 90). | |
| stagger_min_seconds | No | Shortest pause between two accounts of the same network (default 30). Facebook and Instagram share one lane. | |
| youtube_category_id | No | YouTube category id (default 22, People & Blogs). | |
| youtube_playlist_id | No | YouTube: add the video to this playlist of the channel (per_channel, since each channel has its own playlists). | |
| facebook_link_button | No | Facebook 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_reel | No | Instagram 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_id | No | Instagram: 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_control | No | Threads: who can reply: everyone (default), accounts_you_follow, mentioned_only or followers_only. | |
| youtube_made_for_kids | No | YouTube's made-for-kids declaration (COPPA). Required explicitly when targeting YouTube; declare whether the video is made for children. | |
| instagram_comments_off | No | Instagram: turn comments off right after publishing. | |
| instagram_collaborators | No | Instagram: 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_feed | No | Instagram Reel: also show it in the profile's main grid (default true). | |
| linkedin_disable_reshare | No | LinkedIn: stop others from resharing the post. | |
| youtube_notify_subscribers | No | YouTube: notify subscribers about the upload (default true). |
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | ||
| width | No | Fallback only: used when the video can't be measured. | |
| height | No | Fallback only: used when the video can't be measured. | |
| file_name | No | ||
| duration_ms | No | Fallback only: used when the video can't be measured. | |
| workspace_id | Yes | Workspace id from list_workspaces | |
| idempotency_key | No | Any 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
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.
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.
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.
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.
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.
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)ARead-onlyIdempotentInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| poll | No | A poll on X, LinkedIn and Mastodon. A poll post carries no media. | |
| label | No | Internal name for the post (never published). | |
| format | No | Format 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. | |
| caption | Yes | 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. | |
| cta_url | No | Link 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_end | No | Google Business Profile event or offer: when it ends (not before gbp_start), same format. | |
| post_id | No | Existing draft or approved post; enables checking its approval state and preserving its tracked URLs. | |
| campaign | No | utm_campaign value for the tracked links. | |
| cta_text | No | ||
| draft_id | No | Reserved 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_link | No | 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. | |
| gbp_type | No | Google Business Profile: STANDARD (an update, the default), EVENT or OFFER. Events and offers need gbp_title, gbp_start and gbp_end. | |
| x_thread | No | X: up to 5 follow-up posts that continue the post as a thread (each is a paid X post). | |
| alt_texts | No | 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. | |
| gbp_start | No | 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. | |
| gbp_terms | No | Google Business Profile offer: terms and conditions (optional). | |
| gbp_title | No | Google Business Profile event or offer: its title (required there, up to 58 characters). | |
| group_ids | No | Account groups — every active account in them is added to channel_ids. | |
| media_ids | No | Media from upload_media_from_url, in display order. Instagram, TikTok and YouTube need media; Reels/Shorts/Video need a video file. | |
| gbp_button | No | 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. | |
| gbp_coupon | No | Google Business Profile offer: a coupon code (optional). | |
| channel_ids | No | Accounts to publish to (ids from list_channels). | |
| per_channel | No | Per-account overrides and network fields. TikTok accounts need tiktok_privacy here. | |
| schedule_at | No | Optional: also check allowances, caps and confirmation for this time. | |
| video_title | No | Video title on Facebook and LinkedIn videos (YouTube uses youtube_title). | |
| ai_generated | No | 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). | |
| workspace_id | Yes | Workspace id from list_workspaces | |
| youtube_tags | No | YouTube tags, 500 characters in total. | |
| first_comment | No | Posted 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_language | No | Mastodon: the post's language as an ISO 639-1 code (he, en, es…); omitted = the account's default. | |
| threads_topic | No | Threads: the post's topic, 1–50 characters, no period or ampersand (e.g. Recipes). | |
| youtube_title | No | YouTube video title (default: first line of the caption). Overridable per channel. | |
| cover_media_id | No | 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. | |
| paid_promotion | No | Paid promotion or partnership disclosure: YouTube (paid product placement), X (paid partnership). TikTok uses tiktok_commercial. | |
| pinterest_link | No | 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. | |
| content_warning | No | Mastodon: a content warning shown before the post (readers tap to see it; it also hides images). Counts toward the 500 characters. | |
| pinterest_title | No | Pinterest: the Pin's title, up to 100 characters (feeds show about the first 40). The caption is the Pin's description (≤800). | |
| stagger_seconds | No | Deprecated: [min, max] — use stagger_min_seconds and stagger_max_seconds. | |
| telegram_silent | No | Telegram: send without a sound, so channel subscribers get no notification. | |
| tiktok_cover_ms | No | TikTok: 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_license | No | YouTube license (default youtube). | |
| youtube_privacy | No | YouTube: public (default), unlisted or private. | |
| x_reply_settings | No | X: who can reply (default everyone): following, mentionedUsers, subscribers or verified. | |
| cover_first_frame | No | 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. | |
| threads_link_card | No | 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. | |
| pinterest_board_id | No | 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. | |
| youtube_embeddable | No | YouTube: allow embedding on other sites (default true). | |
| facebook_pin_to_top | No | Facebook: pin the post to the top of the Page (feed posts). | |
| instagram_user_tags | No | Instagram single photo: people tagged on it, x/y from 0 to 1 measured from the top-left. | |
| linkedin_visibility | No | LinkedIn: PUBLIC (default), CONNECTIONS or LOGGED_IN. | |
| mastodon_visibility | No | Mastodon: who sees the post: public (default), unlisted (quiet public: not in public timelines or hashtags) or private (followers only). | |
| stagger_max_seconds | No | Longest pause between two accounts of the same network (default 90). | |
| stagger_min_seconds | No | Shortest pause between two accounts of the same network (default 30). Facebook and Instagram share one lane. | |
| youtube_category_id | No | YouTube category id (default 22, People & Blogs). | |
| youtube_playlist_id | No | YouTube: add the video to this playlist of the channel (per_channel, since each channel has its own playlists). | |
| facebook_link_button | No | Facebook 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_reel | No | Instagram 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_id | No | Instagram: 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_control | No | Threads: who can reply: everyone (default), accounts_you_follow, mentioned_only or followers_only. | |
| youtube_made_for_kids | No | YouTube's made-for-kids declaration (COPPA). Required explicitly when targeting YouTube; declare whether the video is made for children. | |
| instagram_comments_off | No | Instagram: turn comments off right after publishing. | |
| instagram_collaborators | No | Instagram: 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_feed | No | Instagram Reel: also show it in the profile's main grid (default true). | |
| linkedin_disable_reshare | No | LinkedIn: stop others from resharing the post. | |
| youtube_notify_subscribers | No | YouTube: notify subscribers about the upload (default true). |
TDQS
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.
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.
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.
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.
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.
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 IARead-onlyIdempotentInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
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.
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.
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.
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.
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.
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.
5 tool updates
- Changed
create_post17 fields changed- changed
Input schema / properties / cover_media_id / descriptionPrevious 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." - added
Input schema / properties / gbp_buttonAdded 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" +} - added
Input schema / properties / gbp_couponAdded value: +{ + "description": "Google Business Profile offer: a coupon code (optional).", + "maxLength": 58, + "type": "string" +} - added
Input schema / properties / gbp_endAdded 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" +} - added
Input schema / properties / gbp_linkAdded 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" +} - added
Input schema / properties / gbp_startAdded 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" +} - added
Input schema / properties / gbp_termsAdded value: +{ + "description": "Google Business Profile offer: terms and conditions (optional).", + "maxLength": 1500, + "type": "string" +} - added
Input schema / properties / gbp_titleAdded value: +{ + "description": "Google Business Profile event or offer: its title (required there, up to 58 characters).", + "maxLength": 58, + "type": "string" +} - added
Input schema / properties / gbp_typeAdded 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" +} - added
Input schema / properties / per_channel / items / properties / gbp_buttonAdded 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" +} - added
Input schema / properties / per_channel / items / properties / gbp_couponAdded value: +{ + "description": "Google Business Profile offer: a coupon code (optional).", + "maxLength": 58, + "type": "string" +} - added
Input schema / properties / per_channel / items / properties / gbp_endAdded 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" +} - added
Input schema / properties / per_channel / items / properties / gbp_linkAdded 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" +} - added
Input schema / properties / per_channel / items / properties / gbp_startAdded 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" +} - added
Input schema / properties / per_channel / items / properties / gbp_termsAdded value: +{ + "description": "Google Business Profile offer: terms and conditions (optional).", + "maxLength": 1500, + "type": "string" +} - added
Input schema / properties / per_channel / items / properties / gbp_titleAdded value: +{ + "description": "Google Business Profile event or offer: its title (required there, up to 58 characters).", + "maxLength": 58, + "type": "string" +} - added
Input schema / properties / per_channel / items / properties / gbp_typeAdded 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" +}
- Changed
list_channels1 field changed- changed
Input schema / properties / network / enumPrevious 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" +]
- Changed
list_posts1 field changed- changed
Input schema / properties / network / enumPrevious 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" +]
- Changed
update_post17 fields changed- changed
Input schema / properties / cover_media_id / descriptionPrevious 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." - added
Input schema / properties / gbp_buttonAdded 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" +} - added
Input schema / properties / gbp_couponAdded value: +{ + "description": "Google Business Profile offer: a coupon code (optional).", + "maxLength": 58, + "type": "string" +} - added
Input schema / properties / gbp_endAdded 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" +} - added
Input schema / properties / gbp_linkAdded 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" +} - added
Input schema / properties / gbp_startAdded 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" +} - added
Input schema / properties / gbp_termsAdded value: +{ + "description": "Google Business Profile offer: terms and conditions (optional).", + "maxLength": 1500, + "type": "string" +} - added
Input schema / properties / gbp_titleAdded value: +{ + "description": "Google Business Profile event or offer: its title (required there, up to 58 characters).", + "maxLength": 58, + "type": "string" +} - added
Input schema / properties / gbp_typeAdded 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" +} - added
Input schema / properties / per_channel / items / properties / gbp_buttonAdded 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" +} - added
Input schema / properties / per_channel / items / properties / gbp_couponAdded value: +{ + "description": "Google Business Profile offer: a coupon code (optional).", + "maxLength": 58, + "type": "string" +} - added
Input schema / properties / per_channel / items / properties / gbp_endAdded 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" +} - added
Input schema / properties / per_channel / items / properties / gbp_linkAdded 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" +} - added
Input schema / properties / per_channel / items / properties / gbp_startAdded 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" +} - added
Input schema / properties / per_channel / items / properties / gbp_termsAdded value: +{ + "description": "Google Business Profile offer: terms and conditions (optional).", + "maxLength": 1500, + "type": "string" +} - added
Input schema / properties / per_channel / items / properties / gbp_titleAdded value: +{ + "description": "Google Business Profile event or offer: its title (required there, up to 58 characters).", + "maxLength": 58, + "type": "string" +} - added
Input schema / properties / per_channel / items / properties / gbp_typeAdded 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" +}
- Changed
validate_post17 fields changed- changed
Input schema / properties / cover_media_id / descriptionPrevious 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." - added
Input schema / properties / gbp_buttonAdded 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" +} - added
Input schema / properties / gbp_couponAdded value: +{ + "description": "Google Business Profile offer: a coupon code (optional).", + "maxLength": 58, + "type": "string" +} - added
Input schema / properties / gbp_endAdded 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" +} - added
Input schema / properties / gbp_linkAdded 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" +} - added
Input schema / properties / gbp_startAdded 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" +} - added
Input schema / properties / gbp_termsAdded value: +{ + "description": "Google Business Profile offer: terms and conditions (optional).", + "maxLength": 1500, + "type": "string" +} - added
Input schema / properties / gbp_titleAdded value: +{ + "description": "Google Business Profile event or offer: its title (required there, up to 58 characters).", + "maxLength": 58, + "type": "string" +} - added
Input schema / properties / gbp_typeAdded 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" +} - added
Input schema / properties / per_channel / items / properties / gbp_buttonAdded 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" +} - added
Input schema / properties / per_channel / items / properties / gbp_couponAdded value: +{ + "description": "Google Business Profile offer: a coupon code (optional).", + "maxLength": 58, + "type": "string" +} - added
Input schema / properties / per_channel / items / properties / gbp_endAdded 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" +} - added
Input schema / properties / per_channel / items / properties / gbp_linkAdded 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" +} - added
Input schema / properties / per_channel / items / properties / gbp_startAdded 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" +} - added
Input schema / properties / per_channel / items / properties / gbp_termsAdded value: +{ + "description": "Google Business Profile offer: terms and conditions (optional).", + "maxLength": 1500, + "type": "string" +} - added
Input schema / properties / per_channel / items / properties / gbp_titleAdded value: +{ + "description": "Google Business Profile event or offer: its title (required there, up to 58 characters).", + "maxLength": 58, + "type": "string" +} - added
Input schema / properties / per_channel / items / properties / gbp_typeAdded 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" +}
6 tool updates
- Changed
create_post10 fields changed- changed
Input schema / properties / ai_generated / descriptionPrevious 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)." - changed
Input schema / properties / confirm / descriptionPrevious 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." - changed
Input schema / properties / cover_media_id / descriptionPrevious 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." - changed
Input schema / properties / per_channel / items / properties / ai_generated / descriptionPrevious 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)." - added
Input schema / properties / per_channel / items / properties / pinterest_board_idAdded 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" +} - added
Input schema / properties / per_channel / items / properties / pinterest_linkAdded 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" +} - added
Input schema / properties / per_channel / items / properties / pinterest_titleAdded 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" +} - added
Input schema / properties / pinterest_board_idAdded 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" +} - added
Input schema / properties / pinterest_linkAdded 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" +} - added
Input schema / properties / pinterest_titleAdded 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" +}
- Changed
list_channels1 field changed- changed
Input schema / properties / network / enumPrevious 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" +]
- Changed
list_posts1 field changed- changed
Input schema / properties / network / enumPrevious 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" +]
- Changed
schedule_post1 field changed- changed
Input schema / properties / confirm / descriptionPrevious 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."
- Changed
update_post9 fields changed- changed
Input schema / properties / ai_generated / descriptionPrevious 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)." - changed
Input schema / properties / cover_media_id / descriptionPrevious 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." - changed
Input schema / properties / per_channel / items / properties / ai_generated / descriptionPrevious 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)." - added
Input schema / properties / per_channel / items / properties / pinterest_board_idAdded 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" +} - added
Input schema / properties / per_channel / items / properties / pinterest_linkAdded 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" +} - added
Input schema / properties / per_channel / items / properties / pinterest_titleAdded 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" +} - added
Input schema / properties / pinterest_board_idAdded 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" +} - added
Input schema / properties / pinterest_linkAdded 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" +} - added
Input schema / properties / pinterest_titleAdded 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" +}
- Changed
validate_post9 fields changed- changed
Input schema / properties / ai_generated / descriptionPrevious 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)." - changed
Input schema / properties / cover_media_id / descriptionPrevious 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." - changed
Input schema / properties / per_channel / items / properties / ai_generated / descriptionPrevious 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)." - added
Input schema / properties / per_channel / items / properties / pinterest_board_idAdded 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" +} - added
Input schema / properties / per_channel / items / properties / pinterest_linkAdded 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" +} - added
Input schema / properties / per_channel / items / properties / pinterest_titleAdded 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" +} - added
Input schema / properties / pinterest_board_idAdded 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" +} - added
Input schema / properties / pinterest_linkAdded 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" +} - added
Input schema / properties / pinterest_titleAdded 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" +}
5 tool updates
- Changed
create_post23 fields changed- changed
Input schema / properties / alt_texts / descriptionPrevious 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." - changed
Input schema / properties / caption / descriptionPrevious 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." - added
Input schema / properties / content_warningAdded 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" +} - changed
Input schema / properties / cover_media_id / descriptionPrevious 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\"." - added
Input schema / properties / mastodon_visibilityAdded 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" +} - added
Input schema / properties / per_channel / items / properties / content_warningAdded 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" +} - added
Input schema / properties / per_channel / items / properties / mastodon_visibilityAdded 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" +} - changed
Input schema / properties / per_channel / items / properties / poll / descriptionPrevious 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." - changed
Input schema / properties / per_channel / items / properties / poll / properties / options / descriptionPrevious value: -"2–4 answers: X ≤25 characters each, LinkedIn ≤30."New value: +"2–4 answers: X ≤25 characters each, LinkedIn ≤30, Mastodon ≤50." - changed
Input schema / properties / per_channel / items / properties / poll / properties / options / items / maxLengthPrevious value: -30New value: +50 - changed
Input schema / properties / per_channel / items / properties / poll / properties / question / descriptionPrevious 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." - added
Input schema / properties / per_channel / items / properties / post_languageAdded 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" +} - added
Input schema / properties / per_channel / items / properties / threads_link_cardAdded 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" +} - added
Input schema / properties / per_channel / items / properties / threads_reply_controlAdded 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" +} - added
Input schema / properties / per_channel / items / properties / threads_topicAdded value: +{ + "description": "Threads: the post's topic, 1–50 characters, no period or ampersand (e.g. Recipes).", + "maxLength": 50, + "type": "string" +} - changed
Input schema / properties / poll / descriptionPrevious 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." - changed
Input schema / properties / poll / properties / options / descriptionPrevious value: -"2–4 answers: X ≤25 characters each, LinkedIn ≤30."New value: +"2–4 answers: X ≤25 characters each, LinkedIn ≤30, Mastodon ≤50." - changed
Input schema / properties / poll / properties / options / items / maxLengthPrevious value: -30New value: +50 - changed
Input schema / properties / poll / properties / question / descriptionPrevious 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." - added
Input schema / properties / post_languageAdded 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" +} - added
Input schema / properties / threads_link_cardAdded 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" +} - added
Input schema / properties / threads_reply_controlAdded 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" +} - added
Input schema / properties / threads_topicAdded value: +{ + "description": "Threads: the post's topic, 1–50 characters, no period or ampersand (e.g. Recipes).", + "maxLength": 50, + "type": "string" +}
- Changed
list_channels1 field changed- changed
Input schema / properties / network / enumPrevious value: -[ - "FACEBOOK", - "INSTAGRAM", - "LINKEDIN", - "TIKTOK", - "YOUTUBE", - "X", - "BLUESKY", - "TELEGRAM", - "WHATSAPP" -]New value: +[ + "FACEBOOK", + "INSTAGRAM", + "LINKEDIN", + "TIKTOK", + "YOUTUBE", + "X", + "BLUESKY", + "TELEGRAM", + "MASTODON", + "THREADS", + "WHATSAPP" +]
- Changed
list_posts1 field changed- changed
Input schema / properties / network / enumPrevious value: -[ - "FACEBOOK", - "INSTAGRAM", - "LINKEDIN", - "TIKTOK", - "YOUTUBE", - "X", - "BLUESKY", - "TELEGRAM", - "WHATSAPP" -]New value: +[ + "FACEBOOK", + "INSTAGRAM", + "LINKEDIN", + "TIKTOK", + "YOUTUBE", + "X", + "BLUESKY", + "TELEGRAM", + "MASTODON", + "THREADS", + "WHATSAPP" +]
- Changed
update_post23 fields changed- changed
Input schema / properties / alt_texts / descriptionPrevious 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." - changed
Input schema / properties / caption / descriptionPrevious 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." - added
Input schema / properties / content_warningAdded 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" +} - changed
Input schema / properties / cover_media_id / descriptionPrevious 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\"." - added
Input schema / properties / mastodon_visibilityAdded 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" +} - added
Input schema / properties / per_channel / items / properties / content_warningAdded 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" +} - added
Input schema / properties / per_channel / items / properties / mastodon_visibilityAdded 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" +} - changed
Input schema / properties / per_channel / items / properties / poll / descriptionPrevious 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." - changed
Input schema / properties / per_channel / items / properties / poll / properties / options / descriptionPrevious value: -"2–4 answers: X ≤25 characters each, LinkedIn ≤30."New value: +"2–4 answers: X ≤25 characters each, LinkedIn ≤30, Mastodon ≤50." - changed
Input schema / properties / per_channel / items / properties / poll / properties / options / items / maxLengthPrevious value: -30New value: +50 - changed
Input schema / properties / per_channel / items / properties / poll / properties / question / descriptionPrevious 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." - added
Input schema / properties / per_channel / items / properties / post_languageAdded 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" +} - added
Input schema / properties / per_channel / items / properties / threads_link_cardAdded 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" +} - added
Input schema / properties / per_channel / items / properties / threads_reply_controlAdded 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" +} - added
Input schema / properties / per_channel / items / properties / threads_topicAdded value: +{ + "description": "Threads: the post's topic, 1–50 characters, no period or ampersand (e.g. Recipes).", + "maxLength": 50, + "type": "string" +} - changed
Input schema / properties / poll / descriptionPrevious 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." - changed
Input schema / properties / poll / properties / options / descriptionPrevious value: -"2–4 answers: X ≤25 characters each, LinkedIn ≤30."New value: +"2–4 answers: X ≤25 characters each, LinkedIn ≤30, Mastodon ≤50." - changed
Input schema / properties / poll / properties / options / items / maxLengthPrevious value: -30New value: +50 - changed
Input schema / properties / poll / properties / question / descriptionPrevious 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." - added
Input schema / properties / post_languageAdded 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" +} - added
Input schema / properties / threads_link_cardAdded 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" +} - added
Input schema / properties / threads_reply_controlAdded 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" +} - added
Input schema / properties / threads_topicAdded value: +{ + "description": "Threads: the post's topic, 1–50 characters, no period or ampersand (e.g. Recipes).", + "maxLength": 50, + "type": "string" +}
- Changed
validate_post23 fields changed- changed
Input schema / properties / alt_texts / descriptionPrevious 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." - changed
Input schema / properties / caption / descriptionPrevious 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." - added
Input schema / properties / content_warningAdded 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" +} - changed
Input schema / properties / cover_media_id / descriptionPrevious 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\"." - added
Input schema / properties / mastodon_visibilityAdded 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" +} - added
Input schema / properties / per_channel / items / properties / content_warningAdded 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" +} - added
Input schema / properties / per_channel / items / properties / mastodon_visibilityAdded 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" +} - changed
Input schema / properties / per_channel / items / properties / poll / descriptionPrevious 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." - changed
Input schema / properties / per_channel / items / properties / poll / properties / options / descriptionPrevious value: -"2–4 answers: X ≤25 characters each, LinkedIn ≤30."New value: +"2–4 answers: X ≤25 characters each, LinkedIn ≤30, Mastodon ≤50." - changed
Input schema / properties / per_channel / items / properties / poll / properties / options / items / maxLengthPrevious value: -30New value: +50 - changed
Input schema / properties / per_channel / items / properties / poll / properties / question / descriptionPrevious 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." - added
Input schema / properties / per_channel / items / properties / post_languageAdded 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" +} - added
Input schema / properties / per_channel / items / properties / threads_link_cardAdded 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" +} - added
Input schema / properties / per_channel / items / properties / threads_reply_controlAdded 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" +} - added
Input schema / properties / per_channel / items / properties / threads_topicAdded value: +{ + "description": "Threads: the post's topic, 1–50 characters, no period or ampersand (e.g. Recipes).", + "maxLength": 50, + "type": "string" +} - changed
Input schema / properties / poll / descriptionPrevious 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." - changed
Input schema / properties / poll / properties / options / descriptionPrevious value: -"2–4 answers: X ≤25 characters each, LinkedIn ≤30."New value: +"2–4 answers: X ≤25 characters each, LinkedIn ≤30, Mastodon ≤50." - changed
Input schema / properties / poll / properties / options / items / maxLengthPrevious value: -30New value: +50 - changed
Input schema / properties / poll / properties / question / descriptionPrevious 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." - added
Input schema / properties / post_languageAdded 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" +} - added
Input schema / properties / threads_link_cardAdded 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" +} - added
Input schema / properties / threads_reply_controlAdded 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" +} - added
Input schema / properties / threads_topicAdded value: +{ + "description": "Threads: the post's topic, 1–50 characters, no period or ampersand (e.g. Recipes).", + "maxLength": 50, + "type": "string" +}
5 tool updates
- Changed
create_post4 fields changed- changed
Input schema / properties / caption / descriptionPrevious 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." - changed
Input schema / properties / cover_media_id / descriptionPrevious 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." - added
Input schema / properties / per_channel / items / properties / telegram_silentAdded value: +{ + "description": "Telegram: send without a sound, so channel subscribers get no notification.", + "type": "boolean" +} - added
Input schema / properties / telegram_silentAdded value: +{ + "description": "Telegram: send without a sound, so channel subscribers get no notification.", + "type": "boolean" +}
- Changed
list_channels1 field changed- changed
Input schema / properties / network / enumPrevious value: -[ - "FACEBOOK", - "INSTAGRAM", - "LINKEDIN", - "TIKTOK", - "YOUTUBE", - "X", - "BLUESKY", - "WHATSAPP" -]New value: +[ + "FACEBOOK", + "INSTAGRAM", + "LINKEDIN", + "TIKTOK", + "YOUTUBE", + "X", + "BLUESKY", + "TELEGRAM", + "WHATSAPP" +]
- Changed
list_posts1 field changed- changed
Input schema / properties / network / enumPrevious value: -[ - "FACEBOOK", - "INSTAGRAM", - "LINKEDIN", - "TIKTOK", - "YOUTUBE", - "X", - "BLUESKY", - "WHATSAPP" -]New value: +[ + "FACEBOOK", + "INSTAGRAM", + "LINKEDIN", + "TIKTOK", + "YOUTUBE", + "X", + "BLUESKY", + "TELEGRAM", + "WHATSAPP" +]
- Changed
update_post4 fields changed- changed
Input schema / properties / caption / descriptionPrevious 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." - changed
Input schema / properties / cover_media_id / descriptionPrevious 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." - added
Input schema / properties / per_channel / items / properties / telegram_silentAdded value: +{ + "description": "Telegram: send without a sound, so channel subscribers get no notification.", + "type": "boolean" +} - added
Input schema / properties / telegram_silentAdded value: +{ + "description": "Telegram: send without a sound, so channel subscribers get no notification.", + "type": "boolean" +}
- Changed
validate_post4 fields changed- changed
Input schema / properties / caption / descriptionPrevious 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." - changed
Input schema / properties / cover_media_id / descriptionPrevious 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." - added
Input schema / properties / per_channel / items / properties / telegram_silentAdded value: +{ + "description": "Telegram: send without a sound, so channel subscribers get no notification.", + "type": "boolean" +} - added
Input schema / properties / telegram_silentAdded value: +{ + "description": "Telegram: send without a sound, so channel subscribers get no notification.", + "type": "boolean" +}
5 tool updates
- Changed
create_post4 fields changed- changed
Input schema / properties / alt_texts / descriptionPrevious 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." - changed
Input schema / properties / caption / descriptionPrevious 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." - changed
Input schema / properties / cover_first_frame / descriptionPrevious 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." - changed
Input schema / properties / cover_media_id / descriptionPrevious 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\"."
- Changed
list_channels1 field changed- changed
Input schema / properties / network / enumPrevious value: -[ - "FACEBOOK", - "INSTAGRAM", - "LINKEDIN", - "TIKTOK", - "YOUTUBE", - "X", - "WHATSAPP" -]New value: +[ + "FACEBOOK", + "INSTAGRAM", + "LINKEDIN", + "TIKTOK", + "YOUTUBE", + "X", + "BLUESKY", + "WHATSAPP" +]
- Changed
list_posts1 field changed- changed
Input schema / properties / network / enumPrevious value: -[ - "FACEBOOK", - "INSTAGRAM", - "LINKEDIN", - "TIKTOK", - "YOUTUBE", - "X", - "WHATSAPP" -]New value: +[ + "FACEBOOK", + "INSTAGRAM", + "LINKEDIN", + "TIKTOK", + "YOUTUBE", + "X", + "BLUESKY", + "WHATSAPP" +]
- Changed
update_post4 fields changed- changed
Input schema / properties / alt_texts / descriptionPrevious 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." - changed
Input schema / properties / caption / descriptionPrevious 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." - changed
Input schema / properties / cover_first_frame / descriptionPrevious 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." - changed
Input schema / properties / cover_media_id / descriptionPrevious 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\"."
- Changed
validate_post4 fields changed- changed
Input schema / properties / alt_texts / descriptionPrevious 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." - changed
Input schema / properties / caption / descriptionPrevious 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." - changed
Input schema / properties / cover_first_frame / descriptionPrevious 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." - changed
Input schema / properties / cover_media_id / descriptionPrevious 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\"."
3 tool updates
- Changed
create_post1 field changed- added
Input schema / properties / per_channel / items / properties / delay_minutesAdded 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" +}
- Changed
update_post1 field changed- added
Input schema / properties / per_channel / items / properties / delay_minutesAdded 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" +}
- Changed
validate_post1 field changed- added
Input schema / properties / per_channel / items / properties / delay_minutesAdded 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" +}
1 tool update
- Changed
invite_member4 fields changed- added
Input schema / properties / role / defaultAdded value: +"viewer" - changed
Input schema / properties / role / descriptionPrevious 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." - changed
Input schema / properties / role / enumPrevious value: -[ - "editor", - "viewer" -]New value: +[ + "viewer" +] - changed
Input schema / requiredPrevious value: -[ - "email", - "role" -]New value: +[ + "email" +]
39 tool updates
- First observed
cancel_post - First observed
create_auto_reply - First observed
create_connect_link - First observed
create_group - First observed
create_post - First observed
create_webhook - First observed
create_workspace - First observed
delete_auto_reply - First observed
delete_comment - First observed
delete_post - First observed
delete_webhook - First observed
get_analytics - First observed
get_approval - First observed
get_claim_link - First observed
get_holidays - First observed
get_post - First observed
get_structure - First observed
hide_comment - First observed
invite_member - First observed
list_auto_replies - First observed
list_auto_reply_activity - First observed
list_channels - First observed
list_comments - First observed
list_groups - First observed
list_members - First observed
list_notifications - First observed
list_posts - First observed
list_webhooks - First observed
list_workspaces - First observed
reply_to_comment - First observed
request_approval - First observed
schedule_post - First observed
send_test_webhook - First observed
set_x_budget - First observed
update_auto_reply - First observed
update_post - First observed
upload_media_from_url - First observed
validate_post - First observed
whoami
Related MCP Connectors
Schedule and publish social posts to Instagram, TikTok, X, LinkedIn, YouTube and five more networks.
Schedule posts to Instagram, TikTok, LinkedIn, X and 6 more. Track analytics and reply to comments.
Schedule, publish and track posts on X, Instagram, LinkedIn, TikTok, YouTube, Threads and Bluesky.
Schedule, publish, and analyze social posts across TikTok, Instagram, YouTube, X, LinkedIn + 5 more.
Related MCP Servers
AlicenseAqualityBmaintenanceSchedule, publish, and measure social posts on Facebook, Instagram, TikTok, LinkedIn, Threads, Pinterest, and X for one brand or many.34MIT- -
- AlicenseAqualityDmaintenanceAI-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.6MIT
- FlicenseAqualityCmaintenanceSchedule and manage social media posts across Facebook, Instagram, Twitter/X, LinkedIn, YouTube, TikTok, and Pinterest directly from Claude.10-
Glama MCP Gateway
Add one secure layer between your agents and this server.