Hermoso
OfficialHermoso is a full-stack AI marketing platform enabling AI agents to run end-to-end marketing operations: research competitors, generate ads, publish to social channels, and manage paid campaigns across multiple networks.
Ad Research & Competitive Intelligence
Search Meta, Google, LinkedIn ad libraries and organic social (TikTok, Instagram, YouTube, Reddit, Threads)
Find competitors by domain and pull their running ads
Tear down competitor strategies into playbooks, mine customer angles from reviews/social
Analyze video ads (structure, transcripts) and fetch long-tail social data via ScrapeCreators
Creative Generation
Plan ad concepts with copy variants and storyboards
Render finished video ads via Studio pipeline, generate raw images, videos, talking avatars, voiceovers, and text with multiple AI models
Create native-feel template ads (iMessage, ChatGPT chat, carousels, etc.)
Fan out variations and score/rank ads
Post-Production
Reframe, upscale, dub videos; swap voices; add film grain/DR proof pills
Fix individual beats, stitch multi-scene videos, trim, speed adjustments, motion recast
Remix competitor static ads into on-brand versions
Publishing & Scheduling
Publish to Facebook, Instagram, Threads, TikTok, YouTube, X, LinkedIn (profiles/pages), Pinterest, Google Business Profile
Schedule, list, and cancel posts across channels
Upload local or external files for use in posts
Ad Campaign Management
Full management for Meta, Google Ads, LinkedIn Ads, Pinterest Ads, Microsoft Advertising, ChatGPT Ads
Create, list, report, update budgets/status, delete campaigns (created paused, spend changes confirm-gated)
Upload assets, pull performance insights (spend, impressions, CTR, CPC, conversions)
File & Document Management
CRUD files on Google Drive, OneDrive; read/write Google Sheets and Docs
Upload files to public URLs; browse workspace asset library; fetch render job details
Workspace & Account
Manage brand workspaces, team members, roles, connectors, skills, AI employees
Handle billing: check credits, buy packs, upgrade plans, auto-reload
Store workspace memory, lock product photos, check ad policy compliance
Allows publishing to Facebook Pages, managing posts, listing Pages and ad accounts, and creating/managing Facebook ad campaigns through Meta's APIs.
Provides Google Ads campaign management (list, report, create, budget, status) and access to the Google Ads Transparency Library for ad research.
Enables creating and appending to Google Docs documents.
Offers full CRUD for Google Drive files and folders, including saving assets and organizing them.
Supports creating spreadsheets, appending rows, and reading data from Google Sheets.
Allows publishing images and Reels to a linked Instagram business account, and searching Instagram Reels for creative research.
Provides management of Meta advertising campaigns across Meta's ad platform, including campaign/ad set/ad creation, budget and status controls, and performance insights.
Allows managing ad campaigns on OpenAI's Advertiser API (ChatGPT Ads), including listing, creating, reporting, and adjusting campaigns.
Enables posting to Pinterest boards and managing Pinterest Ads campaigns.
Supports searching Reddit posts to mine customer language, pain points, and trends for ad research.
Allows posting to Threads and searching Threads posts for social trend and voice research.
Provides publishing to TikTok and searching TikTok videos for hooks, trends, and creative inspiration.
Allows posting videos to YouTube, updating video metadata, retrieving video insights and comments, and searching YouTube for content research.
Hermoso — MCP, CLI & Skills
Run your whole marketing operation from any AI agent: Claude Code, Claude.ai, Cursor, Codex, or your own scripts. Research the ads already winning in a market, generate finished image & video ads (your real product composited in, copy + CTA included), publish them to your own social channels, and build & manage the ad campaigns behind them — all over MCP tools, a CLI, or installable Claude skills.
791 tools. tools/list is always the authoritative set; hermoso_capabilities (free) returns the live model
catalog with exact per-render credit costs plus the full capability map.
What it connects to. Ad platforms: Meta, Google Ads, TikTok Ads, LinkedIn Ads, Reddit Ads, X Ads, Pinterest Ads, Snapchat Ads, Microsoft Advertising, Apple Search Ads and ChatGPT Ads, plus product feeds in Google Merchant Center. Publishing and scheduling — ten channels: Facebook, Instagram, Threads, TikTok, YouTube, X, LinkedIn, Pinterest, Bluesky and Telegram. Messaging: WhatsApp (you message a person, so it is not an eleventh publishing channel). Ad research: the Meta, Google and LinkedIn ad libraries plus organic TikTok, Instagram, YouTube, Threads and Reddit. Analytics: Google Analytics 4, Google Search Console and every connected platform's own post and campaign insights. Files: Google Drive, Sheets, Docs and OneDrive.
It is not all-or-nothing. Research, creation, publishing/scheduling and ads management are four independent
areas — no tool requires that you used another one first. Publish or schedule creative you already have and
generate nothing here (upload_file turns any local or external file into a URL every publish, schedule and
ad-build tool accepts); build and read campaigns on your own ad accounts with your own creative; research
competitors with no brand drafted and no channel connected; or generate a file with nothing connected at all and
just download it. Use the one piece you need, or all of it together.
Which surface should your agent use?
Two shapes, and the right one is decided by what your client can do, not by which we prefer.
Your client | Use | Why |
Runs in a browser — Claude.ai, ChatGPT, Claude Desktop | the hosted connector | It cannot spawn a local process, so a URL is the only shape it has. Nothing to install, no key to paste, and the full toolset arrives with your saved brand context. This is the right answer for these clients, not a lesser one. |
Can run a shell — Claude Code, Cursor, Codex, Cline, OpenClaw, Hermes, your own scripts | the CLI, | A tool manifest is loaded into every session whether or not a tool is called. A shell command costs nothing until it runs, and it reaches every tool rather than the default roster. |
The measured difference (2026-08-27, counted as real tool definitions rather than estimated from bytes):
tools in range | loaded per session | |
Hosted connector, default roster | 306 | 181,713 tokens |
Hosted connector, | 718 | 472,062 tokens |
stdio server ( | 306 | 181,713 tokens |
CLI | all 718 | 0 |
The CLI answers the same questions on demand instead, and only when asked:
npx -y hermoso tools --search reddit # every matching tool, name + one line 2,459 tokens
npx -y hermoso tools plan_ad # one tool's full argument schema 633 tokens
npx -y hermoso call plan_ad --json '{"product":"…"}' # run itSo a terminal agent reaches its first call in roughly 3.4K tokens with the whole roster in range, against
182K for a fraction of it. tools and tools <name> read a registry bundled in the package — no key, no
network, no sign-in — so an agent can browse the entire product before anyone signs in. Only call spends, and
only that needs hermoso auth login once.
Both at once is fine, and is what we suggest for Claude Code. One hermoso auth login covers the CLI and
lets claude mcp add hermoso -- npx -y hermoso mcp pick the key up with no env block, so the agent can reach for
a native tool when it wants structured results and shell out when it wants breadth. If you only want one, take the
CLI: it covers strictly more.
When the connector is still the better trade on a shell-capable client: a session that is going to make many
calls into one area. enable_tools({groups:['ads']}) turns campaign management on in a single free call and the
tools are then native — no shell quoting, structured results. One shell round trip beats loading a 221K-token
group for a single tool; the reverse is true once a session settles into that area.
Related MCP server: Prizmad
Your agent can sign itself up
An agent with no Hermoso account can provision one, get its own key, and be rendering ads in the same session. No human at a browser, no ticket, no waiting.
# 1. Start a signup. This call takes no credential, because the credential is what it creates.
curl -sX POST https://app.hermoso.ai/v1/signup \
-H 'content-type: application/json' \
-d '{"plan":"pro","period":"mo","email":"you@yourcompany.com"}'
# -> { "id": "cs_...", "checkout_url": "https://checkout.stripe.com/...", "claim_token": "hsc_...", "email": { "address": "you@yourcompany.com", "verified": false } }
# email = the human behind the account. A verification link goes there; the account works before it is clicked.
# It is a contact mailbox only, never a sign-in. GET /v1/account/email reports the state; POST /v1/account/email/resend re-sends or changes it.
# 2. Pay at checkout_url. Store claim_token first: it is returned only in that response.
# 3. Claim it. Poll until status is "ready".
curl -sX POST https://app.hermoso.ai/v1/signup/cs_.../claim \
-H 'content-type: application/json' \
-d '{"claim_token":"hsc_..."}'
# -> { "status": "ready", "api_key": "hmk_...", "credits": 3000 }That hmk_ key is the same credential everything else on this page takes: /v1, the MCP server, the CLI. Point
your client at it and the full surface is open.
Paying is something a browser-capable agent can already do itself. Checkout is Stripe's own hosted page, so
Claude in Chrome and clients like it complete it unattended today. Everything else is a one-click handoff: send
checkout_url to whoever holds the card. The same shape covers you later, once you are running: buy_credits
and upgrade_plan mint a ready-to-pay link for more credits or a bigger plan, and billing_status reads the
balance any time.
An agent with its own payment credential can pay with no human at all. POST /api/billing/machine-payment
with {"packId": "pack-1k"} answers HTTP 402 carrying a WWW-Authenticate: Payment challenge (Stripe, through the
Machine Payments Protocol); pay the challenge and retry, and the same credit pack lands on the same balance.
GET /api/billing/config lists the packs under machinePayments. Same packs, same prices, no per-call billing.
The agentic path takes a paid plan. Any of them. The free plan is there for a person signing up at app.hermoso.ai, and asking for it here returns a refusal that says so. Nothing is created until the payment completes, so an unpaid signup leaves no account behind and charges nothing.
One thing still wants a person, and it is worth knowing up front. Connecting a social or ad account means an
OAuth consent screen, and a consent screen cannot be completed headlessly on any platform. list_connectors
shows what is already connected and what is not. Everything else runs with no browser at all: research,
generation, publishing to a channel that is already connected, campaign builds, reporting.
Full request and response shapes, plus every other endpoint, are in the OpenAPI document at app.hermoso.ai/openapi.json, served live from the same table that mounts the routes.
Instant: the hosted Claude.ai connector
Paste https://app.hermoso.ai/mcp?src=readme into Claude → Settings → Connectors → Add custom connector, pick
Always required when Claude asks about authentication (its detector suggests "None" because our discovery
handshake is open; "None" would leave every tool call unauthenticated), approve with your Hermoso account, done — the full toolset with your saved brand context, billed to your plan.
Quickstart for Claude Code (one line)
Get an account at app.hermoso.ai — free tier included; plans & credits are the same ones the web Studio uses. Or skip the browser entirely and let your agent sign itself up on a paid plan with
POST /v1/signup(above).Run one line. Your browser opens once to sign in. Nothing to paste, and no key lands in
.claude.json:
npm install -g hermoso && hermoso auth login && claude mcp add hermoso -- npx -y hermoso mcpAsk for what you want, in your normal prompts. Claude Code reaches for a tool, or runs the
hermosocommand in your terminal, whichever the job needs. You type neither.
Ad campaign and analytics tools stay out of the tool list until you switch them on with enable_tools, which
keeps it small. On a machine with no browser, sign in with hermoso auth login --token hmk_… using a key from
Settings → Agents & API, or skip the sign-in and pass the key to the client instead:
claude mcp add hermoso -e HERMOSO_TOKEN=hmk_… -- npx -y hermoso mcpThe hosted URL works in Claude Code too, but it is the worse path there and it is worth knowing why:
claude mcp add --transport http hermoso "https://app.hermoso.ai/mcp?src=readme" is accepted, and then claude mcp list
reports ! Needs authentication because the client will not start the OAuth flow by itself — you have to open a
session, run /mcp, find the server and press Authenticate. Measured against Claude Code 2.1.241 on 2026-08-23.
Your agent now has the full studio with your workspace's context: the brand profile, products, logos and
learned memory you set up in the web app apply automatically (get_brand shows what's saved; omit brand in
plan_ad/plan_variations to use it). Renders bill your Hermoso credits — same prices as the Studio. Only AI model runs and Ad Spy research spend credits; publishing, scheduling, ads management and analytics are free on every plan (X is the one per-call exception).
1. MCP server (stdio) — Claude Code / Cursor / Codex
hermoso mcp runs a stdio MCP server exposing the full toolset. The published hermoso package means no clone —
npx -y hermoso mcp fetches and runs it. Sign in once with the CLI and no key goes into any client config,
because hermoso mcp reads the bearer hermoso auth login stored:
npm install -g hermoso && hermoso auth login && claude mcp add hermoso -- npx -y hermoso mcpCursor / Codex — sign in the same way, then add to mcp.json (Codex uses the TOML equivalent). Drop the env
block entirely if you signed in above; it is there for CI, where the process cannot read your home directory:
{ "mcpServers": { "hermoso": { "command": "npx", "args": ["-y", "hermoso", "mcp"],
"env": { "HERMOSO_API_BASE": "https://app.hermoso.ai", "HERMOSO_TOKEN": "<your token>" } } } }Then ask your agent: “Generate an image ad with Hermoso.”
What the 791 tools cover
Ad spy / research — find_competitors, competitor_teardown, pull_competitor_ads, research_ads; the
Meta / Google / LinkedIn ad libraries (search_meta_ads, search_google_ads, search_linkedin_ads); organic
social (search_tiktok, search_instagram, search_youtube, search_reddit, search_threads);
fetch_social_data, mine_angles, analyze_video, check_ad_policy, list_skills / get_skill.
Create — draft_brand → plan_ad → render_ad (the Studio quality pipeline: composited text, clean speech,
music, brand end card), or generate_image / generate_video / generate_avatar (UGC creators + lip-sync).
The workspace's saved cast is reusable: list_creators returns every saved creator with their portrait url,
save_creator adds one, delete_creator drops one — re-pass a portrait to generate_avatar / generate_video /
recast_motion and the SAME person stars in every ad, instead of a new face each render.
Also make_template_ad (native HTML ad formats), make_explainer, product_sizzle, make_thumbnail,
remix_static, recast_motion, reframe_video, upscale_video, dub_video, change_voice, finish_video,
fix_beat, stitch_video, clip_video, post_edit, plus plan_variations + score_ad to fan out and rank.
Length is yours to set: pass durationSeconds to plan_ad and the storyboard is authored to it — a length
that fits one clip of the render model renders as a single continuous take, longer is stitched from acts (on a
15s-clip model, 40s = 15+15+10), never time-compressed. What fits one clip is the model's own maximum, not a fixed
number: most video models cap a clip at 15 seconds and the longest-clip one takes 30 seconds in one unbroken
take with native synchronized audio. hermoso_capabilities is the live list — durations, resolutions and the
exact credit cost of every tier — and naming that model in model is how you get it, since an unnamed render is
routed by a narrower auto-pool.
Raw model playground — the full catalog (30+ image / video / voice / writing models, each with its exact
per-render credit cost) with no ad framing: generate_image / generate_video with useBrand:false,
generate_voice, generate_text.
Publish to your own channels — ten of them: Facebook, Instagram and Threads (post_to_meta), TikTok
(post_to_tiktok), YouTube (post_to_youtube + update_youtube_video, youtube_video_insights, comments
read/reply), X (post_to_x, x_post_metrics, x_post_insights, x_mentions, list_x_dms, send_x_dm),
LinkedIn profile and company Pages (post_to_linkedin, post_to_linkedin_page), Pinterest
(post_to_pinterest + boards), Bluesky (post_to_bluesky, delete_bluesky_post, bluesky_post_metrics, plus
list_bluesky_convos / read_bluesky_dm / send_bluesky_dm) and Telegram (post_to_telegram,
delete_telegram_message, list_telegram_chats). schedule_post / list_scheduled / cancel_scheduled give
you one content calendar over exactly that set. upload_file brings in any external or local media, not just
Hermoso renders.
X posting bills credits per API call (X charges per request); a post containing a link costs 13× one without.
Held back, and named rather than hidden: Google Business Profile is built (post_to_google_business,
reviews, Q&A, insights) and is not offered — Google allowlists that API per project and ours reads 0 QPM, so
every call would 403 for every user. It is in schedule_post's channel enum and refused at enqueue.
Message customers on WhatsApp — messaging, not an eleventh publishing channel: you message a person, and
nothing here posts to a feed. list_whatsapp_accounts finds the Business Account and its
numbers, list_whatsapp_templates / create_whatsapp_template / delete_whatsapp_template manage the templates
Meta reviews, and send_whatsapp_message sends one — confirm-gated, because it reaches a real phone and Meta
bills the business for the conversation. Two limits that are permanent facts about Meta's API rather than
anything pending: Hermoso does not receive WhatsApp webhooks, so there is no message history to read — it is
not an inbox surface and list_inbox does not cover it — and outside the 24-hour window that opens when the
customer messages first, WhatsApp accepts an APPROVED template and nothing else.
Run the ads — full campaign trees, built paused and read back before anything is reported, with every spend
change confirm-gated, on eleven platforms: Meta, Google Ads, LinkedIn Ads, Reddit Ads,
Pinterest Ads, Microsoft Advertising, ChatGPT Ads (OpenAI's Advertiser API), X Ads, TikTok Ads,
Snapchat Ads and Apple Ads (Apple Search Ads on the App Store). Each has list + report + create + budget/status tools
(e.g. list_google_ads_campaigns, google_ads_report, create_google_ads_campaign, set_google_ads_budget,
set_google_ads_status). Snapchat needs one extra step the others do not: an ad points at a CREATIVE, and every
Snapchat creative must carry a Public Profile id — build it with upload_snapchat_ads_creative.
Feed the shopping surfaces — Google Merchant Center is the catalog a retail Performance Max or Shopping
campaign advertises (create_google_ads_performance_max_campaign takes a merchantCenterId), and you manage it
from here: accounts and account status, data sources, product upsert / update / delete, per-region inventory,
quota, merchant_report for product-level performance, notifications and conversion sources, plus the disapproval
loop — list_merchant_issues says what is wrong and merchant_issue_help returns Google's own documented fix.
Promotions need the merchant's own enrolment in Google's promotions program; without it Google refuses that
sub-API outright. Microsoft Merchant Center is covered on the same shape (stores, catalogs, products, issues)
for Bing Shopping.
Measure what the ads achieved — Google Analytics 4 closes the loop. Every other connector here reports what an
ad cost; this is the one that reports what it did. analytics_report breaks sessions, users, conversions and
revenue down by channel, source/medium, campaign, landing page, country, device or date, so the campaign Hermoso
built and the revenue it drove sit in one conversation. analytics_realtime shows who is on the site right now.
Start at list_analytics_properties — the tools take a numeric property id, not the G-XXXXXXXXX Measurement ID
from your tracking snippet, and this is what resolves one from the other. It writes as well as reads:
create_analytics_key_event marks an event GA4 already collects as a key event — which is what makes it importable
into Google Ads as a conversion — and create_analytics_custom_dimension registers an event parameter so reports
can break down by it, with list_analytics_definitions showing what the property already measures. It signs in
with the same Google account as Google Ads, YouTube and Drive, but it is its own connection.
GA4 only — the API has no Universal Analytics surface. A custom dimension can be archived but never deleted, and a
property holds 50 event-scoped ones.
Files — Google Drive CRUD (save_to_drive, list_drive_files, update_drive_file, delete_drive_file,
create_drive_folder), Google Sheets (create_sheet, append_to_sheet, read_sheet), Google Docs
(create_doc, append_to_doc), and OneDrive (save_to_onedrive + full CRUD).
Workspace & account — brand workspaces (list_brands, create_brand, use_brand, update_brand,
delete_brand — one account holds many brands, so an agency runs every client through here), memory
(remember, forget, list_memory), custom skills (save_skill, get_skill, list_skills,
delete_skill — the one library, which absorbed the old AI-Employee personas), team (list_team, invite_member, remove_member,
set_role), settings (get_settings, update_settings — including the language every ad, script and plan
is written in), connectors (list_connectors, list_connector_accounts, set_connector_accounts,
disconnect_connector), and billing (hermoso_credits, billing_status, buy_credits, upgrade_plan,
set_auto_reload), plus list_jobs / get_job for async renders.
Connector accounts are picked, not guessed. One person often administers several Facebook Pages, Google Ads customers or LinkedIn company Pages. Only the accounts ticked for a brand are usable — enforced server-side, and an empty selection shares nothing. Linking a new account is the one step that is not headless (it is an OAuth consent screen, so the user does it in the app).
Render jobs queue server-side and poll to completion, returning a served URL.
2. CLI — the token-cheap path for terminal agents
bin/hermoso.mjs exposes the full MCP toolset as subprocess commands, so an agent can shell out instead of carrying a
fat tool manifest.
npm install -g hermoso # installs `hermoso`
hermoso capabilities # valid model ids + costs (run first)
hermoso create --brand "YourBrand" --product "your best-selling product" --format image
hermoso generate image --prompt "…" --ref ./product.png --wait
hermoso generate video --prompt "…" --duration 8 --wait
hermoso competitors yourbrand.com
hermoso research "Liquid Death’s longest-running ads"Add --json to any command for machine output.
Those shortcuts are the common path, not the limit. Every tool the MCP server has is reachable here too, including the ad-campaign and analytics groups a connector leaves out of its default roster:
hermoso tools # every tool, grouped, name + one line
hermoso tools --group ads --search reddit # narrow it
hermoso tools create_meta_campaign # that tool's full argument schema
hermoso call create_meta_campaign --json '{"name":"…"}' # run it
hermoso create_meta_campaign --name "…" # same thing, shortercall goes through the same handler, the same argument validation and the same confirm/spend gates the MCP
server uses — there is no second implementation to drift. tools and tools <name> read a registry bundled in
the package, so they need no key, no network and no sign-in.
3. Claude skills — slash commands that wrap the CLI
skills/ holds four installable skills: hermoso-generate, hermoso-ad-from-brand,
hermoso-product-photoshoot, hermoso-research.
cp -r skills/* ~/.claude/skills/Then invoke /hermoso-ad-from-brand an ad for yourbrand.com — our hero product.
Configuration
Env | Meaning |
| The Hermoso API origin (default |
| Bearer agent key ( |
| Brand-workspace id, for accounts with multiple brand profiles |
| Only for a brand another account shared with you (a team workspace): the owning account id. Set it together with |
mcp/http.mjs is the hosted remote-connector transport (paste-a-URL into Claude.ai → Connectors). It ships in
this repo for transparency and refuses to mount without authenticated identity — no anonymous spend, ever.
License
MIT © Hermoso
Available Tools
169 toolsanalyze_videoAnalyze videoARead-onlyInspect
Break a video ad down into its structure: the verbatim transcript (voiceover + on-screen text) with a beat list, plus duration and sampled frame timestamps. Use to study a reference/competitor ad before remixing its structure. Costs ~a transcription call.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | the video URL (a served /generated/ path or a public http(s) video) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint true, openWorldHint true, and destructiveHint false. The description adds useful behavioral context beyond this: it mentions 'Costs ~a transcription call,' which warns about resource consumption. It also specifies the outputs (transcript, beat list, timestamps) without contradicting any annotation.
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, no fluff. Front-loaded with the core function, then adds usage context and cost. Every sentence earns its place, and the structure is efficient.
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 tool with a single parameter and no output schema, the description adequately explains the return value (transcript, beat list, duration, timestamps) and the expected use case. It even mentions cost, which helps the agent plan. Nothing critical 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%, so the parameter is already documented ('the video URL...'). The description does not add extra meaning about the parameter itself. Baseline of 3 applies because the schema fully covers it.
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?
Description states a specific verb ('Break down') and resource ('video ad'), and precisely lists what it produces: verbatim transcript, beat list, duration, and sampled frame timestamps. It clearly distinguishes itself from sibling tools like finish_video or clip_video, which have different purposes.
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?
Provides explicit context: 'Use to study a reference/competitor ad before remixing its structure.' This clearly indicates when to use it. It does not mention alternatives or when not to use, but for a single-purpose analysis tool, the guidance is sufficient.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
append_to_docAppend text to a Google DocAInspect
Append text to the end of a Google Doc Hermoso can reach — one it created (pass the documentId from create_doc) or one the user handed over with the Google file picker in the app (find its id with list_drive_files).
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | text to append at the end of the doc | |
| documentId | Yes | the document id from create_doc |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false and destructiveHint=false, so the safety profile is covered. The description adds the 'Hermoso can reach' limitation and clarifies the non-destructive nature by saying 'append', but doesn't disclose error behavior or side effects. With openWorldHint=true, the description adequately supplements but doesn't go beyond what annotations expect.
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?
Single sentence that front-loads the core action and scope. The phrase 'Hermoso can reach' is slightly verbose but necessary to convey the limitation. Minimal waste; could be trimmed slightly but is efficient.
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 append tool with two parameters and no output schema, the description covers the essentials: what it does, how to get the ID, and the reachability constraint. Error cases are not described, but given the low complexity and annotations, this is adequate.
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 covers 100% of parameters, but the description adds meaning beyond schema. The schema's documentId description only mentions 'from create_doc', while the tool description extends it to include 'list_drive_files', providing a more accurate and complete source. Text description is straightforward.
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?
Clearly states the verb 'append' and resource 'Google Doc', and further narrows scope to docs Hermoso can reach (created or user-provided). Distinguishes from siblings like create_doc, update_doc, and read_doc by focusing on appending to the end and specifying how to obtain the documentId.
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?
Provides explicit guidance on when to use: when appending to the end of a reachable doc, and offers two methods to source the documentId (from create_doc or list_drive_files). It does not explicitly exclude alternatives like update_doc, but the scope is clear enough for correct selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
append_to_sheetAppend rows to a Google SheetAInspect
Append rows to a Google Sheet Hermoso can reach — one it created (pass the spreadsheetId from create_sheet) or one the user handed over with the Google file picker in the app (find its id with list_drive_files). rows = array of row arrays.
| Name | Required | Description | Default |
|---|---|---|---|
| rows | Yes | rows to append — array of row arrays | |
| range | No | range to append at (default A1 / first sheet) | |
| spreadsheetId | Yes | the spreadsheet id from create_sheet |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint=false and idempotentHint=false, signaling a mutating, non-idempotent operation. The description adds the reachability constraint (created vs. user-shared sheets) which is valuable context beyond annotations. No contradiction exists, and it explains the source of valid spreadsheet IDs.
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 two sentences with no fluff. It front-loads the core purpose and then delivers key details about eligibility and the rows format. Every phrase contributes to understanding, making it highly concise and well-structured.
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 append tool with three parameters and no output schema, the description covers the essential information: what it does, which sheets are valid, how to obtain IDs, and the format of rows. The optional range parameter is documented in the schema, so the description need not repeat it. It is complete enough for an agent to call 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 100% for all parameters, giving a baseline of 3. The description adds meaningful context beyond the schema by explaining that spreadsheetId can come from create_sheet or list_drive_files, which clarifies the allowed values. For 'rows', it repeats the schema description, but the added id-source info justifies a 4.
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 the action 'Append rows' and the resource 'Google Sheet', and explicitly defines the set of reachable sheets (created by Hermoso or handed over via file picker). This distinguishes it from sibling tools like update_sheet, clear_sheet_range, and read_sheet, making the tool's purpose 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?
It gives concrete guidance on how to obtain the spreadsheetId — via create_sheet or list_drive_files — and specifies the condition of which sheets are eligible. It does not explicitly state when not to use the tool versus alternatives, but the tool name and purpose make that distinction clear, so the guidance is adequate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
backfill_postsImport a channel’s past postsAIdempotentInspect
Import this brand's PAST posts from a channel into the performance record, so 'which hook works' can draw on history rather than only on what was published since Hermoso started recording. Supports facebook, instagram, threads, youtube, tiktok, pinterest and bluesky; the others say plainly why they cannot (LinkedIn and Reddit have no enumerate-my-posts endpoint on our grant, X bills per read so it is excluded from bulk import, Google Business has had no per-post insights since 2023, and Telegram's Bot API cannot read a chat's past messages at all — nothing published before Hermoso is recoverable through a bot token). BOUNDED, RESUMABLE AND QUOTED: it runs as a DRY RUN by default and tells you how many posts it found and what reading them will cost — pass confirm:true to import, and pass the returned cursor to continue. AN IMPORTED POST IS WEAKER EVIDENCE THAN A RECORDED ONE and is labelled 'backfilled': its hook is recovered ONLY where the post matches a Hermoso creation by asset or caption. A post made outside Hermoso stays UNATTRIBUTED — it counts toward channel and format totals but never votes on which hook works. Never guess a hook from a caption. Free.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | how many posts this page (default 50, max 200) | |
| cursor | No | resume from a previous run | |
| channel | Yes | which channel to import from | |
| confirm | No | actually import — omit for a dry run that only quotes the cost | |
| accountRef | No | which Page / account, when the brand has more than one |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations (readOnlyHint=false, idempotentHint=true, destructiveHint=false), the description discloses the dry-run default and confirmation requirement, the cost quoting, the resumability, and the crucial caveat that imported posts are weaker evidence, labelled 'backfilled', with hooks only recovered under specific conditions. It also warns 'Never guess a hook from a caption.' This is rich, honest behavioral disclosure that goes well beyond the structured 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 description is dense but every sentence earns its place. It front-loads the core purpose, then systematically covers supported channels, exclusions with reasons, the dry-run/confirm/resume workflow, and the evidence caveat. No filler or repetition; the length is justified by the tool's complexity. The structure uses punctuation effectively to keep it readable.
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 complex tool with 5 parameters, no output schema, and nuanced behavior, the description provides everything an agent needs to call it correctly: what it does, which channels work, why others don't, the default dry-run behavior, how to confirm, how to resume with a cursor, and what happens to imported posts regarding evidence. Even the return value is hinted at ('tells you how many posts it found and what reading them will cost'). Nothing critical 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%, so the schema already documents all five parameters. However, the description adds essential contextual meaning: it explains that limit caps the page size (default 50, max 200), that cursor is for resuming, and that confirm:true is the flag to actually import while omitting it triggers a dry run. It also clarifies accountRef for multiple accounts. This is meaningful added value beyond the schema 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 opens with a clear verb-resource pair: 'Import this brand's PAST posts from a channel into the performance record.' It names the exact purpose (feeding 'which hook works' with history) and lists all supported channels, which distinguishes it from posting, insight, and metrics tools in the sibling set. There is no ambiguity about what this tool accomplishes.
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 explicit workflow guidance: it runs as a DRY RUN by default, requires confirm:true to import, and uses the returned cursor to resume. It also states the intended scenario ('draw on history rather than only on what was published since Hermoso started recording'), and even explains why certain channels are excluded, which prevents inappropriate attempts. This is far above the minimum.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
billing_statusBilling statusARead-onlyInspect
Show this account's billing at a glance: current plan (id + label + the price it is ACTUALLY billed — quote plan.priceUsd per plan.period, not plan.monthlyUsd), credit balance, whether auto-reload is on, whether a card is on file, and whether YOU (this key) have ADMIN rights to change billing. Read-only, free. Call it before upgrade_plan / set_auto_reload to know what's possible — members have read-only billing. IN A SHARED TEAM WORKSPACE A MEMBER SEES THE PLAN AND THE BALANCE ONLY: the workspace owner's payment card and auto-reload belong to them and are not reported (billingScope:'member'). Never tell a member there is no card on file — the honest answer is that you cannot see it.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, and the description reinforces this with 'Read-only, free'. It adds critical behavioral context beyond annotations: the price field nuance (billing per plan.period, not monthlyUsd), the member-specific visibility limitation (billingScope:'member'), and the instruction to never tell a member there is no card because it cannot be seen. This is exactly the kind of hidden behavior agents need to know.
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 dense but every sentence earns its place: it leads with the core purpose, then details the specific fields, then the critical usage caveats. The shared-workspace warning and the instruction about not misreporting card status are essential to correct agent behavior. It is structured front-loaded and thorough without fluff.
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 zero required parameters and no output schema, the description must fully explain what the tool returns and any caveats. It covers the plan, balance, auto-reload, card, admin rights, and the nuanced member view. It also explains when to use it relative to other tools. Nothing an agent needs 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?
There are zero parameters, so the schema carries no parameter documentation. Per the rubric, 0 params gives a baseline of 4. The description does not need to add parameter meaning since there are none, and it correctly focuses on the output and usage context instead.
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 clear verb and resource: 'Show this account's billing at a glance' and enumerates the specific data returned (plan id/label/price, credit balance, auto-reload, card on file, admin rights). It explicitly distinguishes itself from sibling tools by saying to call it before upgrade_plan / set_auto_reload, so an agent can easily tell it apart.
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 explicitly tells the agent when to use it: 'Call it before upgrade_plan / set_auto_reload' and explains that members have read-only billing, so they cannot change billing. It also provides conditional guidance for shared team workspaces, telling the agent exactly what a member sees and how to answer honestly. This is explicit and actionable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
buy_creditsBuy creditsAInspect
Out of credits? Top up with a credit PACK. Call with no argument to list the available packs (id · credits · price). If the account has a saved card and you have billing-admin rights, calling with pack quotes the exact charge and calling again with confirm:true AND the quote's quote_token charges the saved card instantly (same one-click top-up as the app — no redirect). If there's no saved card yet, you get a Stripe checkout URL to hand your human for the FIRST purchase; their card saves for one-click after that. Packs only; subscriptions are managed by a person in Settings → Billing. IF YOU ARE AN AGENT HOLDING YOUR OWN PAYMENT CREDENTIAL, there is a third path that needs no human at all: POST /api/billing/machine-payment with a packId answers HTTP 402 carrying an MPP challenge, and grants the pack once you authorise and retry with the credential — the same packs, the same prices, the same credits. GET /api/billing/config carries a machinePayments block listing the packs with their per-credit rates and saying whether that lane is enabled on this server. Most agents do NOT have their own credential yet, so the checkout link above remains the normal path. To stop running out entirely, turn on auto-reload with set_auto_reload (admin) — low balances then top themselves up from the saved card automatically.
| Name | Required | Description | Default |
|---|---|---|---|
| pack | No | the pack id to buy (e.g. pack-2k) — omit to list the available packs first | |
| confirm | No | set true to actually charge the saved card for `pack` (required for the one-click charge; ignored on the checkout-link path) | |
| quote_token | No | the quoteToken returned by the quote step — REQUIRED (with confirm:true) to charge; it binds the exact pack + price you quoted (10-minute validity) and makes a retried confirm idempotent |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes far beyond the annotations' readOnlyHint=false and idempotentHint=false: it discloses the two-step quote-then-confirm flow, the 10-minute quote_token validity, that the charge hits the saved card instantly with no redirect, that a first purchase saves the card, the requirement of billing-admin rights, and the HTTP 402 MPP challenge on the machine lane. The 'retried confirm idempotent' note refines (rather than contradicts) idempotentHint=false, since it specifies that only the token-bound confirm step is idempotent while the tool overall is not.
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 long, but it is front-loaded with the simplest entry point ('Call with no argument to list the available packs') and flows logically through the three purchase paths plus the auto-reload alternative. Every sentence carries distinct information needed to avoid wrongly charging a human's card or selecting the wrong payment lane; the density is justified by the payment-flow complexity.
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 full burden of conveying return values — and it does: the pack listing format (id · credits · price), the quote returning a quote_token, the Stripe checkout URL, and the HTTP 402 MPP challenge. It also covers prerequisites (saved card, billing-admin rights, machine credential availability) and the fallback (set_auto_reload). Nothing an agent needs to invoke this tool correctly or choose a path 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 100%, so the baseline is 3 and the schema already documents each parameter's individual meaning. The description adds orchestration semantics beyond the schema: omit `pack` to list, `confirm:true` alone is insufficient without the `quote_token` from the quote step, `quote_token` is ignored on the checkout-link path, and it binds the exact pack+price quoted with a 10-minute validity window. This sequencing and lifecycle info is real added value, though each parameter's core definition remains in 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?
The description names a specific action (top up / buy a credit PACK) and a resource, and enumerates the distinct behaviors: list packs, quote, one-click charge, checkout link, and machine-payment. It differentiates itself from billing-adjacent siblings like billing_status, upgrade_plan, and set_auto_reload without requiring the agent to open any other tool.
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 explicitly routes the agent: 'the checkout link above remains the normal path' for most agents, the machine-payment path only for agents holding their own payment credential, and subscriptions are explicitly out of scope ('managed by a person in Settings → Billing'). It also names the alternative for the underlying problem: 'turn on auto-reload with set_auto_reload (admin)'. When-to-use, when-not-to-use, and alternatives are all stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
call_toolRun any Hermoso tool by nameADestructiveInspect
Run ANY Hermoso tool by name — including the paid-campaign, analytics and channel-admin tools that are not in this session's starting list — with the same permissions, the same account and the same result as calling it directly. Get the exact name and its args from find_tools first. This is the route on hosts that cannot reload their tool list mid-conversation (claude.ai, ChatGPT): enable_tools switches a group on server-side, but such a host keeps the list it fetched at connect time. Arguments are validated against the tool's own schema and a mistake is answered with the expected parameters, not a silent default. Refused by name, with the way out, when the tool needs a connector this workspace has not made or is withheld by the host's own policy.
| Name | Required | Description | Default |
|---|---|---|---|
| args | No | the tool's arguments as an object, exactly as its own schema takes them | |
| name | Yes | the tool name exactly as find_tools returned it, e.g. create_meta_lead_form |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations, the description discloses that invoking through call_tool uses the same permissions, account, and result as a direct call; that arguments are validated against the target tool's schema; that invalid arguments return the expected parameters rather than silently defaulting; and that tools requiring unavailable connectors or withheld by host policy are refused by name with an actionable way out. This is rich, non-obvious behavioral context.
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 earns its place: purpose, source of parameter values, host-specific rationale, validation behavior, and refusal conditions. The most important action and scope are front-loaded, and the length is justified by the complexity and risk of a generic tool dispatcher.
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 the tool's complexity as a dynamic dispatcher and the absence of an output schema, the description fully covers how to invoke it, how to source parameters, what validation behavior to expect, and when/why it may refuse. The statement that results match a direct call also informs the agent about return behavior without needing an output schema.
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. The description adds operational meaning by directing the agent to obtain the exact name and args from find_tools and by explaining that args must match the target tool's own schema, with validation errors surfacing expected parameters. This goes slightly beyond the schema's bare definitions.
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 opens with a specific verb and resource: 'Run ANY Hermoso tool by name', and immediately clarifies its unique scope—it can invoke tools not in the session's starting list, including paid-campaign, analytics, and channel-admin tools. This clearly distinguishes it from the many specific sibling tools and from enable_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?
The description gives explicit when-to-use guidance: it is the route on hosts like claude.ai and ChatGPT that cannot reload their tool list mid-conversation. It also names the alternative (enable_tools) and explains why that alternative fails on such hosts, plus instructs the agent to get the exact name and args from find_tools first.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cancel_scheduledCancel a scheduled postADestructiveIdempotentInspect
Remove a queued post before it goes out. Get the id from list_scheduled. Only works while it is still queued — something already published cannot be unsent (use manage_meta_post to delete a Facebook/Instagram post after the fact).
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | the scheduled post id from list_scheduled |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and idempotentHint=true. The description adds the queued-state precondition and the alternative for published posts, which is useful beyond annotations. It does not contradict 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 waste. The action is front-loaded, followed by source, precondition, and alternative—each sentence 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 one-parameter tool with no output schema and annotations covering destructive/idempotent behavior, the description provides everything an agent needs: what, when, where to get the id, and what to do if it's too late. 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?
Schema coverage is 100% (the 'id' description already says 'the scheduled post id from list_scheduled'). The description reinforces the exact source of the id, adding practical retrieval guidance beyond 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 specific verb ('Remove') and resource ('a queued post') with a clear boundary condition ('before it goes out'). It distinguishes itself from list_scheduled and manage_meta_post, making it unambiguous among siblings.
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 instructs where to get the id ('Get the id from list_scheduled'), states the valid condition ('while it is still queued'), and names the alternative for published posts ('use manage_meta_post'). This fully routes the agent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
change_voiceChange narrator voiceAInspect
Swap the narration of a finished video into a different voice — keeps the performance, lip-sync, and background sound. Use when the user likes the video but wants a different narrator voice; use dub_video only for language translation. Paid; returns the served URL.
| Name | Required | Description | Default |
|---|---|---|---|
| video | Yes | the source video URL | |
| voice | No | target narrator voice preset name, e.g. 'Aria', 'George', 'Rachel', 'Sarah', 'Brian', 'Charlotte' (defaults to a warm female read). A saved VOICE CLONE of the user's own voice counts as a preset here — name it the way it is saved on their cast |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations cover the safety profile (not read-only, not destructive, not idempotent), and the description adds context beyond them: the operation is 'Paid,' it preserves 'the performance, lip-sync, and background sound,' and it 'returns the served URL.' This is meaningful behavioral disclosure consistent with 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?
Three sentences with zero waste: purpose, usage guidance, and cost/return detail. The core scoping constraint is front-loaded ahead of the alternative and cost notes.
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 2-parameter tool with full schema coverage and no output schema, the description covers purpose, selection criteria, cost, preservation guarantees, and return value. Only a minor gap: it does not state whether the tool is synchronous or produces a new render rather than mutating the original video.
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 the baseline is 3; both 'video' and 'voice' are already documented with examples and a default. The description adds no parameter-level detail beyond what the schema provides.
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 opens with a specific verb and resource: 'Swap the narration of a finished video into a different voice.' It distinguishes itself from the closest sibling by stating 'use dub_video only for language translation,' so an agent can tell the two apart without opening either 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 an explicit trigger condition — 'Use when the user likes the video but wants a different narrator voice' — and names the alternative with its exclusive condition: 'use dub_video only for language translation.' Both when-to-use and when-not-to-use are stated with nothing left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
check_ad_policyCheck ad policyARead-onlyInspect
Pre-flight ad copy against Meta's REAL, live Advertising Standards before you run it — a flat 1-credit check. Pulls Meta's actual policy pages and returns a verdict (pass / fix / block) where every flagged issue QUOTES Meta's own policy text verbatim plus a compliant rewrite that keeps the sell. It's a check, not an edit — it never changes the creative. Especially worth running for regulated-adjacent categories (health/supplements, weight-loss or beauty results claims, finance/crypto/insurance, alcohol, dating, gambling) or ANY strong/absolute/guaranteed claim.
| Name | Required | Description | Default |
|---|---|---|---|
| copy | Yes | the ad copy / script / on-screen text to check | |
| claims | No | the claims / proof points the ad makes | |
| category | No | the product category — helps pick the relevant policy pages | |
| imageDescription | No | a description of the creative / image when relevant |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, openWorldHint, and destructiveHint, so the safety profile is known. The description adds valuable behavioral details beyond this: it pulls live Meta policy pages, returns verbatim quotes, provides compliant rewrites, never edits creative, and charges a flat 1 credit. These details enrich the agent's understanding beyond the annotations without 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 core purpose, then explains the method, differentiates it from editing, and gives usage guidance. Every sentence contributes value without excessive verbosity. It is reasonably concise given the amount of contextual information (cost, output format, use cases). Slightly longer than strictly necessary but well-organized.
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 the tool's complexity (live external data, verdicts, verbatim quotes, rewrites) and lack of output schema, the description covers the key operational aspects: return format (verdict, quotes, rewrite), non-destructive behavior, cost, and when to prioritize it. It does not mention rate limits or prerequisites, but these are not critical for basic invocation. The description is complete enough for an agent to use the tool correctly in most scenarios.
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 all parameters are adequately described in the schema. The tool description does not add any param-specific meaning beyond mentioning 'copy' implicitly and referencing categories in the usage guidance. It does not explain how to format or what to include for each parameter beyond the schema, so it does not exceed the baseline.
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 a specific action ('Pre-flight ad copy against Meta's REAL, live Advertising Standards'), identifies the resource (ad copy) and outcome (verdict pass/fix/block). It explicitly differentiates from editing tools by stating 'It's a check, not an edit', which helps distinguish from potential siblings like edit-oriented tools. The purpose is unambiguous and directly actionable.
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 clear context on when to use it: 'before you run it' and for specific regulated-adjacent categories or strong claims. It does not explicitly mention when NOT to use it or name alternative tools, but the guidance is sufficiently contextual to guide an agent. Missing an explicit when-not clause prevents a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
clear_sheet_rangeClear a range in a Google SheetADestructiveIdempotentInspect
Empty a range of cells in a Google Sheet, leaving the rows themselves in place. DESTRUCTIVE: call it WITHOUT confirm first and nothing is cleared — you get back the real number of filled cells in that exact range. Show the user that number, get an unambiguous yes, then call again with confirm:true AND confirmCells set to it. The echo is not ceremony: it is what catches naming A1:Z1000 when you meant A1:Z10, which is the mistake that actually happens. There is deliberately NO default range. The clear is read back and reported as confirmed only if the range really is empty afterwards. To remove a whole tab instead, use manage_sheet_tabs.
| Name | Required | Description | Default |
|---|---|---|---|
| range | Yes | the range to clear, e.g. "A2:D50" or "Sheet1!A2:D50" | |
| confirm | No | ||
| sheetUrl | No | ||
| confirmCells | No | echo back the filled-cell count the unconfirmed call reported | |
| spreadsheetId | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark destructiveHint=true and idempotentHint=true, but the description goes far beyond annotations by disclosing the two-call confirmation mechanism, the 'nothing is cleared' behavior without confirm, the confirmCells echo purpose, and the post-clear readback verification. This is rich behavioral context that annotations alone do not 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?
The description is lengthy but every sentence carries essential operational information: the destructive warning, the confirmation flow, the echo rationale, and the alternative. It is structured logically, starting with the action, then the destructive warning, then the workflow. While not terse, it avoids redundancy and earns its length.
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?
Even without an output schema, the description explains what the user gets back (the number of filled cells on the unconfirmed call, and a confirmation only if the range is truly empty). It also warns about the common range-mistake scenario. This is sufficient for an agent to correctly perform the two-step destructive operation, though it does not describe error cases or edge conditions beyond that.
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 only 40% schema description coverage, the description compensates substantially. It explains the confirm workflow, the confirmCells parameter ('echo back the filled-cell count'), and gives an A1:Z1000 example for range. It does not detail sheetUrl/spreadsheetId, but those are common and not critical for a destructive tool whose main parameters are well explained.
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 ('Empty a range of cells') on a specific resource ('a Google Sheet') and explicitly differentiates from a sibling ('To remove a whole tab instead, use manage_sheet_tabs'). It also clarifies that rows remain in place, leaving no ambiguity about what clearing entails.
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 detailed when-to-use and when-not-to-use guide. It explains the mandatory two-step confirmation workflow, warns about the no-default-range policy, and explicitly names the alternative tool for removing whole tabs. This leaves no inference needed for safe invocation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
clip_videoClip a long videoAInspect
Cut ONE long video into several RANKED, ready-to-post short clips (podcast, webinar, interview, conference talk, long ad cut → Reels/Shorts/TikTok). Transcribes the source with timestamps, picks the strongest SELF-CONTAINED moments, then cuts + reframes each with ffmpeg — no video model renders anything, which is why it's fast and cheap. THE VERTICAL REFRAME IS SUBJECT-AWARE: a few stills per clip go to ONE cheap vision call, which decides a SINGLE crop offset that is held for that clip's whole length — so a speaker sitting camera-left is not cropped out of their own clip, while the framing still never drifts INSIDE a clip (a per-frame crop truncates to whole pixels and shimmers, so it is deliberately not tracked). It costs one small vision call per clip, billed as its own event. When nothing is being discarded, or no single subject can be located, the crop stays dead centre exactly as before — read reframedToSubject and each clip's reframeWhy back off the result rather than assuming either way. ACCEPTS: (a) a YouTube link (or Vimeo / Loom / Dailymotion / Streamable / Rumble / Wistia / Twitch / TED) — the server pulls the video down itself; (b) a direct https .mp4/.mov/.webm; (c) a Hermoso /generated/ URL (upload_file turns a local file into one). NOT supported: TikTok / Instagram / Facebook links, and anything age-restricted, private, members-only, geo-blocked or still LIVE — those fail fast with the real reason and are fully refunded, so ask for a direct file or an upload rather than retrying. Source must be at least ~15s and under ~600MB; only the first ~40 minutes is analysed (the result reports truncated:true when it hits that). Cost: a ~7-credit hold, settled to the exact transcription + encode cost, plus the clip-selection model's tokens billed as their own small event. RETURNS clips[] — each with its OWN served mp4 URL, title, hook, ready-to-post caption, 0-100 score and source timecode — not a single video. SUBTITLES ARE BURNED IN BY DEFAULT — slim white CAPS, thin black outline, bottom safe band, no box and no plate — because short-form is watched on mute; pass captions:false for clean footage. TIMING IS APPROXIMATE, NOT WORD-LEVEL: each cue is anchored to the transcript's own per-sentence timestamp and split inside a sentence by character count, so it tracks the speech closely but is not frame-accurate sync — never promise that. Read captionsBurned back off the result: it counts the clips that actually carry a burned track, and captionNote says why any are bare.
| Name | Required | Description | Default |
|---|---|---|---|
| count | No | how many clips to cut, 1-8 (default 4) | |
| video | Yes | the long video to clip — a YouTube/Vimeo/Loom/Dailymotion/Streamable/Rumble/Wistia/Twitch/TED watch URL, a direct https .mp4/.mov/.webm, or a Hermoso /generated/ URL | |
| captions | No | burn subtitles into every clip. DEFAULT TRUE — a clip cut from a podcast or a talk is watched on mute, and the words are the product. Set false for clean footage. A clip whose window carries no readable speech is delivered bare rather than captioned with a guess, and the result says which. | |
| aspectRatio | No | clip shape — '9:16' (default) vertical for Reels/Shorts/TikTok; 'keep' leaves the source framing untouched |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With annotations present (readOnlyHint:false, destructiveHint:false), the bar is lower, but this description adds exceptional behavioral context: the ~7-credit hold and settlement, the subject-aware reframe algorithm ('a SINGLE crop offset that is held for that clip's whole length'), refund-on-failure behavior, default burned-in subtitles, and the explicit warning that timing is approximate ('never promise that'). It even tells the agent to read reframedToSubject/reframeWhy/captionsBurned rather than assume. Nothing contradicts 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 description is long, but nearly every sentence earns its place: each segment maps to a real agent decision (input choice, exclusion handling, cost awareness, reframe behavior, captions toggle, timing caveat, result-field reading). The core purpose is front-loaded in the first sentence, followed by mechanism, then operational details. It could be tightened slightly, but for a tool with this many edge cases the density is justified.
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?
Since there is no output schema, the description carries the full burden of explaining returns, and it does: 'RETURNS clips[] — each with its OWN served mp4 URL, title, hook, ready-to-post caption, 0-100 score and source timecode — not a single video', plus the interpretable fields reframedToSubject, reframeWhy, captionsBurned, captionNote, and truncated. Inputs, outputs, constraints, cost, and edge-case behavior are all covered, leaving no critical gap for an agent 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 100% and the schema's own parameter descriptions are already rich (video lists all accepted URL types; captions explains the mute-watching rationale; aspectRatio covers defaults and 'keep'). The description adds complementary behavioral context around parameters — the ~600MB/size gate for `video`, the no-speech-window rule for `captions`, and the read-back fields that interpret results. Value is additive but partially duplicative of the schema, so 4 rather than 5.
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 verb+resource+outcome: 'Cut ONE long video into several RANKED, ready-to-post short clips', immediately followed by concrete use cases (podcast, webinar, interview, conference talk, long ad → Reels/Shorts/TikTok). It clearly differentiates from video siblings — reframe_video (reframes), dub_video (audio), stitch_video (concatenates), edit_video — by centering on the 'cut into ranked clips' operation.
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 strong context on accepted input formats and explicit exclusions: 'NOT supported: TikTok / Instagram / Facebook links, and anything age-restricted, private, members-only, geo-blocked or still LIVE', plus actionable advice ('ask for a direct file or an upload rather than retrying'). It also states hard constraints (min ~15s, ~600MB, ~40min window). It stops short of naming sibling tools as explicit alternatives for non-clipping tasks, so it loses a point.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
collect_post_metricsRead how the recorded posts performedAIdempotentInspect
Fetch fresh performance numbers for this brand's recorded posts and store them as a time-series. Metrics ACCRUE, so a post is read at ~24 hours and again at ~7 days; this collects whichever readings are due and skips the ones already taken. A channel that cannot report a metric records it as ABSENT with the reason — never as zero — and a read that fails is recorded as 'could not tell', which contributes to nothing. X IS SKIPPED BY DEFAULT because X bills us per API call: pass includeMetered:true to include it, and tell the user it costs credits BEFORE you do. The skip is always reported so a channel missing from the numbers is never mistaken for one that performed badly. Free except for X.
| Name | Required | Description | Default |
|---|---|---|---|
| max | No | cap how many posts to read in this run (default 40) | |
| includeMetered | No | also read X, which BILLS CREDITS per post read — ask the user first |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare idempotentHint=true and destructiveHint=false, but the description goes far beyond them: it explains accrual and skipping, how missing metrics are recorded as ABSENT (never zero), how failures become 'could not tell', the default skipping of X due to billing, and the requirement to inform the user about credits. This rich disclosure about side effects, cost, and data handling is exactly what an agent needs and exceeds annotation coverage.
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 longer than average but every sentence carries necessary information: accrual schedule, skip behavior, ABSENT vs zero, failure handling, billing for X, and the reporting of skips. It is structured with punctuation and a clear flow. It could be slightly tighter, but the density is justified for a tool with multiple behavioral nuances. Front-loads the core 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?
For a tool with no output schema and moderate complexity, the description is remarkably complete. It tells the agent what it does, when to call it (due readings), how it handles data quirks (ABSENT, 'could not tell'), billing implications (X costs credits), and the need to inform the user. It also notes that skips are always reported, preventing misinterpretation. Nothing critical for selecting or invoking the tool 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%, so both 'max' and 'includeMetered' already have clear descriptions in the schema. The tool description reinforces the billing aspect of includeMetered ('tell the user it costs credits BEFORE you do') but does not add fundamentally new parameter semantics beyond what the schema provides. 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?
The description opens with a clear, specific verb+resource: 'Fetch fresh performance numbers for this brand's recorded posts and store them as a time-series.' It precisely defines scope ('this brand's recorded posts') and the accrual model (24h and 7d readings), making it distinct from per-platform metrics tools like x_post_metrics or bluesky_post_metrics. Even without naming siblings, the behavior clearly separates it.
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 when to use it—when metrics are due per the accrual schedule—but does not explicitly contrast it with alternatives or state when not to use it. It says 'this collects whichever readings are due and skips the ones already taken,' which gives a condition, but no explicit route to sibling tools or exclusions. This is adequate but not explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
competitor_teardownCompetitor teardownARead-onlyInspect
Tear a competitor's ad strategy down into an actionable playbook: their opening-hook MIX, longest-running campaign THEMES, the WHITE SPACE nobody in their set runs, 2-3 render-ready COUNTER-PLAYS, and the territories they own that you should avoid. Pass competitor {name, domain?}. CONTRACT: supply ads (raw ad objects from a prior pull_competitor_ads / search_meta_ads call) to tear exactly those down, OR omit ads and this pulls the competitor's real Meta ads first (spends a credit or two, longest-running = proven winners). Auto-tailors the white space + counter-plays to YOUR saved brand. Spends credits (free when you pass ads).
| Name | Required | Description | Default |
|---|---|---|---|
| ads | No | ad objects to tear down (from pull_competitor_ads / search_meta_ads). Omit to auto-pull their Meta ads first. | |
| language | No | output language (default English) | |
| competitor | Yes | the competitor to tear down |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses credit costs ('spends credits, free when you pass ads'), the conditional data source (auto-pulls Meta ads when `ads` omitted), and that it auto-tailors outputs to the saved brand. These go beyond the annotations (readOnlyHint, destructiveHint) which only cover safety. No contradiction; the tool is read-only yet consumes credits, and this is clearly 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 description is lengthy but every sentence carries operational information: outputs in caps, the contract, the credit behavior, and auto-tailoring. It front-loads the core purpose and uses structural markers (CONTRACT) for clarity. Minor redundancy (spending mention twice) but nothing trivial. Efficiency is high given the tool's complexity.
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 tool with no output schema and only safety annotations, the description is remarkably complete. It specifies inputs, the conditional behavior, cost implications, and the nature of outputs (playbook components). The only missing piece is exact output format, but the enumerated deliverables suffice for an agent to know what to expect.
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 descriptions for all three parameters. The description enriches meaning: for `ads`, it explains the two modes (supply or omit) and the consequence of omission; for `competitor`, it adds that domain sharpens page match. This adds contract-level semantics not present in the field descriptions, justifying above the baseline of 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?
The description opens by stating a specific verb-resource pair ('Tear a competitor's ad strategy down into an actionable playbook') and enumerates concrete outputs (opening-hook MIX, longest-running THEMES, WHITE SPACE, COUNTER-PLAYS). It clearly distinguishes itself from sibling research tools like research_ads or search_meta_ads by focusing on a strategic teardown rather than raw data retrieval.
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 'CONTRACT' section explicitly tells an agent when to pass `ads` (after a pull_competitor_ads / search_meta_ads call) versus when to omit it (auto-pull, spending credits). It implies the tool is for creating a playbook, contrasting with pure research tools. It could name alternatives more explicitly, but the usage context is clear enough.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
convert_onedrive_fileConvert a OneDrive file to PDF or JPGARead-onlyInspect
Turn a file already in the user’s OneDrive into a PDF or a JPG — Microsoft does the conversion on its own servers, so nothing is re-encoded here and nothing is lost in a screenshot. It reads about 130 source formats, which is the point: PowerPoint and Word decks, Excel, Photoshop PSD, Illustrator AI, Sketch, 3D (fbx/glb/obj), video (mp4/mov/webm), HEIC from an iPhone, and the raw camera formats (CR2, NEF, ARW, DNG) that nothing else in this product can open. Use it to turn a client’s deck into images you can actually put in an ad, to get a usable JPG out of a designer’s PSD or a photographer’s raw file, or to hand someone a PDF of a spreadsheet. CONVERTING TO JPG REQUIRES BOTH width AND height — Microsoft refuses the call without them. The result is stored at a durable Hermoso URL you can pass straight to a render or a post; Microsoft’s own conversion link expires within minutes, so do not hand that one to anyone. Needs OneDrive connected — no new permission.
| Name | Required | Description | Default |
|---|---|---|---|
| width | No | REQUIRED for jpg — output width in pixels | |
| fileId | Yes | the OneDrive item id, from list_onedrive_files | |
| format | No | default pdf | |
| height | No | REQUIRED for jpg — output height in pixels |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, and the description adds meaningful behavior: conversion happens on Microsoft's servers (no local re-encoding), no data is lost, output is stored at a durable Hermoso URL, and the Microsoft-provided link expires in minutes. This goes beyond annotations and covers essential operational details without contradiction.
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 long but each sentence serves a purpose: it explains the mechanism, enumerates supported formats, gives examples, states a hard constraint (JPG dimensions), and describes output and permissions. It is front-loaded with the core function, and while detailed, it avoids fluff. Slightly overlong for a 4-5, but very efficient for the complexity it covers.
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 no output schema, the description does a good job describing what the tool produces (a durable URL) and how to use the result ('pass straight to a render or a post'). It covers prerequisites, output behavior, and a key pitfall (expiring link). It omits explicit response structure (e.g., whether it returns just the URL or an object), but the guidance is sufficient for an agent to use the tool 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 100%, so baseline is 3. The description adds value by explaining that JPG conversion requires both width and height because Microsoft refuses the call without them, and it clarifies that fileId comes from list_onedrive_files. This exceeds the schema by providing rationale and origin context, justifying a score above baseline.
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 verb (convert), a clear resource (OneDrive file), and output formats (PDF or JPG). It also distinguishes itself from siblings by highlighting the broad input format support (e.g., PSD, AI, raw camera formats) that other tools in the product cannot open. This makes the tool's purpose unmistakable and separate from read/get/list 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?
The description provides explicit use cases ('turn a client's deck into images', 'get a usable JPG out of a designer's PSD', 'hand someone a PDF of a spreadsheet') and a critical warning about avoiding the expiring Microsoft link. It also notes the prerequisite of OneDrive being connected. This clearly guides when and why to use the tool, and even hints at the source for the fileId (list_onedrive_files).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_brandCreate a brand workspaceAIdempotentInspect
Add a NEW brand workspace (a separate brand/client on this account) and switch to it. Each workspace has its OWN brand profile, memory, swipefile, Library, avatars, skills, playbooks and connectors — nothing leaks between them. Use this for a second brand or a new client; use draft_brand to FILL a workspace, and update_brand to edit one. Re-running with the same name returns the existing workspace instead of a duplicate. Free (the ~50-credit research cascade only starts when you then run draft_brand).
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | the brand / client name for the new workspace | |
| activate | No | switch this connection to the new brand (default true) — everything you do next scopes to it |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses that the tool switches to the new workspace, that it is free but triggers a ~50-credit research cascade only when draft_brand is run, and that re-running with the same name returns the existing workspace. These details go beyond the annotations (idempotentHint, destructiveHint) and add meaningful behavioral context.
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 five sentences and each adds value, front-loading the core action and expanding with scope, usage, and cost. It is slightly long but well-structured, efficiently packing information without redundancy.
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 the tool's complexity and lack of output schema, the description covers all necessary aspects: workspace isolation, typical usage, idempotence, and cost implications. An agent has enough information to invoke it correctly without further clarification.
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 already describes both parameters (name and activate) with 100% coverage, so the description adds no parameter-specific meaning beyond the schema. It mentions workspace isolation and switching, which indirectly relates to 'activate', but not explicitly; this meets the baseline for full-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 clearly states the tool adds a new brand workspace and switches to it, enumerating the isolated contents (brand profile, memory, swipefile, etc.). It also explicitly distinguishes from sibling tools draft_brand and update_brand, leaving no ambiguity about the purpose.
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 explicitly states when to use this tool ('for a second brand or a new client') and when to use alternatives ('draft_brand to FILL a workspace, and update_brand to edit one'). It also clarifies the idempotent re-run behavior, which helps an agent decide correctly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_docCreate a Google DocAInspect
Create a new Google Doc in the user’s Drive with a title + optional body text — e.g. export ad copy, a creative brief, or a report. Returns the document id + URL. Needs Google Drive connected (Settings ▸ Connectors ▸ Google Drive — one connection covers Drive, Sheets and Docs).
| Name | Required | Description | Default |
|---|---|---|---|
| text | No | body text to insert | |
| title | No | document title |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes beyond the annotations by disclosing the required Drive connection, noting that one connection covers Drive, Sheets, and Docs, and stating that the tool returns the document id and URL. This adds behavioral context (prerequisites, output) that annotations do not provide. No contradiction with the annotations (readOnlyHint=false, destructiveHint=false) is 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?
The description is two sentences with no redundancy. It front-loads the main action and scope, includes valuable examples, and tucks the prerequisite and return-value information into a compact second sentence. Every word 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 creation tool, the description covers the core essentials: what, examples, return value, and prerequisites. It lacks explicit clarification on whether a title is mandatory (schema has no required parameters, but the description implies title is needed), which would be a minor gap. Overall, it's sufficient for an agent to invoke successfully.
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 already fully describes both parameters (text as 'body text to insert', title as 'document title') with 100% coverage. The description adds minor clarification by restating that title is for the document title and text is optional body text, but it doesn't introduce new parameter-specific details beyond what's in the schema. The baseline of 3 is appropriate given 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 states the specific verb-resource pair ('Create a new Google Doc') with clear scope (in the user's Drive) and provides concrete examples (export ad copy, creative brief, report). It clearly distinguishes this creation tool from sibling tools like append_to_doc, read_doc, and update_doc, which handle different operations on existing docs.
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 makes the primary use case explicit by describing what the tool accomplishes and giving example scenarios. While it doesn't explicitly state when NOT to use it (e.g., for editing existing docs), the clear scoping to 'new' docs implicitly differentiates it from update/append tools, and the prerequisite note about Drive connection adds practical guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_drive_folderCreate a Drive folderAInspect
Create a folder in the user’s Google Drive (optionally nested under parentId) to organize saved files. Returns the folder id + webViewLink. Use that ID as update_drive_file’s moveToFolderId or as parentId for a nested folder. NOTE: save_to_drive’s folder is a NAME, not this id — it find-or-creates a folder by that name, so pass the folder NAME there (or omit and just save, then move with update_drive_file).
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | folder name | |
| parentId | No | parent folder id for a nested folder (default: Drive root) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate mutation (readOnlyHint=false). Description adds valuable behavioral context: return value (folder id + webViewLink) and the distinction between the returned ID and the NAME used by save_to_drive. While it doesn't cover error handling or permissions, it goes beyond annotations without contradiction.
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 sentences, each adding distinct value: purpose, return value, and usage warnings. No fluff; information is front-loaded and logically ordered. The critical save_to_drive clarification is placed at the end, which is acceptable.
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 tool with full schema coverage and relevant annotations, the description covers purpose, return value, usage pattern, and potential confusion with sibling tools. Nothing an agent needs 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 already documents both parameters (100% coverage). Description adds meaning by explaining parentId's role ('parent folder id for a nested folder, default: Drive root') and clarifies the id/name distinction for name usage. This enriches the schema's baseline descriptions.
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?
Description states a specific verb ('Create') and resource ('folder in the user’s Google Drive') with optional nesting under parentId, clearly distinguishing it from siblings like save_to_drive and update_drive_file. The purpose is immediately clear without ambiguity.
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?
Provides explicit when-to-use guidance: 'Use that ID as update_drive_file’s moveToFolderId or as parentId for a nested folder.' Also warns about save_to_drive's folder being a NAME not an id, and advises passing the NAME there or omitting it. This fully routes the agent to correct alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_onedrive_folderCreate a OneDrive folderAInspect
Create a folder in the user’s OneDrive (optionally nested under parentId) to organize saved files. Returns the folder id + webViewLink. Use that id as update_onedrive_file’s moveToFolderId or as parentId for a nested folder. NOTE: save_to_onedrive’s folder is a NAME (find-or-created), not this id.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | folder name | |
| parentId | No | parent folder id for a nested folder (default: OneDrive root) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate a non-read-only, non-destructive write operation. The description adds value by disclosing the return format (folder id + webViewLink), the optional nesting behavior, and the semantic distinction from save_to_onedrive's folder name. It does not contradict annotations and covers the key behavioral aspects beyond the structured metadata.
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 three sentences, front-loaded with the core purpose, then return value, then usage and a caveat. Every sentence earns its place with no redundancy or filler. It is efficient and well-organized.
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 tool with full schema coverage and clear annotations, this description is complete. It explains the return value (compensating for the lack of an output schema), provides usage guidance, and disambiguates from a similar sibling. Nothing essential is missing 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?
Schema coverage is 100%, with both 'name' and 'parentId' already described in the input schema. The description reiterates the nesting behavior but does not add new parameter-level meaning beyond what the schema provides. Since the schema covers parameter semantics, the description's additional context is useful but not required, landing at the baseline of 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?
The description states a specific verb and resource ('Create a folder in the user's OneDrive'), explains its purpose ('to organize saved files'), and distinguishes itself from close siblings like save_to_onedrive and create_drive_folder by explicit naming and context. It also mentions the return value, making the tool's role 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 provides clear usage guidance: it explains how to use the returned id (as moveToFolderId for update_onedrive_file or as parentId for nesting) and explicitly warns about the difference from save_to_onedrive's folder name. While it doesn't enumerate all alternatives, it effectively prevents common misuse and gives actionable next steps.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_sheetCreate a Google SheetAInspect
Create a new Google Spreadsheet in the user’s Drive and optionally fill it with rows — e.g. export a swipefile, ad list, or performance report. Pass rows as an array of row arrays (first row = headers). Returns the spreadsheet id + URL. Needs Google Drive connected (Settings ▸ Connectors ▸ Google Drive — one connection covers Drive, Sheets and Docs).
| Name | Required | Description | Default |
|---|---|---|---|
| rows | No | rows to write — array of row arrays; first row = headers | |
| title | No | spreadsheet title |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint=false and openWorldHint=true, so the write nature is known. The description adds the requirement of a Google Drive connection (one connection covers Drive, Sheets, Docs) and clarifies that rows are optional, which goes beyond the schema. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences with no filler. The purpose is front-loaded, followed by usage details and a prerequisite. Every sentence contributes meaningful information for the agent.
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 tool with two optional parameters and no output schema, the description covers everything needed: purpose, row format, return value (id + URL), and a connection prerequisite. The examples help the agent understand common use cases. Nothing critical 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 100% with descriptions for both parameters. The description adds value by clarifying that rows are optional, providing examples of what rows might contain, and noting that the first row is treated as headers. This complements the schema without redundancy.
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 verb and resource ('Create a new Google Spreadsheet in the user's Drive') and provides concrete examples (export a swipefile, ad list, performance report). It clearly differentiates from siblings like append_to_sheet and update_sheet by focusing on creation of a new spreadsheet.
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 clear context (creating a new sheet, optionally with rows) and includes a prerequisite (Google Drive connected). It does not explicitly name alternative tools or when not to use it, but the purpose is unambiguous enough that an agent can infer when to use it vs. modifying existing sheets.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
delete_brandDelete a brand workspaceADestructiveIdempotentInspect
PERMANENTLY delete a brand workspace and EVERYTHING in it — brand profile, memory, swipefile, Library creations, generated assets, avatars, skills, playbooks, chats — and disconnect its connected accounts. Irreversible, and it applies to everyone the workspace is shared with. Call it WITHOUT confirm first: it reports exactly what that workspace holds. Show the user that inventory verbatim, get an unambiguous yes, then call again with confirm:true — plus, if the workspace is not empty, confirmName set to its exact name and confirmConnectors set to the number of connected accounts it reported. Those two exist because confirming INTENT does not prove you picked the right WORKSPACE, and a wrong target is how a live brand was destroyed. The account's FIRST/anchor brand cannot be deleted this way (it holds the workspace's root storage) — that one is replaced from the app.
| Name | Required | Description | Default |
|---|---|---|---|
| brand | Yes | brand id or exact name from list_brands | |
| confirm | No | REQUIRED true — this destroys the whole workspace and cannot be undone | |
| confirmName | No | the workspace's EXACT name, required when it is not empty — copy it from the inventory this tool returned, after the user has agreed to it | |
| confirmConnectors | No | the number of connected accounts the inventory reported, required when there is at least one — the user must specifically agree to losing them, because reconnecting each needs a browser and no agent can do it |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark destructiveHint=true, but the description adds crucial behavioral context: the operation is irreversible, affects all shared users, requires a confirmation protocol, and the first call without confirm serves as a dry-run inventory. It explains the rationale for the confirmation fields, going well 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 description is dense but every sentence carries necessary safety information. It is front-loaded with the most critical warning (irreversible) and then flows logically into the confirmation protocol. Though it is a long paragraph, it is structured in a cause-and-effect manner that justifies its length. Could be broken into shorter sections, but it is not bloated.
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, high-stakes operation, the description covers the full behavioral contract: what is deleted, irreversibility, impact on shared users, the two-phase confirmation with exact parameters, and the anchor-brand exception. Nothing essential for an agent 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 100% and each parameter already has a description. The description adds value by explaining why confirmName and confirmConnectors exist: to prove the correct workspace was targeted, preventing accidental destruction of a live brand. This clarifies the intent and requirement beyond schema descriptions.
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 verb and resource: "PERMANENTLY delete a brand workspace and EVERYTHING in it." It enumerates what is included and explicitly distinguishes this from other delete tools by naming the anchor-brand exception. The purpose is unmistakable.
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 an explicit two-phase workflow: call without confirm to get an inventory, show the user, get unambiguous yes, then call with confirm:true and necessary verification fields. It also states when NOT to use it (anchor brand) and how that case is handled. This is exemplary usage guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
delete_creatorDelete a creatorADestructiveIdempotentInspect
Remove a saved creator from this workspace’s cast by id (from list_creators). Records a cross-device delete so they don’t reappear on the user’s other devices. It only drops the roster entry — ads already rendered with that person are untouched — and the same portrait can be saved again with save_creator, so no confirm is needed.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | the creator id (from list_creators) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds key behavioral details beyond annotations: it records a cross-device delete to prevent reappearance, clarifies that ads rendered with the person remain untouched, and notes that the portrait can be saved again. These are not covered by annotations (which only mark destructive/idempotent), so they add significant context.
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, front-loaded with the action, then efficient details about scope and re-save. No wasted 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?
For a single-parameter delete tool with annotations covering destructive/idempotent, the description covers cross-device behavior, side effects (ads untouched), and reversibility (save_creator). There is no output schema, so return values are not a concern. An agent has all needed info to call 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?
The schema already describes the 'id' parameter as the creator id from list_creators, and the description repeats that without adding new details. Since coverage is 100%, the description adds no extra semantic value beyond 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?
The description states a specific verb ('Remove') and resource ('saved creator from this workspace’s cast'), and identifies the id source ('from list_creators'). It clearly differentiates from siblings like save_creator by focusing on deletion and scope.
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 says the deletion only drops the roster entry and that the same portrait can be saved again with save_creator, implying the alternative for re-adding. It also notes no confirm is needed, providing a usage cue. It could be more explicit about when not to use it (e.g., if wanting to fully remove permanently), but it gives clear context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
delete_drive_fileDelete a Drive fileADestructiveIdempotentInspect
Delete a Drive file. By default it goes to Trash (recoverable); pass permanent:true to delete it forever. Pass fileId (from list_drive_files) + confirm:true. Irreversible when permanent — confirm with the user first.
| Name | Required | Description | Default |
|---|---|---|---|
| fileId | Yes | the Drive file id | |
| confirm | No | REQUIRED true | |
| permanent | No | true = delete forever; default trashes (recoverable) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark destructiveHint=true, but the description adds critical behavioral nuance: default goes to Trash (recoverable), permanent is irreversible, and confirmation with the user is required. This goes well beyond annotations by explaining the recovery path and the need for explicit user consent, covering the key behavioral aspect of the 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?
The description is three sentences, front-loaded with the core action, then details irreversible behavior and usage steps. Every sentence adds value without redundancy. It is efficient and well-structured.
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 delete tool with no output schema, the description is complete: it explains what happens by default, how to make it permanent, which parameters to pass, and the safety caution. It covers all essential information an agent needs to call this tool correctly, even among many similar delete tools.
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 descriptions for each parameter. The description adds value by instructing to pass fileId from list_drive_files and emphasizing confirm:true, which clarifies that confirm is effectively required even though the schema's required array only lists fileId. This bridges a gap between schema and actual usage.
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 the action: 'Delete a Drive file.' It specifies the resource and the verb, and distinguishes from siblings like update_drive_file, get_drive_file, and list_drive_files. It also adds nuance about trash vs permanent deletion, making the purpose unmistakable.
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 practical usage hints: 'Pass fileId (from list_drive_files) + confirm:true' and explains the permanent option. It implicitly signals when to use this tool (when deleting a Drive file), though it doesn't explicitly contrast with alternatives. The context is clear and actionable, but lacks an explicit 'when not to use' statement.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
delete_linkedin_lead_subscriptionStop a LinkedIn lead webhookADestructiveIdempotentInspect
Remove a lead notification webhook (subscriptionId from list_linkedin_lead_subscriptions). Leads themselves are unaffected and stay readable; only the real-time delivery stops. Read back from LinkedIn. Free.
| Name | Required | Description | Default |
|---|---|---|---|
| pageId | No | the company Page that owns the form — from list_linkedin_pages; omit when one Page is shared | |
| adAccountId | No | read forms owned by an AD ACCOUNT instead of a Page | |
| subscriptionId | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate destructive, idempotent, and open-world behavior, and the description adds crucial scoping: only the webhook is removed, while leads remain intact. 'Read back from LinkedIn' also discloses the external side effect, and there is no contradiction with 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?
Three short sentences front-load the core action and immediately clarify the destructive scope. Every sentence earns its place: the action, the non-destructive effect on leads, and the external synchronization/cost note.
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?
Even without an output schema, the description covers what the call does, what it affects, and where to get the required parameter. The idempotent and open-world hints come from annotations, making this complete enough for an agent to select and invoke the tool 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?
The schema already documents pageId and adAccountId, and the description adds meaning for the required subscriptionId by tying it directly to list_linkedin_lead_subscriptions. Since 67% of parameters are schema-described, the description meaningfully compensates for the remaining undocumented parameter.
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 opens with the specific verb 'Remove' and the exact resource, 'a lead notification webhook', and anchors the required subscriptionId to its source, list_linkedin_lead_subscriptions. It also explicitly scopes what is not affected ('Leads themselves are unaffected'), which distinguishes it from any lead-deletion or subscription-creation tool.
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 tells the agent where to obtain the subscriptionId and makes the intended use case clear: stop real-time delivery while keeping leads readable. It does not explicitly enumerate exclusions versus every sibling tool, but the context is sufficient for selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
delete_onedrive_fileDelete a OneDrive fileADestructiveIdempotentInspect
Delete a OneDrive item — it moves to the OneDrive recycle bin (recoverable there). Pass fileId (from list_onedrive_files) + confirm:true. Confirm the exact file with the user first.
| Name | Required | Description | Default |
|---|---|---|---|
| fileId | Yes | the OneDrive item id | |
| confirm | No | REQUIRED true |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds recoverability ('moves to the OneDrive recycle bin') and a confirmation requirement beyond what annotations already state (destructiveHint=true). This gives the agent important behavioral context for a mutation, meeting the lowered bar set by 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?
Two sentences, zero waste, with the action and critical safety note front-loaded. The structure is clean: what it does, where it goes, how to call it, and a safety directive.
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 delete operation with destructiveHint, it covers the essentials: the action, recoverability, how to get the ID, and the confirmation requirement. No output schema is present, but delete typically returns minimal info, so this is adequate. Missing edge cases like non-existent files aren't critical.
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 covers both params, but the description enriches them: it specifies fileId comes from list_onedrive_files and that confirm:true is required (aligning with the schema's 'REQUIRED true' description). This helps the agent construct valid calls.
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: 'Delete a OneDrive item' with the key behavior of moving to the recycle bin. Clearly distinguishes from siblings like delete_drive_file by specifying OneDrive specifically, so an agent can immediately know what it's for.
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?
Provides explicit instructions: 'Pass fileId (from list_onedrive_files) + confirm:true' and emphasizes confirming with the user first. While it doesn't name alternatives or when-not-to-use, the guidance is clear and actionable for this destructive operation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
delete_playbookDelete a playbookADestructiveIdempotentInspect
Delete a saved playbook by id (from list_playbooks). Records a cross-device delete so it does not come back on the next sync. Minor + re-creatable, so no confirm needed.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | the playbook id (from list_playbooks) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and idempotentHint=true. The description adds valuable behavioral context: it records a cross-device delete to prevent reappearance on sync, and explains it is 'minor + re-creatable' so no confirmation is needed. This goes beyond the annotations and gives an agent insight into side effects. No contradiction.
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 succinct sentences: the first states the action and id source, the second explains cross-device behavior and the lack of confirmation. No extraneous words, and important details are 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 single-parameter, no-output-schema tool, this description is fully adequate. It covers how to get the id, the side effect (cross-device delete), and why no confirmation is needed. Combined with annotations for destructive/idempotent hints, 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?
The schema already fully describes the id parameter (type, required, description). The tool description repeats the instruction 'from list_playbooks', which adds a small hint about provenance but does not substantially augment the schema. With 100% schema coverage, 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?
The description clearly states the action ('Delete a saved playbook by id'), specifies the resource (playbook), and tells the agent exactly where to get the id ('from list_playbooks'). It distinguishes this tool from other delete operations (e.g., delete_creator) by naming the resource type. This is specific and 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 context: you must first call list_playbooks to obtain the id. It does not explicitly name alternatives or state when not to use it, but the resource specificity is high and the id source instruction is a clear prerequisite. A slight gap is absence of explicit comparison to sibling delete tools, but the resource target makes it obvious.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
delete_skillDelete a custom skillADestructiveIdempotentInspect
Delete one of the workspace’s CUSTOM skills by id (from list_skills). Built-in skills/recipes can’t be deleted. Minor + re-creatable, so no confirm needed.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | the custom skill id (from list_skills) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate destructiveHint and idempotentHint, but the description adds useful context: it is 'Minor + re-creatable' and explicitly states no confirm is needed. It also discloses the constraint that built-in skills cannot be deleted, which is behavioral info beyond the annotations. There's no contradiction with 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?
Two sentences with no fluff. The primary action and scope are front-loaded, followed by the exclusion and confirmation guidance. Every sentence adds value.
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 single-parameter delete tool with no output schema and annotations covering safety, the description is sufficient. It covers what is deleted, how to identify it, what's excluded, and the confirmation behavior. 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?
Schema coverage is 100%, with the id parameter already described as 'the custom skill id (from list_skills)'. The description essentially repeats this source reference, adding no new semantic detail beyond what the schema provides. Baseline 3 is appropriate given the 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 clearly states the verb ('Delete'), the resource ('workspace's CUSTOM skills'), and the scope ('by id (from list_skills)'). It also distinguishes custom skills from built-in skills/recipes, which are explicitly excluded. This differentiates it from any other delete operations in the sibling list.
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 explicit when-to-use context: delete custom skills, not built-in ones. It also gives the source of the id (list_skills) and explains that no confirmation is needed due to the minor, re-creatable nature, guiding the agent on when it's safe to proceed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
diagnose_postsWhat to fix next, post by postARead-onlyInspect
WHAT TO FIX NEXT, post by post — and the tool that fixes it. post_performance tells you which hook is AHEAD; this tells you what is WRONG with a given post and where the next edit goes. Under-distributed is A HOOK PROBLEM (change the opening: mine_angles, then list_hooks, then plan_variations). Seen but not held is A RETENTION PROBLEM (plan_variations to rebuild the middle against the same hook). Seen, held, and still not converting is AN OFFER PROBLEM. FOUR REFUSALS, AND YOU SHOULD REPEAT THEM RATHER THAN PAPER OVER THEM: (1) a post younger than ~24h is TOO EARLY and is never called a failure — it has not had its run; (2) a metric the platform does not publish is UNMEASURED, never zero — Facebook has published no post reach since 2026-06-15, Reddit publishes no impressions, and Google Business publishes nothing per-post at all; (3) below 5 measured posts on a channel there is no baseline of the brand's own, and the ONLY fallback is a published short-video hook floor that is NOT our measured number and does not transfer off TikTok/Instagram/YouTube — it is attributed in the output and you should attribute it too; (4) it does not always find a problem, and 'nothing here needs fixing' is a real answer rather than a failure to look. Hermoso cannot see conversions for an organic post — no channel reports installs or purchases against a post id — so the offer rung runs ONLY when the user tells you they are not converting and you pass converting:false. Print summary verbatim. Read-only, 0 credits.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | how many recent posts to diagnose (default 25, max 200). The baseline is always built from EVERY post recorded for the brand, never only these, so a bad month can never become its own definition of normal. | |
| channel | No | restrict to one channel: facebook, instagram, threads, x, linkedin, youtube, tiktok, reddit, pinterest | |
| converting | No | pass false ONLY when the user has told you these posts are getting seen and are not converting — it re-reads the ones that are earning their reach as an offer problem instead of a win. Omit when you do not know; we cannot measure it. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, and the description reinforces with 'Read-only, 0 credits.' It adds valuable behavioral context not in annotations: that it may return 'nothing here needs fixing' as a real answer, that it cannot see organic post conversions, and that the baseline is built from ALL recorded posts. These details meaningfully improve call quality.
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?
Though long, the description is front-loaded with purpose, uses clear section markers (headers, numbered refusals), and every sentence carries unique information. The structure makes it easy to skim for key rules. The length is justified by the complexity of the diagnostic logic. No redundancy.
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 the tool's complexity, the description is thorough: it covers purpose, usage conditions, the four refusal cases, the converting behavior, output instruction ('Print summary verbatim'), and its read-only nature. There is no output schema, so the description compensates by specifying the call to action. An agent has everything needed to decide when to call and what to expect.
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 covers each parameter with descriptions, so baseline is 3. The description adds extra meaning: for limit, it states the baseline always uses every post, not just the limited set, preventing a bad month from becoming its own normal; for converting, it clarifies the condition under which converting:false should be passed and that it should be omitted when unknown. This adds value beyond 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?
The description clearly states the tool's purpose: 'tells you what is WRONG with a given post and where the next edit goes.' It distinguishes itself from sibling post_performance by contrasting 'which hook is AHEAD' vs 'what is WRONG'. This is a specific verb+resource with clear differentiation from similarly named 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?
The description explicitly explains when to use this tool versus alternatives. It references post_performance for hook comparison, prescribes the sequence 'mine_angles, then list_hooks, then plan_variations' for hook problems, and details the four refusal conditions that tell the agent when NOT to call the tool. It also specifies when the offer rung runs (only with converting:false). This is exemplary.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
disconnect_connectorDisconnect a connected accountADestructiveIdempotentInspect
Disconnect a third-party account from this workspace (Meta, Google Ads, Google Drive/Sheets/Docs, YouTube, TikTok, LinkedIn, X, Reddit, Pinterest, Google Business, Microsoft Advertising/OneDrive, Slack, …). This always drops the stored credentials, so every tool for that provider stops working immediately and posts/campaigns already published are NOT affected. WHETHER IT ALSO REVOKES THE GRANT AT THE PROVIDER DEPENDS ON THE PROVIDER — a few (Threads, Microsoft) publish no revocation endpoint, so the authorisation stays in place until the user removes it in that provider's own settings. The unconfirmed call reports which it is for this provider (list_connectors also carries it as revokesAtProvider) — relay that verbatim rather than promising a revoke. RECONNECTING NEEDS A BROWSER (the provider's consent screen) — an agent cannot undo this. Name the provider to the user, then call with confirm:true. Use list_connectors for the exact provider ids.
| Name | Required | Description | Default |
|---|---|---|---|
| account | No | on a channel with several connected accounts (TikTok, X, YouTube, Threads, Bluesky, Telegram, Reddit, Pinterest): remove ONLY this account (@handle or id from list_connector_accounts) and keep the others | |
| confirm | No | REQUIRED true — reconnecting needs the user's browser | |
| provider | Yes | provider id exactly as list_connectors reports it, e.g. "meta", "google_ads", "youtube", "linkedin" |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the destructiveHint and readOnlyHint annotations, the description discloses concrete behavioral details: credentials are always dropped, provider tools stop immediately, published posts are not affected, revocation is provider-dependent (Threads/Microsoft do not revoke), and the unconfirmed call reports revokesAtProvider. It also states the agent cannot undo reconnection, which is critical operational context.
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 dense and front-loaded with the most important facts (destructive action, immediate effect, published content unaffected). It is longer than necessary due to the extensive provider list and repeated emphasis, but each sentence carries actionable guidance rather than 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?
The description covers prerequisites, provider-id sourcing, provider-dependent revocation behavior, confirmation workflow, and irreversibility. For a destructive connector tool with no output schema, this is sufficient context for an agent to call it correctly and relay accurate caveats to the user.
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 100% schema description coverage the baseline is 3, but the description adds practical meaning by explaining why confirm:true is mandatory (reconnection needs a browser) and telling the agent to source provider ids from list_connectors. The account parameter is left to the schema, but that is acceptable given the 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 opens with a specific verb-resource pair ('Disconnect a third-party account from this workspace') and scopes it to credential-bearing connectors, which clearly separates it from list-only siblings. It further explains the consequences of disconnecting, so there is no ambiguity about what action is being performed.
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 explicitly instructs the agent to obtain exact provider ids from list_connectors, to name the provider to the user, and to call with confirm:true only after user confirmation. The warning that reconnecting requires a browser and cannot be undone serves as an explicit when-not-to-call signal.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
draft_brandDraft brand profileAInspect
Onboard a brand profile — from a website domain, a free-text description, or a social handle — into a {name, products, logo, …} object you can pass to plan_ad / generate. 0 credits. IMPORTANT: a domain can resolve to a DIFFERENT company than intended (e.g. bala.com is an engineering firm, not the Bala fitness brand at shopbala.com). Before spending any credits on research or renders, VERIFY the returned name (and summary) match the brand the user meant; if it looks wrong, re-draft with the correct domain or a description (pass save:false until confirmed) — this tool cannot ask the user, so the caller owns that check.
| Name | Required | Description | Default |
|---|---|---|---|
| save | No | save as the workspace’s brand (like Studio onboarding) so plan_ad/create use it automatically. Default: saves only when NO brand is saved yet; pass true to overwrite, false to never save | |
| domain | No | a website to scrape | |
| platform | No | platform for socialHandle (instagram/tiktok/…) | |
| description | No | a free-text brand description (no website) | |
| socialHandle | No | a social handle to draft from (influencers/creators) — pair with platform |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=false and destructiveHint=false, and the description adds meaningful context beyond that: it's 0 credits, it cannot ask the user (caller owns verification), and it warns that a domain can resolve to a different company than intended (bala.com vs shopbala.com). This discloses a real failure mode and the save:false workflow, which no annotation 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?
The core purpose is front-loaded in the first sentence, and the IMPORTANT paragraph is justified because it flags a critical verification pitfall that materially affects correct invocation. Slightly long, but each segment (purpose, credit cost, domain-mismatch warning, save semantics) 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 5-parameter tool with no output schema and minimal annotations, the description covers the input sources, the ambiguous-domain risk, the save semantics, and the credit cost. It could add the exact return shape beyond the partial {name, products, logo, …}, but what's needed to call it correctly and safely is present.
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 all five parameters (save, domain, platform, description, socialHandle) are already documented in the schema. The description names the three input sources and references save:false, which lightly reinforces parameter meaning, but adds little beyond what the schema provides — the baseline 3 for high coverage 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 states a specific verb ('onboard a brand profile'), the resource (brand), three input sources (domain, free-text description, social handle), and the output shape ({name, products, logo, …} object). It clearly distinguishes itself from sibling brand tools (create_brand, update_brand, get_brand) by describing the draft-from-source behavior, so an agent can tell it apart without opening sibling 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?
The description gives workflow guidance — results can be passed to plan_ad/generate, and the caller should verify name/summary and re-draft with save:false until confirmed. However, it never explicitly contrasts draft_brand with the sibling create_brand/update_brand tools or states when to pick one over the other, so the 'when to use vs alternative' guidance is implied rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
dub_videoDub videoAInspect
Localize a finished video into another language WITHOUT re-rendering it: the spoken track is transcribed, translated, re-voiced and lip-synced back onto the SAME footage, so the visuals, timing and edit are untouched. Just pass the video and the language — the script is read off the source automatically (pass script only to override what it heard). Paid; returns the served URL of the localized video.
| Name | Required | Description | Default |
|---|---|---|---|
| video | Yes | the source video URL | |
| voice | No | optional target voice preset, e.g. 'Aria' (warm female) or 'George' (confident male). Defaults to a voice matching the source speaker's register. | |
| script | No | OPTIONAL override for the original spoken words. Leave this out — the source video is transcribed automatically. Only pass it when you already know the exact script and the auto-transcript got it wrong. | |
| language | Yes | target language, e.g. 'Spanish', 'de', 'French (Canada)' |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations are neutral (readOnlyHint: false, destructiveHint: false), so the description carries the burden of disclosing behavior. It clearly states that it does NOT re-render, preserves visuals/timing/edit, transcribes/translates/re-voices/lip-syncs, and returns the served URL. It also discloses that it is paid. This adds significant behavioral context beyond annotations, though it omits potential limitations like processing time or input format constraints.
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 moderately long but every sentence earns its place: it explains the mechanism, the simple invocation, the script override nuance, and the cost/return. Key facts (no re-render, pass video+language, paid, returns URL) are front-loaded, making it skimmable. A slight trim could tighten it, but it remains focused.
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 specifies that it returns 'the served URL of the localized video.' It covers all four parameters, the cost, and the behavioral specifics. Missing details like asynchronous processing or video size limits are non-essential for basic usage, so the description is virtually complete for an agent to invoke 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 description coverage is 100%, so each parameter already has a description. The tool description enhances this by explaining the script parameter's override purpose ('pass script only to override what it heard') and adding nuance about the voice parameter's default selection. This goes beyond mere schema repetition, adding practical guidance without being redundant.
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 verb ('localize') and resource ('finished video') with a clear outcome (transcribed, translated, re-voiced, lip-synced back onto the same footage). It distinctly differentiates from siblings like clip_video or edit_video by focusing on language localization without re-rendering, leaving no ambiguity about what the tool does.
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 explicitly tells the agent to 'Just pass the video and the language', making the core usage obvious. It also provides a conditional for the script parameter (use only when auto-transcript fails) and mentions the tool is paid, which is a cost guideline. However, it does not explicitly contrast with alternative tools, though no direct sibling exists that performs dubbing, so the context is sufficiently clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
duplicate_scheduledDuplicate a scheduled postAInspect
Copy an existing scheduled or already-published post into a NEW queued post — the way to run a creative again, reuse a post that worked as the starting point for the next one, or re-send something after it went out. It copies the caption, media, per-channel captions, title, description, tags and the target board / Page / company Page / listing, and ANY of those can be overridden in the same call. Give a new time in at, or useQueue:true to drop it into the brand’s next free posting slot. The copy is INDEPENDENT — editing or cancelling it never touches the original — and it is a genuinely new post rather than a re-send, so it publishes even where the original already did. To re-fire only the channels that FAILED, use retry_scheduled instead.
| Name | Required | Description | Default |
|---|---|---|---|
| at | No | when the copy goes out — ISO timestamp or epoch milliseconds (default: an hour from now) | |
| id | Yes | the post to copy, from list_scheduled | |
| link | No | ||
| title | No | ||
| chatId | No | TELEGRAM — which chat, group or channel the copy goes to (@username or numeric id) | |
| pageId | No | FACEBOOK / INSTAGRAM / THREADS — which connected Page (list_meta_pages) | |
| boardId | No | PINTEREST — the board for the copy (list_pinterest_boards) | |
| message | No | a different caption for the copy | |
| captions | No | per-channel caption overrides for the copy | |
| channels | No | post the copy to these channels instead of the original’s | |
| imageUrl | No | ||
| timezone | No | IANA zone for the queue, e.g. "America/New_York" | |
| useQueue | No | instead of naming a time, take the brand’s next free posting slot | |
| videoUrl | No | ||
| imageUrls | No | CAROUSEL — an ORDERED list of image URLs published as ONE swipeable post | |
| locationId | No | GOOGLE BUSINESS — which listing (list_business_locations) | |
| visibility | No | ||
| linkedinOrganizationId | No | LINKEDIN — publish the copy as this company Page (list_linkedin_pages) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations (readOnlyHint=false, idempotentHint=false, destructiveHint=false), the description adds crucial behavioral details: 'The copy is INDEPENDENT — editing or cancelling it never touches the original — and it is a genuinely new post rather than a re-send, so it publishes even where the original already did.' This clarifies side effects and independence, which annotations do not convey. No contradiction with annotations exists.
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 a single dense paragraph that front-loads the core purpose and then adds context. It is not overly verbose given the tool's complexity (18 parameters), and every sentence adds value, from use cases to independence to the retry_scheduled contrast. It could be broken into bullet points for readability, but it is structured logically and remains comprehensible.
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 the tool's complexity (18 parameters, nested objects, many channel-specific fields), the description covers the essential behavior, scheduling options, independence, and the difference from retry_scheduled. It does not need to explain every parameter because the schema already does, and no output schema exists so return values are not required. The description provides enough for an agent to call it correctly without missing key context.
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 72% (many parameters have descriptions), and the description adds meaningful context beyond those. It explains that all copied fields 'can be overridden in the same call' and clarifies the scheduling distinction between 'at' and 'useQueue:true'. It also mentions the default time ('an hour from now') implicitly via 'at' description in schema, but the description does not list every parameter. It augment the schema without fully compensating for the 28% undocumented parameters, so a 4 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 opens with a specific verb and resource: 'Copy an existing scheduled or already-published post into a NEW queued post.' It clearly states the action, the object, and the result, and distinguishes it from the sibling tool retry_scheduled by noting 'To re-fire only the channels that FAILED, use retry_scheduled instead.' This leaves no ambiguity about what the tool does and when to differentiate it.
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 explicitly lists use cases ('run a creative again, reuse a post that worked as the starting point for the next one, or re-send something after it went out') and provides a direct alternative: 'To re-fire only the channels that FAILED, use retry_scheduled instead.' It also explains the two scheduling modes (at vs useQueue), giving the agent clear conditions for each. No gaps remain about when to choose this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
edit_videoEdit a video clipAInspect
EDIT/transform an existing video clip with a natural-language instruction (video-to-video) — KEEPS the original motion, timing and edit, changes the subject/setting/style. Use for 'change the background to a city', 'make it nighttime', 'restyle it as claymation', 'swap the product'. Best on 3–10s clips. NOT for mechanical cuts, trims, end cards or watermarks (use post_edit — seconds, ~2 credits, no AI model), NOT for making a new video (generate_video / render_ad), NOT for translating the spoken track (dub_video) and NOT for putting a saved creator's face on the motion (recast_motion). Paid render; returns the served URL of the edited clip.
| Name | Required | Description | Default |
|---|---|---|---|
| video | Yes | the source video URL (from a previous render, a job result, or list_library) | |
| elements | No | OPTIONAL identity/product grounding (≤4): a creator portrait or the real product photo, so the edit restores the REAL thing instead of re-inventing it. Describe each one in the instruction. Leave out for a plain restyle | |
| keepAudio | No | default true — keep the source clip’s audio track. Set false to return the edit silent | |
| instruction | Yes | the exact transformation to apply, in the user’s own words |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations are all false (readOnlyHint, destructiveHint, etc.), so the description carries the full burden. It clearly discloses key behaviors: the edit preserves original motion/timing, it is a paid render, and it returns a served URL. It also explains how the elements parameter affects behavior (restores real identity/product vs. plain restyle). No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense yet every sentence earns its place: purpose is front-loaded, followed by concrete use cases, the recommended clip length, a clear 'NOT for' section naming five alternatives, and a final note on cost and output. The structure guides an agent from selection to invocation without redundancy.
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 the tool's complexity (video editing, multiple parameters, no output schema), the description covers purpose, usage, exclusions, cost, output URL, and best practices. It doesn't mention error scenarios or hard maximum video length, but the 'Best on 3–10s clips' is a reasonable heuristic. The schema covers source URL provenance. Overall, an agent has everything needed to decide and call the tool 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 100% (all parameters have descriptions), so baseline is 3. The description adds meaningful context for the 'elements' parameter, explaining its purpose (identity/product grounding), the max count (≤4), and when to omit it (plain restyle). It also clarifies the 'instruction' parameter as 'in the user’s own words'. This goes beyond the schema's literal descriptions and aids correct usage.
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 verb ('EDIT/transform') and resource ('an existing video clip') and immediately defines the scope: keeps motion/timing, changes subject/setting/style. It provides concrete examples ('change the background to a city', 'restyle it as claymation'). It also distinguishes itself from five named sibling tools, so an agent can reliably tell edit_video apart from post_edit, generate_video, render_ad, dub_video, and recast_motion.
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 explicitly states when to use (for style/subject/setting changes) and when NOT to use, listing specific alternatives for each excluded case (mechanical cuts → post_edit, new video → generate_video/render_ad, translation → dub_video, face swap → recast_motion). It also adds a practical recommendation ('Best on 3–10s clips') and flags the paid nature. This leaves no ambiguity about tool selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
enable_toolsTurn on more Hermoso toolsAIdempotentInspect
Switch on a group of tools that is not in this session's roster. WORKS ON CLIENTS THAT RE-READ THE TOOL LIST (stdio, the CLI); a host that fixed its roster at connect time — ChatGPT does — will not show the new tools until it reconnects, and this tool says so in its reply rather than reporting a success you cannot use. The connect-time route that always works is ?tools=all on the server URL. The default roster is every group EXCEPT ads and analytics and channel_admin, which are held out purely on SIZE: paid-campaign management is by far the largest group, most of the total schema weight across eleven ad platforms, and measurement is a third again on top of everything else. Most sessions need neither. Nothing in either is unfinished or unsafe — they are one call away. CALL THIS THE MOMENT YOU NEED ONE. If the user asks to build, budget, target, report on or change an ad campaign on any platform, call enable_tools({groups:['ads']}) first and the tools appear. If they ask about their own site or product analytics, a tag/tracking container, or how a search engine crawls, indexes or ranks their site, call enable_tools({groups:['analytics']}). Groups: core, research, create, channels, channel_admin, analytics, ads, files, workspace — or 'all'. Free, instant, and it never turns anything off.
| Name | Required | Description | Default |
|---|---|---|---|
| groups | Yes | Groups to switch on, e.g. ['ads']. Unknown names are refused by name rather than ignored. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate idempotentHint=true and destructiveHint=false, but the description adds valuable behavioral context: it only works on clients that re-read the tool list, it reports 'not a success you cannot use' in its reply when the host won't show new tools, it is 'free, instant, and it never turns anything off.' This goes well beyond the annotations and helps the agent set correct expectations.
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 long but information-dense and well-structured. It front-loads the core action, then the important caveat, then the default-roster explanation, and ends with actionable triggers. Some repetition (e.g., the group list appears twice in different forms) could be trimmed, but every section earns its place for an agent making a decision.
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 tool with one required parameter and no output schema, the description is exceptionally complete: it covers when to call, which groups exist, why some groups are hidden by default, the limitation with connect-time-only hosts, and the alternative route. Nothing an agent needs to invoke 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 100% and the schema parameter description already explains the groups array and unknown-name behavior. The tool description further enriches this by listing all valid group names ('core, research, create, channels, channel_admin, analytics, ads, files, workspace — or all') and giving concrete usage examples. This is meaningful added value over 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?
The description states a specific verb and resource: 'Switch on a group of tools that is not in this session's roster.' It clearly distinguishes itself from siblings by being the meta-tool that enables other tools, and it explicitly names the groups and examples. This is unambiguous and not a tautology.
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 explicit when-to-use instructions: 'CALL THIS THE MOMENT YOU NEED ONE.' It provides concrete triggers for ads and analytics ('If the user asks to build, budget, target... call enable_tools({groups:['ads']}) first') and even names the alternative connect-time route (`?tools=all`). It also explains the limitation with hosts that fixed their roster, so the agent knows what to expect.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
error_detailError detailARead-onlyInspect
One error group in full by fingerprint (from list_errors): every field, plus the most recent redacted occurrences — status, connector, job id, workspace, and a shape-only echo of the inputs. This is what makes a bug reproducible. Read-only, 0 credits.
| Name | Required | Description | Default |
|---|---|---|---|
| fingerprint | Yes | the `fp` value from list_errors |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, and the description reinforces this with 'Read-only, 0 credits,' adding cost information. More importantly, it discloses that occurrences are 'redacted' and inputs are only a 'shape-only echo,' setting accurate expectations about the response — behavioral traits not present in 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?
Three short sentences, front-loaded with the core purpose before enumerating the returned content. The closing 'This is what makes a bug reproducible' adds value framing without fluff. Compact and well-ordered, with only minor density in the field enumeration.
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 single-parameter, read-only tool with no output schema, the description gives ample context: how to obtain the key, what content to expect, redaction behavior, and cost. One could wish for explicit output structure given the absence of an output schema, but the field listing partially covers this. Quite complete for the tool's complexity.
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 'fingerprint' parameter documented as 'the fp value from list_errors.' The description repeats this source relationship ('by fingerprint (from list_errors)') but adds no new syntactic or format detail beyond what the schema already provides, so the baseline of 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 states a specific verb (retrieve) and resource (one error group) keyed by fingerprint, explicitly naming its sourcing tool list_errors. It distinguishes itself from list_errors by describing the expanded content — full fields plus redacted occurrences — so an agent understands this is the detail complement to the listing tool.
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 makes the prerequisite explicit: the fingerprint comes from list_errors, implying the workflow of listing first and then drilling into a specific group. It does not name exclusions or explicitly state when not to use it, but the source relationship and the 'makes a bug reproducible' framing give clear usage context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
export_swipefile_deckSwipefile to Google SlidesAInspect
Turn a SWIPEFILE COLLECTION into a real Google Slides deck — one slide per saved ad, carrying the creative, the brand, the ad copy, the run dates with the run length, and the platform. This is the thing a marketer actually presents to a client or a team; until now the swipefile’s only export was JSON. Returns the presentation id + URL. Creates a NEW deck every time: under the drive.file scope Hermoso can only touch files it created, so it cannot add slides to a deck the user already has. A creative whose ad-library link has expired cannot be embedded — Meta signs those URLs with a short expiry — so that slide says so in words and keeps its copy and run dates, and the reply reports how many. Needs Google Drive connected (Settings ▸ Connectors ▸ Google Drive — one connection covers Drive, Sheets, Docs and Slides).
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | max ads to include, 1-60 (default 30) | |
| title | No | deck title (default: the collection name) | |
| collection | No | the swipefile collection to export, by name or id (default: the first collection) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description thoroughly discloses behavioral mechanics beyond the annotations: it explains the drive.file scope limitation (why it cannot modify existing decks), the handling of expired ad-library links (falls back to textual description, reports count), returns presentation id+URL, and the connector prerequisite. Annotations only indicate readOnly=false, openWorld=true, idempotent=false, destructive=false; the description adds substantial operational depth that an agent needs to call it correctly.
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 well-structured and front-loaded with the core purpose, then progresses to behavioral constraints and prerequisites. It is longer than strictly necessary (~150 words) but every sentence serves a distinct function (purpose, return value, new-deck behavior, expiry handling, connector requirement). Slight over-explanation of the expiry edge case could be trimmed, but overall it earns its length.
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 tool with no output schema, it explicitly states the return value (presentation id + URL). It covers failure modes (expired links), scope limitations, and the required connector setup. It also handles the fact that all parameters are optional by stating defaults. Nothing an agent needs to call this tool 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% — each parameter (limit, title, collection) already has explicit descriptions including defaults. The main description adds no additional meaning about parameters beyond what the schema provides. Per the rubric, with high schema coverage the baseline is 3; the description doesn't elevate it further.
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 opens with a specific verb+resource: 'Turn a SWIPEFILE COLLECTION into a real Google Slides deck', and enumerates exactly what each slide carries (creative, brand, copy, run dates, platform). It also differentiates from siblings by noting 'until now the swipefile’s only export was JSON', making it clear this is the dedicated Slides export. No ambiguity about what the tool does.
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 the clear use case ('the thing a marketer actually presents') and provides critical constraints: creates a NEW deck every time, cannot add to an existing deck due to drive.file scope, and requires Drive connected (with explicit settings path). It implicitly contrasts with JSON export and other Drive file tools (e.g., create_doc, create_sheet) by positioning it as the presentation-specific exporter, though it does not name alternatives explicitly. That is sufficient context for an agent to decide when to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fetch_app_screensFetch App Store screensAIdempotentInspect
Pull an APP brand's REAL App Store screenshots into the workspace brand, so a screen-hungry native format can use them. Use when the brand has 0–1 app screens on file and you want make_template_ad(template:'app-ui-tour'), or the user asks to 'pull my app's screenshots'. Pass appName (defaults to the saved brand's name). FREE — a keyless App Store lookup. It needs a CONFIDENT match: an ambiguous or unknown app returns 0 screens and saves nothing, which you should relay plainly rather than retrying with guesses. On success the screens are saved to the brand (durable URLs) and are immediately usable.
| Name | Required | Description | Default |
|---|---|---|---|
| appName | No | the app's name to look up on the App Store — defaults to the saved brand's name | |
| brandId | No | a brand id/name from list_brands to save the screens onto; omit to use the active brand |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses it modifies the brand by saving screens (consistent with readOnlyHint false), is free and keyless, and requires a confident match. It clearly explains failure behavior ('returns 0 and saves nothing') and instructs to relay plainly. This adds significant context beyond the annotations, which already state idempotent and non-destructive.
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 dense and efficient. It front-loads purpose, then gives usage, failure, and success details. Some marketing emphasis (e.g., 'REAL', 'FREE') adds flavor but each sentence contributes value. Slightly verbose in tone, but overall well-structured and 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 tool with only two optional parameters and no output schema, the description fully covers when to use it, what happens on success and failure, and where data is saved. It also mentions that screens are immediately usable. Nothing an agent needs 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?
Both parameters (appName and brandId) are fully described in the schema (100% coverage). The description minimally repeats appName's default but does not introduce new semantics. Since the schema already carries the parameters' meaning, a baseline score 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?
Clearly states it pulls App Store screenshots into the workspace brand, with a specific verb and resource. Mentions the use case (app-ui-tour template) which helps disambiguate from other asset tools. The definition is specific about the source (App Store) and destination (brand).
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 provides conditions for use: when the brand has 0–1 app screens and the user wants make_template_ad(template:'app-ui-tour') or asks to 'pull my app's screenshots'. Also advises against retrying on ambiguous matches, giving both positive and negative guidance. This leaves no ambiguity about when to invoke the tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fetch_assetFetch assetARead-onlyInspect
Resolve a generated asset reference (a /generated/… path or any URL) to a clickable absolute URL + a direct download URL.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | the asset url or /generated/ path | |
| name | No | optional filename for the download |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, so the agent knows this operation is safe and non-mutating. The description adds the behavioral detail that it returns two URL forms (clickable and download), which is helpful. However, it doesn't mention potential failure modes (e.g., invalid reference, auth) or any rate limits. Given the low annotation bar, a 3 is appropriate.
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, information-dense sentence that leads with the core purpose and specifies input constraints. There is zero fluff; every part of the sentence earns its place. The structure is exemplary for a simple utility 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?
The tool is simple (2 params, 1 required) and the description fully explains the output (both URL types). Since there is no output schema, the description carries the responsibility for return values, and it does so clearly. It also defines the accepted input format, so an agent has everything needed to invoke it correctly. Complete for its complexity.
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%, both 'url' and 'name' are described in the schema. The tool description doesn't add parameter-specific detail beyond what the schema provides (e.g., no format examples or edge cases). Since the schema carries the full load, baseline 3 is correct.
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 the verb ('Resolve'), the resource ('a generated asset reference'), and the exact outcome (clickable absolute URL + download URL). It even specifies the accepted input forms (/generated/ path or any URL), making the purpose unambiguous. No sibling tool performs this action, so no differentiation is needed.
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 the use case: whenever an agent has an asset reference that needs to be converted to usable URLs. It doesn't explicitly state when not to use it or list alternatives, but given the absence of any similar sibling tool, this is clear context. The lack of exclusions is acceptable because there are no obvious competing tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fetch_social_dataFetch social dataARead-onlyInspect
Generic escape hatch for any ALLOWLISTED long-tail social/web endpoint the dedicated search_* tools don't cover — e.g. {path:'/v1/instagram/profile', params:{handle:'nike'}}. Allowlisted platform families: TikTok (+ TikTok Shop), Instagram, YouTube, Facebook (organic profiles/posts/events/marketplace), LinkedIn (organic posts/companies), Twitter/X, Reddit, Threads, Snapchat, Pinterest, Twitch, Bluesky, Truth Social, Rumble, Spotify, SoundCloud, GitHub, Google search, link-in-bio pages (Linktree etc.). Param names vary per endpoint (profiles use handle, keyword searches use query, Reddit uses subreddit). WARNING: returns RAW provider JSON — large and messy; prefer the dedicated search_* tools. Spends credits.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | exact endpoint path, e.g. '/v1/tiktok/profile' — non-allowlisted paths are rejected | |
| params | No | endpoint query params, e.g. {handle:'nike'} |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=true and openWorldHint=true, and the description is consistent (fetching data is read-only). Beyond the annotations, the description discloses that it returns RAW provider JSON — large and messy — and that it spends credits. These are meaningful behavioral traits that help the agent anticipate side effects and output format without contradicting any annotation.
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 dense but every sentence earns its place: purpose, example, allowlisted platforms, parameter naming conventions, the warning about raw output, and the credit cost. The most important info is front-loaded, and there is no filler or repetition of schema details.
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 the tool's open-ended nature (generic endpoint, no output schema), the description is complete enough for an agent to decide whether to use it and how to invoke it. It lists the platform families, explains the path/params structure, warns about the raw output, and notes credit consumption. It does not attempt to enumerate every endpoint, which would be unrealistic, but it equips the agent with the necessary guardrails.
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% (both path and params have descriptions). The description adds practical semantic value by explaining that param names vary per endpoint and providing concrete examples (handle for profiles, query for keyword searches, subreddit for Reddit). This goes beyond the generic schema descriptions and helps the agent construct valid params correctly.
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 purpose: a generic escape hatch for any ALLOWLISTED long-tail social/web endpoint not covered by the dedicated search_* tools. It provides a concrete example ({path:'/v1/instagram/profile', params:{handle:'nike'}}) and explicitly distinguishes itself from the search_* siblings, so an agent can tell when to reach for it.
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 explicit guidance: use it only for long-tail endpoints not covered by the dedicated search_* tools, and explicitly says 'prefer the dedicated search_* tools' and warns that it 'spends credits.' This clearly states when to use it, when not to, and names the alternative category.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_competitorsFind competitorsARead-onlyInspect
Discover a brand's competitor / similar / adjacent brands from its domain (Claude grounded by web search). mode=competitors (default, excludes the searched company), inspiration (best relevant ads incl. it), or company. 0 credits.
| Name | Required | Description | Default |
|---|---|---|---|
| mode | No | 'competitors' (default, excludes the searched company), 'inspiration' (best relevant ads incl. it), or 'company' | |
| domain | Yes | the brand domain, e.g. flourish.com |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, openWorldHint=true, and destructiveHint=false, covering the safety profile. The description adds valuable context beyond that: it mentions the tool is 'Claude grounded by web search' (indicating web-based grounding) and clarifies the behavior of each mode. However, it does not elaborate on the 'company' mode's exact output, leaving a minor gap in transparency.
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 concise and front-loaded: it opens with the core purpose, then efficiently covers modes and cost in a few short sentences. Every sentence adds useful information—purpose, grounding, mode details, and cost—with no redundancy or 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 tool with no output schema, the description does not describe the return format (e.g., list of brand names/domains) or any prerequisites like domain formatting. The 'company' mode is mentioned but its behavior is not explained. Given the tool's moderate complexity (2 params, modes), the description is somewhat incomplete, though the core purpose is clear.
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 parameters are fully documented in the schema. The description adds meaning by explicitly stating the default mode ('competitors (default)') and the exclusion behavior ('excludes the searched company'), which goes slightly beyond the schema's enum descriptions. This adds value but does not dramatically compensate for any missing param details.
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 the tool's function: 'Discover a brand's competitor / similar / adjacent brands from its domain.' It names the specific resource (brands) and the input (domain), and differentiates from sibling tools like pull_competitor_ads or competitor_teardown by focusing on brand discovery rather than ads or analysis. The modes are also mentioned, adding specificity.
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 usage context by explaining the three modes and their behavior (competitors excludes searched company, inspiration includes it, company presumably returns the company itself), and notes the cost ('0 credits'). However, it does not explicitly state when to use this tool versus related siblings (e.g., competitor_teardown) or when not to use it, leaving some room for inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_creatorsFind the creators already winning in a nicheARead-onlyInspect
Scan organic TikTok, Instagram Reels and YouTube for a niche across a few query variants, fold the posts into creators, and rank them on median views, engagement rate and how often they show up for that niche; the top rows get follower counts AND public contact info (an Instagram business email / phone / category, the bio link, an email in a TikTok bio) so outreach can start from the result. Real people, not AI actors — for influencer sourcing, UGC casting and partnership prospecting ("who should we send product to?"). About one credit per search call (platforms × queries, default 3 × 3) plus one per enriched profile; repeats inside 20 minutes are free. Then shortlist (save_to_swipefile), check a profile (instagram_profile / fetch_social_data), draft outreach (generate_text), or approve them for Partnership Ads (manage_meta_partnership_creator).
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | creators to return, 1–30 (default 12) | |
| niche | Yes | product category, topic or hashtag — "calorie tracker app", "matcha", "#cleanbeauty" | |
| enrich | No | read follower counts for the top 6 (default true, ~1 credit each) | |
| queries | No | query variants per platform, 1–4 (default 3); each is a paid search call | |
| platforms | No | default all three | |
| minAvgViews | No | ||
| minEngagement | No | interactions per view, 0–1 (0.05 = 5%) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnly/openWorld/destructive annotations, the description discloses credit economics ('one credit per search call (platforms × queries, default 3 × 3) plus one per enriched profile; repeats inside 20 minutes are free'), enrichment behavior, and the data-quality guarantee 'Real people, not AI actors'. This gives an agent clear expectations about cost, output contents, and reliability.
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 paragraph is long but information-dense: scanning behavior, ranking criteria, contact data, use cases, credit costs, and follow-up tools are all present. It is front-loaded with the core function before moving to cost and workflow. It could be broken into clearer sentences or bullets, 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 7 parameters, no output schema, and a paid search tool, the description covers the essentials: output contents ('the top rows get follower counts AND public contact info'), credit cost, and intended workflow. The main completeness gap is the undocumented minAvgViews parameter, which neither the schema nor the description explains clearly, leaving a small but real ambiguity for an agent.
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 high (86%), so the baseline is 3; the description adds value by tying queries and platforms to credit costs and explaining that enrich yields 'follower counts AND public contact info'. It also connects ranking to 'median views, engagement rate and how often they show up,' informing parameters like minAvgViews and minEngagement. One gap remains: minAvgViews has no schema description and the tool description never explains its units, so it does not reach a 5.
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 a specific verb ('Scan organic TikTok, Instagram Reels and YouTube'), a concrete resource (creators matched to a niche), and a clear outcome (ranked creators with followers and public contact info). It also distinguishes itself from raw search or saved-creator siblings by saying 'fold the posts into creators' and 'Real people, not AI actors.'
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?
Use cases are explicit: 'for influencer sourcing, UGC casting and partnership prospecting' and 'who should we send product to?'. It also names follow-up tools like save_to_swipefile, fetch_social_data, generate_text, and manage_meta_partnership_creator, giving an agent the downstream workflow. It stops short of an explicit when-not-to-use warning versus content-search siblings, so it earns a 4 rather than 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_toolsFind a Hermoso tool by name or taskARead-onlyIdempotentInspect
Search EVERY Hermoso tool — including the paid-campaign (ads), analytics and channel_admin groups that are NOT in this session's starting list because of their size — by name, task or group, and get each one's parameters in one line. Use it the moment the user asks for something you do not see a tool for (a campaign, an ad set, a lead form, a click-to-WhatsApp ad, a report, keywords, audiences): a tool missing from your list is NEVER proof the feature is missing. Then run the tool with call_tool. Free, read-only.
| Name | Required | Description | Default |
|---|---|---|---|
| group | No | limit to one group: core, research, create, channels, channel_admin, analytics, ads, files, workspace | |
| limit | No | how many to return (default 12, max 40) | |
| query | No | words from the task or the tool name, e.g. "lead form", "whatsapp", "google ads keyword", "meta insights" |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already carry the safety profile (readOnlyHint=true, idempotentHint=true, destructiveHint=false), and the description adds context beyond them: the search spans tools outside the session's starting list, it is free, and it returns one-line parameter summaries. These traits align with the annotations, so there is no contradiction.
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 sentences and roughly 90 words, with the core purpose front-loaded and every sentence carrying distinct information: scope, trigger, decision rule, follow-up, and cost. It is dense, but appropriately so for a discovery tool that must override the agent's default assumption that its list is complete.
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 carries the burden of explaining return values, and it does ('parameters in one line'). For a discovery tool with zero required parameters, it covers scope, when-to-use, output shape, follow-up action, and cost; limit defaults and enum values live in the schema where they belong.
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%, putting the baseline at 3, but the description adds value by showing query formulation examples ('lead form', 'whatsapp', 'google ads keyword', 'meta insights') and naming concrete group values (`ads`, `analytics`, `channel_admin`) that map directly to the group parameter.
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+resource ('Search EVERY Hermoso tool'), names the three search dimensions (name, task, group), and specifies the output ('each one's parameters in one line'). It clearly distinguishes itself from siblings like call_tool and hermoso_capabilities by explicitly flagging the hidden `ads`, `analytics`, and `channel_admin` 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?
The description gives an explicit trigger ('Use it the moment the user asks for something you do not see a tool for') with concrete examples (campaign, ad set, lead form, click-to-WhatsApp ad). It reinforces the decision rule with a strong negative framing ('a tool missing from your list is NEVER proof the feature is missing') and names the follow-up action ('Then run the tool with call_tool'), effectively drawing the boundary against execution tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
finish_videoFinish videoAInspect
Post-process an EXISTING rendered video (its served mp4 URL) with the proven direct-response 'reviewer' finish and/or a film-grain pass — no AI model, ~30s, a couple of credits. pills=true composites a header pill (e.g. '10/10 would buy again'), a brand-accent sub-pill, and 3-4 green-check proof pills cascading in on the beat (YOU author the copy: header ≤40 chars, sub ≤34, each point ≤44 — concrete real benefits, never fabricated stats). grain=true applies a subtle camera-grain finish that makes photoreal AI renders look phone-shot ('less AI') — works alone or with pills. Returns a NEW video; the original is untouched.
| Name | Required | Description | Default |
|---|---|---|---|
| sub | No | accent sub-pill copy, ≤34 chars (usually the product/brand) | |
| grain | No | default false — anti-AI film-grain finish | |
| pills | No | default true — set false for a grain-only pass | |
| accent | No | brand accent hex for the sub-pill | |
| header | No | header pill copy, ≤40 chars (required when pills is on) | |
| points | No | 3-4 proof points, ≤44 chars each | |
| videoUrl | Yes | the served URL of the video to finish (from a previous render/job) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With annotations all set to false (readOnlyHint, destructiveHint, idempotentHint), the description carries the full behavioral burden and does so thoroughly. It discloses that the original is untouched (non-destructive), gives time and cost estimates (~30s, a couple of credits), explains the aesthetic effect of grain ('less AI'), and warns against fabricated stats. This is rich, specific behavioral context that goes far beyond what annotations provide.
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 a single dense paragraph, but every sentence carries information: purpose, modes, constraints, and side effects. It front-loads the core action and the result (new video, original untouched). It could be slightly more streamlined, but there is no filler or repetition.
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 tool with 7 parameters and no output schema, the description covers the essential context: it explains both modes, how they interact, the return behavior ('Returns a NEW video'), and the non-destructive guarantee. It does not specify the exact output format (e.g., URL object), but for a post-processing tool that returns a video, that level of detail is likely sufficient. Minor gaps like error handling are not critical given the clarity elsewhere.
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 already covers 100% of parameters with descriptions, so the baseline is 3. The description adds value by explaining the visual and strategic purpose of pills and grain, clarifying that the agent authors the copy with character limits (repeated from schema but reinforced), and describing how grain works alone or with pills. This complements the schema without redundancy.
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 opens with a specific verb ('Post-process') and a precise resource ('EXISTING rendered video (its served mp4 URL)'), immediately distinguishing this from generation or editing tools. It names the two modes (reviewer finish and grain pass) and the visual elements (header, sub-pill, proof pills), leaving no ambiguity about what the tool does.
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 explicitly constrains when to use it: it requires an existing rendered video URL from a previous render/job, and states it is a post-processing step ('no AI model'). It does not explicitly name sibling alternatives like edit_video or upscale_video, but the strong precondition and the mention of 'proven direct-response reviewer finish' effectively distinguish it. The guidance is clear enough for an agent to route correctly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fix_beatFix a video beatAInspect
Surgically re-render ONE time window (1.5-8s) of an existing rendered video and splice it back on the VIDEO TRACK ONLY — the rest of the video and ALL audio stay byte-identical. Use when one beat/shot is broken ('the shot at 8 seconds glitches') and a full re-render would waste the parts that worked; bills only the replacement clip's seconds (~1/3 of a full render). Do NOT pick a window covering spoken dialogue (a video-only splice under speech breaks lip-sync) — pass speechWindows to enforce this.
| Name | Required | Description | Default |
|---|---|---|---|
| prompt | Yes | what the replacement footage should show — describe the shot, matching the master's style | |
| refImage | No | optional product/style anchor image URL | |
| videoUrl | Yes | the served URL of the master video to fix | |
| endSeconds | Yes | window end in seconds (window 1.5-8s) | |
| startSeconds | Yes | window start in seconds | |
| speechWindows | No | [[start,end],...] windows with spoken lines — the fix window must not overlap these |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations provide minimal safety hints (all false), so the description carries the full burden. It discloses that the tool modifies the video track only, keeps audio byte-identical, bills only the replacement seconds (~1/3 of full render), and warns about lip-sync issues under dialogue. This is thorough behavioral disclosure beyond the schema.
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 a compact paragraph with a clear logical flow: core action, use cases, billing impact, and a critical warning. No fluff; every sentence serves a purpose and the most important constraint (video-only splice) 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?
The tool is complex (6 params, nested array, specific constraints) and the description covers its purpose, constraints, and billing implications well. It misses the output format (e.g., returns a job ID or new video URL) and error conditions, but the core use cases are fully addressed.
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%, giving baseline 3, but the description adds context: the 1.5-8s window constraint, the meaning of prompt relative to master style, and the importance of speechWindows in avoiding dialogue overlap. This elevates understanding beyond bare parameter names.
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 precise verb-resource pair: 're-render ONE time window' of an existing video, and further distinguishes itself by specifying VIDEO TRACK ONLY with byte-identical preservation of the rest. It clearly separates from siblings like full re-render or clip_video by emphasizing surgical splicing.
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 states when to use ('when one beat/shot is broken'), when not to (avoid dialogue windows), and names the alternative (full re-render) with reasoning. Also gives a concrete negative condition and instructs to pass speechWindows to enforce that constraint.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
forgetForget a memoryADestructiveIdempotentInspect
Delete a saved Memory item by its id (from list_memory). Records a cross-device delete so it doesn’t come back. Minor + re-creatable (you can remember it again), so no confirm needed.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | the memory item id (from list_memory) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already flag destructiveHint=true and idempotentHint=true, but the description adds critical context beyond these: it records a cross-device delete (so it won't reappear), and explains the action is minor/re-creatable and thus requires no confirmation. This materially enriches the behavioral model 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?
Two sentences, no fluff. The first sentence states the core action and source of id; the second explains side effects and the no-confirm rationale. Information is front-loaded and every word 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, single-parameter tool with no output schema, this description covers the action, the id source, cross-device persistence, reversibility, and why no confirmation is needed. Nothing essential is missing for an agent 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 description coverage is 100% and both the schema and description state the id is from list_memory. The description adds no additional parameter semantics beyond what the schema provides, so 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 the exact verb 'Delete' and resource 'saved Memory item', and explicitly references the id source (list_memory). Clearly distinguishes from sibling tools like remember and list_memory by identifying the delete operation.
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?
Conveys clear usage context: use this when you have a memory id (from list_memory) and want to remove it. It does not explicitly mention when not to use it or alternatives, but the context is unambiguous enough for an agent 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.
format_sheetFormat a Google SheetAIdempotentInspect
Make an exported sheet readable: bold the header row, FREEZE it so it stays visible while scrolling, and auto-size the columns so nothing is cut off. Worth calling right after create_sheet — a raw export with unsized columns and a header that scrolls away is the difference between a spreadsheet someone reads and one they close. Changes no cell VALUE, so it is never gated. The defaults do all three on the first tab; pass tab to pick another, freezeRows:0 to skip freezing, boldHeader:false or autoResize:false to skip those.
| Name | Required | Description | Default |
|---|---|---|---|
| tab | No | tab title or numeric sheetId (default: the first tab) | |
| sheetUrl | No | ||
| autoResize | No | ||
| boldHeader | No | ||
| freezeRows | No | how many top rows to freeze (default 1, 0 = none) | |
| spreadsheetId | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds behavioral context beyond annotations: it states it changes formatting but not cell values, and explains how to skip individual operations via parameters. Annotations already declare idempotent and non-destructive, and the description enriches this with specifics about freezing and auto-size.
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 longer than typical, but every sentence adds value. It front-loads the purpose and then explains usage and parameter specifics. The rhetorical flourish about 'the difference between a spreadsheet someone reads and one they close' is not wasteful, but could be trimmed without loss.
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 formatting tool with no output schema, the description covers the core use case, parameter semantics, and behavioral details. It does not mention error handling or authorization, but those are covered by annotations (idempotent, non-destructive) and are not critical 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?
Schema coverage is only 33% (only tab and freezeRows have descriptions). The description compensates by explaining the defaults and how to override each operation (tab, freezeRows, boldHeader, autoResize). It does not detail sheetUrl/spreadsheetId, but those are conventional identifiers.
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 the specific actions (bold header, freeze, auto-size) and the resource (exported sheet). It also distinguishes itself from create_sheet by describing it as a follow-up formatting step, not a creation or data mutation tool.
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 provides a concrete trigger ('Worth calling right after create_sheet') and explains why (raw export with unsized columns). It also notes that it changes no cell value and is never gated, implying non-destructive use. However, it does not explicitly name alternatives for editing values or when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
generate_avatarGenerate talking avatarAInspect
Render a TALKING-AVATAR / creator lip-sync clip from a portrait image + a script. Blocks until done (1–3 min). Requires the avatar capability (canAvatar in hermoso_capabilities). Spends credits.
| Name | Required | Description | Default |
|---|---|---|---|
| image | Yes | local path or URL of the presenter portrait | |
| voice | No | voice name (Rachel/Sarah/George/Adam) | |
| script | Yes | the words the avatar speaks | |
| resolution | No | '1080p' (default) or '480p'/'720p' draft |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses important behavioral traits not covered by annotations: it blocks for 1–3 minutes, spends credits, and requires a specific capability flag. These are significant for an agent to plan execution. However, it does not mention what the tool returns (e.g., a URL, file path) or any side effects beyond spending credits, so a 4 reflects good but not exhaustive transparency.
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 with zero filler. The primary action is front-loaded, and the critical constraints (blocking, credits, capability) are stated compactly. Every clause adds value.
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 generation tool with no output schema, the description covers the core purpose, blocking duration, credit cost, and capability prerequisite. The main gap is the absence of any mention of the output format (e.g., returns a media URL or file), which an agent needs to handle the result. Given the complexity, it is mostly complete but missing that return detail.
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 each parameter already has a clear description (e.g., image is a portrait, script is the spoken words, resolution lists options). The tool description adds minimal extra meaning beyond restating 'portrait image + script'. The baseline of 3 is appropriate since the schema does the heavy lifting.
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 the tool renders a talking avatar / creator lip-sync clip from a portrait image and a script. It is specific enough to distinguish from siblings like generate_voice (audio only) or generate_video (generic video) by naming 'talking-avatar' and 'lip-sync'.
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 when to use (need a talking avatar) but does not explicitly contrast with alternatives or state when NOT to use it. The capability requirement (canAvatar) and blocking behavior suggest a specific use case, but no exclusions or comparative routing to other content-generation tools are provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
generate_imageGenerate ad imageAInspect
Render a finished ad IMAGE and return its served URL. refImages (local paths or URLs) force product-accurate compositing (drops a real product into the scene). MULTI-BRAND CAUTION: useBrand hydration pulls the SAVED workspace brand — when working a brand that is NOT the saved one (a fresh draft_brand), pass that brand's own productImages/logo as refImages (and useBrand:false) or the output composites the WRONG brand's product. NOTE that the saved-brand hydration also decides the ENGINE: attaching product photos routes the render to the compositing model, so a model you named is only honoured when no references ride — pass raw:true (or useBrand:false) to render on exactly the model you asked for. model = a catalog id from hermoso_capabilities (omit for the default). RAW MODEL ACCESS: raw:true dispatches your prompt to the model BYTE-IDENTICAL — no rewriting, no appended guidance, no negative prompt, no brand references attached on your behalf. Credits, the durable delivery of the finished asset and the per-model validation are unchanged. Fast (seconds). Spends credits.
| Name | Required | Description | Default |
|---|---|---|---|
| raw | No | RAW MODEL ACCESS: run the caller’s prompt on the named model with no Hermoso adjustments at all — the prompt reaches the provider byte-identical (no hex-to-colour-name rewrite, no prepended fidelity preamble) and NO saved-brand product photos are attached, so the model you name is the model that renders. Use it to drive the raw catalog; leave it off for an on-brand ad. Billing, the durable Library landing and per-model validation are unchanged. | |
| model | No | image model id from hermoso_capabilities | |
| prompt | Yes | the full image prompt — subject, composition, lighting, and any on-image ad text | |
| useBrand | No | default true: with no refImages, the server hydrates the SAVED brand’s product/logo references so the output lands on-brand; pass false for a pure prompt-only render | |
| imageSize | No | pixel-size preset for models that support it (e.g. 1K/2K) — omit for the default | |
| refImages | No | local file paths or URLs of product/logo references to composite in | |
| aspectRatio | No | e.g. '1:1', '9:16', '16:9' |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
All four annotation hints are false, so the description carries the full disclosure burden and meets it. It discloses that the tool spends credits, that saved-brand hydration can silently swap the engine to the compositing model, that raw:true sends the prompt byte-identical with no rewriting/guidance/negative-prompt, and that delivery and validation are unchanged. This is deep, honest behavioral disclosure far beyond what annotations provide.
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 and output, and every sentence carries distinct value (engine behavior, multi-brand caution, raw semantics, cost, timing). It is slightly dense and run-on in the engine/multi-brand passages, but contains zero filler, so it earns a high score despite the parsing effort.
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 complex tool with 7 parameters, subtle mode interactions, cost implications, and no output schema, the description is remarkably complete. It covers the deliverable (served URL), engine-selection behavior, brand hydration caution, raw mode, cost (credits), durability, and the capabilities catalog for model ids. 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 100%, but the description adds genuine cross-parameter semantics the schema cannot express alone: the interaction between refImages, useBrand, model, and raw (e.g., 'a model you named is only honoured when no references ride — pass raw:true (or useBrand:false)'). It also clarifies that model is 'a catalog id from hermoso_capabilities (omit for the default),' connecting to a sibling capability tool. This is additive meaning, not duplication.
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, resource, and output: 'Render a finished ad IMAGE and return its served URL.' This clearly distinguishes generate_image from video/voice/text siblings (generate_video, generate_voice, generate_text) and names the core deliverable. It also lays out distinct modes (compositing vs raw) that define the tool's scope.
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?
Provides rich, actionable usage context: when to pass refImages for product-accurate compositing, the explicit MULTI-BRAND CAUTION instructing to pass the fresh brand's productImages and set useBrand:false, and when to use raw:true to guarantee the named model renders. Lacks only an explicit routing against sibling image tools like render_ad or make_template_ad, which keeps it a 4 rather than a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
generate_textGenerate textAInspect
Text generation against the writing-model catalog (Claude, Gemini, GPT, Llama, DeepSeek…) — ad copy, hooks, scripts, rewrites, brainstorms. Prompt-only, no ad assembly (for a finished on-brand creative use plan_ad → render_ad). BY DEFAULT the model answers as a marketing copywriter (a short house system prompt is applied, which is what you want for ad copy); pass raw:true for a plain, unstyled answer from the model itself with NO system prompt at all. model = a writing-model id from hermoso_capabilities (omit for the default Claude orchestrator). Paid (a credit or two by length).
| Name | Required | Description | Default |
|---|---|---|---|
| raw | No | RAW MODEL ACCESS: send the prompt with NO Hermoso system prompt — the model answers as itself rather than as an ad copywriter. Use it whenever the ask is not marketing copy (analysis, code, extraction, a plain question). Default false: the copywriter framing is applied. | |
| model | No | a writing-model id from hermoso_capabilities (a Claude / Gemini / GPT / Llama / DeepSeek id) — omit for the default | |
| prompt | Yes | the writing task / question |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations are all false, offering no behavioral hints, so the description carries the full burden. It discloses the default copywriter system prompt, the raw:true escape hatch to bypass it, and that the tool is paid by length—valuable behavioral context not in the schema. It doesn't contradict annotations, though it omits error handling and response format.
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, information-dense paragraph where each sentence earns its place: purpose, scope, exclusions, default behavior, parameter tips, and cost. No redundancy or filler; the most critical scoping info is front-loaded before the parameter notes.
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 prompt-based generation tool, the description covers purpose, usage boundaries, default behavior, and cost. It omits an explicit return-type description and error cases, but these are well-implied for text generation, and the schema handles parameter documentation. The tool's complexity is low enough that this is nearly 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 100% with detailed parameter descriptions for prompt, model, and raw. The description adds only minor reinforcement (e.g., 'Claude orchestrator' for model) but doesn't introduce new semantic meaning beyond the schema. Baseline 3 is appropriate because the schema already does the heavy lifting.
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 verb 'generate' and resource 'text' against a specific writing-model catalog, and enumerates concrete use cases (ad copy, hooks, scripts, rewrites, brainstorms). It explicitly distinguishes itself from ad-assembly tools (plan_ad → render_ad) and other generation siblings (image, voice, video), making its purpose unmistakable.
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 direct when-to-use (prompt-only text generation) and when-not-to-use (for a finished on-brand creative use plan_ad → render_ad) guidance. It also explains the raw:true option for non-marketing copy, providing clear selection criteria against alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
generate_videoGenerate videoAInspect
Render a RAW video clip from your own prompt and return its served mp4 URL. For finished brand ADS prefer render_ad (it runs the Studio quality pipeline — composited text, clean speech, end card, music); use this for raw/experimental clips or precise manual control. ONE generation = one continuous clip up to the model’s longest listed duration — the longest-clip model in the catalog today renders a full multi-beat spot of up to 30 SECONDS in ONE unbroken take with native synchronized audio, so never assume a generic 8–10s cap and never stitch something that fits one clip; durationSeconds must be one of the model’s durations from hermoso_capabilities, which is the live list. TO GET A SPECIFIC MODEL, NAME IT in model: an unnamed render is routed by the server’s own auto-pool, which is narrower than the catalog, so the longest-clip and highest-resolution models are reached by naming them and not by omitting the field. Renders take 1–3 min. refImage anchors the opening frame; ttsScript adds a voiceover. AUDIO IS NOT FREE AND NOT OPTIONAL BY DEFAULT: a clip delivered with no audio of its own gets a music bed composed and CHARGED on top of the render (see musicMood and audio) — on a cheap short draft the bed can cost as much as the clip. Pass refVideo (a clip URL) to EDIT an existing video instead of generating from scratch — the omni engine transforms that clip per your prompt, inheriting the source clip’s canvas + length (aspectRatio/durationSeconds are ignored for an edit). RAW MODEL ACCESS: your prompt is NOT dispatched verbatim by default — a few small guards are appended (packaging/label safety when no reference image rides, a negative prompt on the models that take one, reference-binding lines when references ride) and hex colour codes are rewritten to colour names. Pass raw:true for none of that. raw:true dispatches your prompt to the model BYTE-IDENTICAL — no rewriting, no appended guidance, no negative prompt, no brand references attached on your behalf. Credits, the durable delivery of the finished asset and the per-model validation are unchanged. Spends credits (Starter plan is video-blocked server-side).
| Name | Required | Description | Default |
|---|---|---|---|
| raw | No | RAW MODEL ACCESS: dispatch this prompt to the model BYTE-IDENTICAL — no appended packaging/label guidance, no negative prompt, no reference-binding lines, no hex-to-colour-name rewrite. Use it when you want the model itself rather than Hermoso's render craft. Two provider-mandated corrections still apply, because the vendor hard-fails without them: an @ImageN token that outnumbers the references actually shipped is dropped, and a prompt past the endpoint's published character cap is trimmed at a sentence boundary. Billing, durable delivery and per-model validation are unchanged. | |
| audio | No | default true. false = render SILENT: no native model audio, no music bed, and no bed charge held or billed. This is the ONLY way to decline the automatic bed (see musicMood) — leave it alone for anything that should have sound, and do not combine it with ttsScript. | |
| model | No | video model id from hermoso_capabilities. Naming one is a DELIBERATE pick — the server asks before ever swapping it (no silent fallback); omit it to let the router pick | |
| prompt | Yes | the video prompt / shot description (for a refVideo edit, this is the transformation instruction) | |
| refImage | No | local path or URL to anchor the first frame | |
| refVideo | No | URL of an existing video to EDIT rather than generate from scratch — the omni engine accepts a raw clip and transforms it per your prompt, inheriting the SOURCE clip’s canvas (aspect ratio) and length (aspectRatio/durationSeconds are ignored for an edit). Omit to generate a fresh clip. | |
| ttsVoice | No | voice name, e.g. Rachel / George | |
| musicMood | No | WHICH mood the music bed is composed in (upbeat / calm / warm / epic / tense / playful / elegant / hype / chill / dramatic). It does NOT decide WHETHER there is one: a clip that comes back with no audio track — every model hermoso_capabilities lists as "silent", plus any audio model that returned mute — gets a bed composed and CHARGED automatically, at the flat per-track fee hermoso_capabilities reports as explainerMusicCredits, and omitting this field only means the mood defaults to "warm". Pass audio:false for a genuinely silent clip with no bed and no bed charge. | |
| ttsScript | No | voiceover script to speak | |
| resolution | No | '1080p' default (what we ship and bill for); '480p'/'720p' = cheaper draft passes, '4k' = premium final delivery (more credits). NOT EVERY MODEL OFFERS EVERY TIER — this enum is what the tool accepts, and each model's OWN `resolutions` list in hermoso_capabilities is what it can actually render (the longest-clip 30s model, for one, tops out at 720p). Ask for a tier the chosen model does not list and it is rendered at that model's best available tier instead, with nothing in the reply saying so — so check `resolutions` before promising anyone 1080p or 4k. | |
| aspectRatio | No | default '9:16' | |
| durationSeconds | No | length of THIS ONE clip in seconds — pick one of the CHOSEN model’s listed durations from hermoso_capabilities (never a generic guess: the lists differ per model, from 4–8s on the short models up to 30s on the longest-clip one). This is a single continuous generation, so it CANNOT exceed that model’s longest clip: a longer ask is REFUSED with nothing rendered and nothing charged (it is never quietly truncated). Past ~15s only the long-clip models qualify, and an unnamed render is routed by the narrower auto-pool — so NAME the model in `model` when you are asking for a long single take. For a spot longer than any one clip, use plan_ad with durationSeconds then render_ad, which stitches acts of at most one model clip each (on a 15s-clip model, 40s = 15+15+10). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
All annotations are false (no readOnly/idempotent/destructive hints), so the description carries the full burden — and it carries it exceptionally. It discloses billing charges ('AUDIO IS NOT FREE... the bed can cost as much as the clip', 'Spends credits'), prompt rewriting by default with raw:true as the byte-identical escape, refusal over truncation ('a longer ask is REFUSED with nothing rendered and nothing charged'), silent resolution downgrades ('rendered at that model's best available tier instead, with nothing in the reply saying so'), and 1–3 min latency. This is far beyond what annotations provide.
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 earns its place given the tool's genuine complexity (12 params, billing, raw access, edit mode, routing) — nothing is filler. However, it is a single dense wall of text (~350+ words) with heavy ALL-CAPS emphasis, dashes and parentheticals that hurt scannability. Substantial but poorly structured for an agent to parse quickly.
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 tool with zero annotations and no output schema, the description is essentially complete. It covers the return value (served mp4 URL), the single-clip duration ceiling with refusal behavior, the audio billing trap, credit spend, the raw bypass, edit-mode semantics, and model-routing pitfalls. Nothing an agent needs to call this tool correctly and avoid hidden costs 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 100% and the schema's own per-parameter descriptions are unusually rich (durationSeconds, musicMood, resolution, raw are all deeply explained), so the baseline is 3. The description adds cross-parameter value by connecting the dots: it ties durationSeconds to model choice and the narrower auto-pool, links audio to musicMood and the automatic charge, and explains how refVideo nullifies aspectRatio/durationSeconds — synthesis the schema alone doesn't provide. The description complements rather than repeats 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?
Opening sentence states a specific verb and resource: 'Render a RAW video clip from your own prompt and return its served mp4 URL.' It further differentiates from render_ad ('use this for raw/experimental clips or precise manual control') and names the sibling it is not (render_ad runs the Studio quality pipeline). An agent can cleanly separate the two tools without inspecting either 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 routing guidance: 'For finished brand ADS prefer render_ad... use this for raw/experimental clips or precise manual control.' It also gives concrete when-to conditions for editing (refVideo), for raw access (raw:true when you want the model itself rather than Hermoso's craft), and for naming a model (when you need the longest/highest-resolution tiers). The description explains not just what but when, with named alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
generate_voiceGenerate voiceoverAInspect
RAW text-to-speech from the voice-model catalog: speak a script in a chosen voice and return the served MP3 URL. For a standalone voiceover / narration clip — NOT for adding audio to a video (render_ad and generate_video voice their own spots; change_voice re-voices a finished clip). engine picks the voice model (default 'seed-audio'; also 'eleven-v3', 'minimax-speech', 'kokoro'); voice is a preset name from that engine (see hermoso_capabilities → voice engines) — a name that engine does not have is REFUSED for free with its real list, and a few engines generate their own voice and take no preset at all (the reply says which voice actually spoke). Paid (a couple of credits by length; ≤900 characters).
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | the script to speak (≤900 characters) | |
| voice | No | a voice preset from the chosen engine (e.g. 'Aria'/'George' on eleven-v3, 'stokie_en' on seed-audio) — omit for the engine default | |
| engine | No | voice-engine id: 'seed-audio' (default), 'eleven-v3', 'minimax-speech', or 'kokoro' — listed in hermoso_capabilities |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only provide flags (readOnlyHint=false, etc.), which are neutral. The description goes far beyond by disclosing: cost implications ('Paid (a couple of credits by length; ≤900 characters)'), refusal behavior ('a name that engine does not have is REFUSED for free with its real list'), and the fact that some engines generate their own voice and ignore presets, with the reply indicating which voice actually spoke. This adds rich behavioral context 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?
Though the description is long, every sentence carries actionable information. It leads with the core purpose and output, then defines scope exclusions, then details parameters, then covers edge cases and cost. There is no fluff, and the structure flows naturally from what to when to how. The density is appropriate for the tool's complexity.
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 must convey the return value, which it does ('return the served MP3 URL'). It covers parameter semantics, defaults, refusals, cost, and character limits. It also references a sibling tool (hermoso_capabilities) for authoritative voice lists. An agent has everything needed to call this tool correctly in all scenarios.
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%, meaning all parameters are described in the schema. The description adds substantial meaning: engine defaults and valid values (seed-audio default, plus others), the relationship between engine and voice presets (preset must belong to engine), and directs the agent to hermoso_capabilities for the full voice list. It also clarifies the character limit and cost model. This goes well beyond the schema's basic field descriptions.
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 clear, specific purpose: 'RAW text-to-speech from the voice-model catalog: speak a script in a chosen voice and return the served MP3 URL.' It defines the resource (voice-model catalog), the action (speak a script), and the output (MP3 URL). It also explicitly distinguishes itself from sibling tools (render_ad, generate_video, change_voice) by stating what it is NOT for, leaving no ambiguity about its role.
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 guidance is explicit: 'For a standalone voiceover / narration clip — NOT for adding audio to a video (render_ad and generate_video voice their own spots; change_voice re-voices a finished clip).' It also describes the engine choices with a default, mentions voice preset behavior, handles edge cases (engines that ignore presets and generate their own voice), and notes the character limit. This gives an agent clear conditions for when to use this tool versus alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_brandGet saved brandARead-onlyInspect
What Hermoso ALREADY KNOWS for this account/workspace — the same saved brand profile (products, logos, palette, positioning) + learned memory the web Studio uses. Call it when you need to know whether a brand is on file: if hasBrand is true you can omit brand everywhere; if false, onboard with draft_brand. Not a required first step before a render: the create tools read the saved brand by themselves. 0 credits.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint: true, but the description adds value by detailing the content returned (products, logos, palette, positioning, learned memory), the hasBrand indicator, and the fact that it costs 0 credits. It also clarifies the tool's role relative to create tools, which is behavioral context not present in annotations. No contradictions.
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 three sentences, front-loaded with the primary purpose, then usage guidance, then a caveat. There is zero filler or redundancy. Every sentence earns its place, providing essential information in a compact form.
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 the tool has no parameters and no output schema, the description needs to cover return semantics and usage context—which it does thoroughly. It states the returned elements (products, logos, palette, positioning, memory), the hasBrand flag, the cost (0 credits), and the relationship to create tools. Nothing an agent needs 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?
The tool has 0 parameters, and the schema is empty with 100% coverage. Per the rubric, 0 params gives a baseline of 4. The description doesn't discuss parameters (there are none), but it does clarify what the output contains, which is irrelevant to parameter semantics. Since there are no inputs to document, the score aligns with the baseline.
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 explicitly states that this tool returns the saved brand profile (products, logos, palette, positioning) and learned memory for the account/workspace. It clearly differentiates from siblings like list_brands (which lists brands) and draft_brand (onboarding) by focusing on the current saved brand and the hasBrand flag. The verb 'get' is implicit via title, but the description makes the resource and purpose 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?
Provides explicit when-to-use guidance: call it to check if a brand is on file, with clear branching (if hasBrand true, omit brand; if false, onboard with draft_brand). Also states when not to use it: not required before a render because create tools read the saved brand automatically. This is strong, actionable usage guidance that distinguishes from alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_drive_fileGet a Drive file’s detailsARead-onlyInspect
Fetch one Drive file’s metadata — name, type, size, modified time, a webViewLink to open it and a webContentLink to download it. Pass fileId (from list_drive_files). Read-only.
| Name | Required | Description | Default |
|---|---|---|---|
| fileId | Yes | the Drive file id (from list_drive_files) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, and the description explicitly restates 'Read-only' (consistent, not contradictory). It adds value beyond annotations by listing the metadata fields returned, which helps the agent anticipate the response shape even without an output schema.
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 with zero filler: the first states the action and return fields, the second gives the parameter source and read-only nature. It is front-loaded and every sentence 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 read tool with one parameter and no output schema, the description fully covers the return fields and parameter origin. Annotations handle the safety profile. Nothing the agent needs 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?
The schema already provides a description for fileId, and the description adds the crucial origin hint ('from list_drive_files'), which is not in the schema. This gives the agent actionable context for obtaining a valid 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 description states a specific verb ('Fetch') and resource ('one Drive file's metadata'), and enumerates the exact fields returned (name, type, size, modified time, webViewLink, webContentLink). It clearly distinguishes from siblings like list_drive_files (which lists many) and update/delete_drive_file (which mutate).
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 provides a clear source for the parameter ('Pass fileId (from list_drive_files)'), which acts as an explicit usage hint. It doesn't explicitly list when not to use, but the purpose is unambiguous and there is no competing sibling for single-file retrieval.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_jobGet render jobARead-onlyInspect
Poll a render job by id. Returns status (queued|running|done|error), progress, and on done the served media URL. Renders take 1–3 minutes: keep calling this until done/error without asking the user — several calls is normal, not a stall. An id that does not exist on this account answers status "not_found" — that is FINAL: stop polling it, and do not re-fire the render (that double-charges).
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | the job id, e.g. job_xxx |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations (readOnlyHint, destructiveHint), the description adds crucial behavioral context: expected render duration (1–3 minutes), the polling loop, and the finality of the 'not_found' status including the cost implication of re-firing. This is operational nuance not covered by annotations and directly informs agent behavior.
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-loaded: it opens with the core action and return values, then provides timing and termination guidance. Every sentence earns its place, with no filler or redundancy.
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 the tool's simplicity (single parameter, no output schema), the description covers all necessary information: statuses, progress, URL on completion, polling expectations, and the not_found edge case. An agent can call this tool correctly without additional information.
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 a description for the id parameter ('the job id, e.g. job_xxx'). The tool description refers to the id but adds no additional semantic detail beyond confirming it targets a render job. Since the schema already captures the parameter meaning, the baseline score 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 clearly states the tool's purpose: 'Poll a render job by id' and lists what it returns (status, progress, served media URL). This uses a specific verb (poll) and resource (render job), and distinguishes it from other get_* tools that retrieve different resources (e.g., get_brand, get_drive_file).
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 explicit usage guidance: poll repeatedly until done/error without asking the user, and warns that a 'not_found' status is final and must not be re-fired to avoid double-charging. It also sets expectations about call frequency ('several calls is normal') and identifies when polling is no longer appropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_linkedin_leadRead one LinkedIn leadARead-onlyIdempotentInspect
One LinkedIn lead by id (from list_linkedin_leads), with every answer named by field. Personal data — show, never republish. Read-only, free.
| Name | Required | Description | Default |
|---|---|---|---|
| leadId | Yes | ||
| pageId | No | the company Page that owns the form — from list_linkedin_pages; omit when one Page is shared | |
| adAccountId | No | read forms owned by an AD ACCOUNT instead of a Page |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already supply read-only/idempotent/non-destructive hints; the description adds value by disclosing that results are named by field and that the lead contains personal data that may be shown but never republished. It repeats read-only/'free' status without contradicting any annotation.
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 pack identity, return-shape, and handling policy with no filler. The key scoping phrase ('One LinkedIn lead by id') 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 one-required-parameter read tool with strong annotations, the description is nearly complete: it explains where the ID comes from, what output to expect, and the sensitive-data policy. It doesn't specify error/not-found behavior, but that is a minor gap for a simple read by ID.
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 already describes pageId and adAccountId in useful terms; the description mainly clarifies leadId's provenance ('by id (from list_linkedin_leads)'). With 67% schema coverage, this is adequate but not a major contribution beyond 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?
The description states a specific operation — retrieving one LinkedIn lead by ID — and ties the ID to list_linkedin_leads, which distinguishes it from the list/collection siblings. It also communicates the output characteristic ('every answer named by field').
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 locates the tool in a workflow: after listing leads, pass a lead ID to read that single lead in full. It doesn't name sibling alternatives or state when not to use it, but the contextual signal is strong and the privacy instruction gives a use restriction.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_onedrive_fileGet a OneDrive file’s detailsARead-onlyInspect
Fetch one OneDrive item’s metadata — name, type, size, modified time, a webViewLink to open it and a webContentLink to download it. Pass fileId (from list_onedrive_files). Read-only.
| Name | Required | Description | Default |
|---|---|---|---|
| fileId | Yes | the OneDrive item id (from list_onedrive_files) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, and the description reinforces this with 'Read-only'. It adds value by specifying the exact metadata returned (webViewLink, webContentLink, etc.), which is beyond what annotations convey. No contradiction exists; the description complements the annotations with concrete output details.
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 a single, well-structured sentence that front-loads the main purpose, lists the returned fields, and includes the input requirement. There is no wasted language; every clause 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 read-only fetch with one parameter, the description adequately covers input (fileId from list_onedrive_files) and output (specific metadata fields). It does not mention error cases or permissions, but given the readOnlyHint annotation and the absence of an output schema, these are not critical gaps. It is sufficiently complete 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?
Schema description coverage is 100% – the only parameter fileId is described as 'the OneDrive item id (from list_onedrive_files)' in the schema. The description repeats this source, adding no new semantic meaning beyond what the schema already provides. Thus, it meets the baseline of 3 but does not exceed it.
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 it fetches metadata for a single OneDrive item, listing specific fields (name, type, size, modified time, webViewLink, webContentLink) and says to pass fileId. This distinguishes it from sibling operations like update_onedrive_file, delete_onedrive_file, and convert_onedrive_file, as it is a read/fetch operation.
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 tells the agent to pass fileId from list_onedrive_files, providing a clear prerequisite and flow. It explicitly mentions 'Read-only', aligning with its intended use for inspection. It does not name alternative tools for when not to use it, but the context is strong enough for correct selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_post_refillPosting refill statusARead-onlyInspect
Show the automatic posting refill for this brand: whether it is on, whether it is in dry-run (preview) mode, how many days ahead it fills, its render budget, when it next runs, and how many posts are queued right now. It also names the channels that CANNOT be posted to and why. Read-only, free.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, lowering the disclosure burden. The description adds genuinely useful context beyond annotations: the operation is free (cost implication), it surfaces dry-run preview mode, and it reports which channels are blocked and why. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two well-structured sentences that front-load the core purpose before listing the returned fields and the blocked-channels detail. Each enumerated item earns its place; slightly long but no wasted 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?
With no output schema, the description carries the burden of explaining the return, and it does so thoroughly by listing every field an agent would care about. Simple zero-parameter invocation means nothing is missing for correct usage.
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 and an empty schema, so the baseline is 4. The description compensates by detailing the output fields the call returns, which substitutes effectively for any parameter documentation.
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 a specific verb ('Show') and resource ('the automatic posting refill for this brand') and enumerates the exact fields returned (on/off, dry-run mode, days ahead, render budget, next run, queued posts, blocked channels). This clearly distinguishes it from the mutating siblings set_post_refill and run_post_refill.
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 communicates read-only, free status-check context, which implies it is for inspecting configuration rather than changing or triggering it. However, it does not explicitly name the alternative tools (set_post_refill, run_post_refill) or give a contrastive condition for when to use them, leaving some routing to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_settingsRead app settingsARead-onlyInspect
Read this account's app settings — the LANGUAGE Hermoso writes ads, copy and answers in, the app appearance (theme), and whether the weekly competitor-watch email is on. Same settings as the web app's Settings pane. Read-only, free.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is covered. The description adds value by specifying that the tool is 'free', matches the web app settings, and enumerates the returned settings, which provides behavioral context 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 description is two sentences, front-loads the core purpose, and every clause adds information (scope, contents, parity, read-only/free). No fluff or redundancy.
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 parameterless, read-only tool with no output schema, the description is complete: it states what settings are returned, confirms it matches the web app, and notes it is free. There is nothing an agent needs to invoke it correctly that 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?
The tool has zero parameters and an empty schema, so the baseline is 4 per the calibration. The description correctly implies there are no inputs, and it doesn't need to explain parameter formatting since none exist.
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 specifies a clear verb ('Read'), a resource ('this account's app settings'), and enumerates the exact settings included (language, theme, weekly email toggle). It also notes parity with the web app's Settings pane, which distinguishes it from the many sibling tools that operate on different resources (e.g., voice, posts, connectors).
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 by stating what it reads and that it is read-only and free, but it does not explicitly redirect away from alternatives like update_settings or mention when not to use it. The context is clear, but there is no explicit guidance on alternate selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_skillGet skillARead-onlyInspect
Load a bundled skill’s full SKILL.md workflow instructions by name (from list_skills). Follow the loaded instructions to run that workflow with the other tools. Read-only, free.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | bundle name from list_skills, e.g. hermoso-generate |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is covered. The description adds value by stating 'free' (cost context) and specifying that it loads the 'full SKILL.md workflow instructions', which clarifies what the tool returns. This goes slightly beyond the annotations without 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?
Two concise sentences, both front-loaded with the primary purpose and immediately after, the prerequisite and usage guidance. No redundant phrasing or filler; every word 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 one-parameter read-only tool, the description is complete. It names the source (list_skills), what is returned (full SKILL.md instructions), the cost (free), and how to use the result. No output schema exists, and the description sufficiently covers what an agent needs to know.
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 the only parameter 'name' already has a descriptive schema entry ('bundle name from list_skills, e.g. hermoso-generate'). The description adds no additional parameter-specific details beyond what the schema provides, so the 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?
The description states a specific verb ('Load') and a specific resource ('bundled skill's full SKILL.md workflow instructions'), and it clearly differentiates from the sibling list_skills by indicating this tool loads the instructions rather than just listing names. It also notes it is read-only and free, which reinforces the purpose.
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 explicitly says the name comes 'from list_skills', establishing a prerequisite and guiding the agent to call list_skills first. It then instructs to 'Follow the loaded instructions to run that workflow with the other tools', explaining how to use the result, which is clear and actionable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
hermoso_capabilitiesStart here: what Hermoso can do and what it costsARead-onlyInspect
Probe what this Hermoso account can do RIGHT NOW: available image/video model ids + their exact credit costs, aspect ratios, video durations, the recipe ids, and the canEdit/canAvatar flags. Call it when you need a specific model id, an exact cost, or a capability you are not sure of. It is NOT a prerequisite for rendering: generate_image, generate_video and render_ad all run with model omitted and route to the server’s own default. Read-only, free.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is covered. The description adds further behavioral context: it is 'free' (costs no credits) and clarifies that the rendering tools route to server defaults when `model` is omitted. This goes beyond the annotation-derived safety and helps the agent plan resource usage.
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 sentences pack all essential information without redundancy: what it does, when to call it, and a clarifying non-prerequisite statement. The key purpose is front-loaded, and every sentence 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 parameterless, read-only probe, the description is fully sufficient. It enumerates the exact types of data returned, states that it is free, and clarifies that it is not needed before rendering. Together with the annotations, an agent has everything required to decide whether and when to invoke 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?
The tool has zero parameters, so the schema trivially covers 100% and there is nothing to explain. The baseline for 0 parameters is 4, and the description does not need to add parameter documentation; it instead focuses on the output contents, which 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 opens with a strong verb-object pair ('Probe what this Hermoso account can do') and enumerates exactly what is returned: model ids, credit costs, aspect ratios, durations, recipe ids, and flags. It distinguishes itself from rendering tools by explicitly stating it is not a prerequisite, so an agent can tell it apart from generate_image, generate_video, and render_ad without opening their 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?
Provides explicit when-to-use guidance ('Call it when you need a specific model id, an exact cost, or a capability you are not sure of') and also states when it is NOT needed ('It is NOT a prerequisite for rendering'), naming the sibling tools that run without it. No ambiguity remains.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
hermoso_creditsCredit balanceARead-onlyInspect
Return the account credit balance, the credits this account has spent on the calls listed, those recent priced calls, and costModel — the one-sentence rule of what costs credits. THE RULE: only AI model runs and Ad Spy research spend credits; publishing, scheduling, ads management, analytics, comments, DMs and connectors are FREE on every plan (X is the single per-call exception). Check before kicking off paid generation; answer "does posting cost credits?" with NO.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false. The description adds valuable behavioral context beyond those annotations: the rule for what consumes credits, the free operations list, and the single per-call exception. This helps the agent reason about cost implications without contradicting the read-only annotation.
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 primary return value and then delivers the cost rule and usage guidance. It is somewhat longer than necessary, especially with the all-caps 'THE RULE' emphasis, but every sentence adds useful information for the agent.
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 balance tool without an output schema, the description covers the essential return elements and the cost model well. It does not detail the exact structure of 'recent priced calls' or specify how recent, but the tool is simple enough that an agent can call it correctly with this information.
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 and the schema confirms this with 100% coverage. There are no parameter semantics to document, so the baseline of 4 applies. The description indirectly supports invocation by clarifying what the returned data means.
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 uses a specific verb ('Return') and identifies the resource and the exact data returned: account credit balance, credits spent on listed calls, recent priced calls, and costModel. This clearly differentiates it from related sibling tools like buy_credits and billing_status by stating what this particular tool provides.
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 explicit guidance on when to use the tool: 'Check before kicking off paid generation.' It also preempts a common agent question by stating that posting does not cost credits. It does not explicitly name alternative tools or when not to use it, but the usage context is strong.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
invite_memberInvite a teammateAInspect
Invite someone to this brand workspace by email (role: member = read-only on billing, admin = full). This SENDS a real email invite / share link — an account change. Confirm the exact email + role with the user, then call with confirm:true.
| Name | Required | Description | Default |
|---|---|---|---|
| role | No | default member | |
| Yes | the invitee’s email | ||
| confirm | No | REQUIRED true — this invites a real person |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations indicate it is not read-only and not idempotent, but the description adds critical behavioral detail: it SENDS a real email invite/share link and is an account change. It also mandates confirm:true, which is not in annotations. This goes beyond the structured metadata and is highly relevant for an agent to understand the real-world impact.
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 concise sentences, front-loaded with the core action, and the critical warning about confirming with the user and needing confirm:true. No wasted words; every sentence 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 an invitation tool that sends a real email, the description covers the essential behavioral and usage constraints. It doesn't describe the return format, but that is not critical for calling the tool correctly. The role meanings and confirmation requirement are the key details, and they are present.
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%, but the description adds meaning beyond the schema for role (explains permissions) and for confirm (emphasizes it's required to actually send). This is valuable clarification that the schema's brief descriptions do not provide.
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 the verb (invite), the resource (someone to this brand workspace), and the method (by email). It also explains the role semantics (member read-only on billing, admin full), which distinguishes it from other team management tools like remove_member or set_role. The purpose is 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?
It provides clear context: use to invite someone by email, and it warns to confirm the exact email and role with the user and call with confirm:true. It doesn't explicitly state when not to use or name alternatives, but the guidance is actionable and sufficient for correct invocation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
leave_connectorRemove my own account from a shared connectionADestructiveIdempotentInspect
On a connector that several teammates can contribute their OWN account to (see list_connectors — the row reports multiContributor), remove YOURS from this brand: your stored credential is dropped and the accounts you shared stop being shared. Your teammates' accounts on the same connection keep working, and nothing changes at the provider — reconnecting in a browser shares again. Use this instead of disconnect_connector when the connection is not yours to remove: disconnect_connector revokes the grant at the provider and only the person who created the connection may call it.
| Name | Required | Description | Default |
|---|---|---|---|
| provider | Yes | provider id exactly as list_connectors reports it, e.g. "linkedin", "tiktok_ads", "meta" |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond annotations (destructive, idempotent, non-read-only), the description discloses that only your contribution is removed, teammates' accounts remain functional, and nothing changes at the provider. It also notes that reconnecting shares again, adding context about reversibility and scope.
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 longer than necessary but every clause adds value: explanation of the multiContributor context, precise side effects, and the alternative. It is front-loaded with the core action. Slight verbosity prevents a 5, but no redundancy exists.
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, shared-connection mutation, the description covers what happens, who is affected, and when to use it, plus directs to list_connectors for verification. No output schema exists but none is needed; the agent has everything 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 100%, and the schema description already explains the provider parameter with examples. The tool description does not add extra meaning about the parameter beyond the schema; it references 'this brand' but doesn't clarify the mapping further. 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?
The description clearly states 'remove YOURS from this brand' with specifics: drops stored credential, stops sharing your accounts. It distinguishes from disconnect_connector by naming it as the alternative for connections you own, so an agent can differentiate 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?
Explicitly says 'Use this instead of disconnect_connector when the connection is not yours to remove' and explains why disconnect_connector is different (revokes at provider, only creator can call). This gives clear when and when-not guidance with a named alternative.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_brandsList brandsARead-onlyInspect
List every brand on this account (id + name) and which one this connection currently acts on, PLUS any brand another account shared with you (a team workspace). Multi-brand accounts: call this, then use_brand to switch. A SHARED workspace is switched into the SAME way — pass its name or the profile id printed here to use_brand. If a brand looks empty (no connected accounts, no Library) when the app shows it full, you are almost certainly acting on a different workspace: call this first. Read-only, free.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, so the description doesn't need to repeat that. It adds valuable behavioral context: it lists current active brand, shared brands, and warns about a common misreading of empty brands. It also notes 'free' (cost trait). This exceeds the baseline but isn't exhaustive about return format or error handling.
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 a single, well-structured paragraph that front-loads the core purpose, then usage guidance, then troubleshooting. Every sentence earns its place—no fluff. Capitalization of 'PLUS' and 'SAME' adds emphasis without excess. It is concise despite covering multiple scenarios.
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 there is no output schema, the description adequately explains what the tool returns (id+name, active brand, shared brands) and how to use it with use_brand. It includes a troubleshooting tip that addresses a common misinterpretation. For a zero-parameter list tool, this is complete; 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?
The tool has zero parameters, so the baseline is 4. The description compensates by indicating what the output contains (id, name, active brand, shared brands), which is helpful even though there is no input schema to document. Since there are no params to explain, this 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 clearly states it lists every brand on the account with id and name, the currently active brand, and shared team workspaces. It explicitly differentiates from the sibling use_brand by instructing to call this first, and mentions troubleshooting for misinterpreted empty brands. The verb+resource is specific and 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?
It gives explicit when-to-use guidance: 'Multi-brand accounts: call this, then use_brand to switch' and 'If a brand looks empty... call this first.' This tells the agent exactly when this tool is appropriate versus alternatives, and even explains how shared workspaces are handled. No ambiguity remains.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_business_locationsList Google business listingsARead-onlyInspect
List the Google Business Profile listings SHARED WITH THIS BRAND — id, title, address, website and Maps link. These are the only listings anything here can post to or read: one Google login often manages several businesses (an agency manages its clients’), and the user ticks which of them belong to this brand. Call this before posting whenever more than one is shared and let the USER pick: a Post on the wrong storefront is a public mistake Hermoso will not make for them. If nothing is shared, ask the user to choose — list_connector_accounts("google_business") then set_connector_accounts — and never name or guess a listing. Read-only, 0 credits. Needs Google Business Profile connected (Settings ▸ Connectors ▸ Google Business Profile).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, but the description adds substantial behavioral context: the read-only nature is confirmed, and it discloses that the operation costs 0 credits, that a Google Business Profile connection is required, and that only shared listings are visible. It also explains the multi-business scenario (agencies) which is a behavioral caveat not inferable from annotations alone.
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 dense but well-organized: it opens with the core function and output, then explains when to call it with a concrete fallback, then safety considerations, then credit cost and connection requirement. Every sentence adds value, and the length is justified by the richness of guidance. It is front-loaded and efficient.
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 no output schema, the description explicitly lists the return fields (id, title, address, website, Maps link). It covers connection prerequisites, credit cost, usage triggers, fallback steps, and the critical safety behavior of letting the user pick. Nothing an agent needs to call this 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?
The tool has zero parameters, so the baseline for parameter semantics is 4 (no params to document). The description doesn't need to add parameter info; it already covers the relevant context. No gap exists.
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 verb (list), a precise resource (Google Business Profile listings shared with this brand), and enumerates the returned fields (id, title, address, website, Maps link). It clearly distinguishes from siblings like get_business_location (single) and list_google_business_posts (posts) by emphasizing the filtering scope.
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?
Provides explicit when-to-use guidance: call before posting when more than one listing is shared, and let the user pick. It also gives a fallback procedure for no-shared-listings (list_connector_accounts then set_connector_accounts) and explicitly warns against guessing a listing. This is exemplary usage instruction with clear alternatives and exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_connector_accountsList a connector’s accountsARead-onlyInspect
Show every identity a connected account can act as, and which ones this BRAND is currently allowed to use — Facebook Pages + Instagram + Meta ad accounts, Google Ads customers, LinkedIn company Pages (and the personal profile), Pinterest ad accounts, Microsoft Advertising accounts. One person often administers several; only the ticked ones can be posted to or spent from. Call this before set_connector_accounts, and let the USER pick — never guess. Providers: tiktok, x, youtube, threads, bluesky, telegram, reddit, pinterest, instagram, meta, google_ads, linkedin, pinterest_ads, linkedin_ads, reddit_ads, apple_ads, microsoft_ads, google_business, google_analytics, snapchat_ads, x_ads, tiktok_ads, google_tag_manager, google_search_console, bing_webmaster. Read-only, free.
| Name | Required | Description | Default |
|---|---|---|---|
| provider | Yes | which connector’s accounts to list |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint and destructiveHint, but the description adds meaningful behavioral context: it explains the distinction between identities the brand can use versus those that are merely available, and warns that only 'ticked' accounts can be posted to or spent from. It also adds the pricing signal 'free,' which is beyond annotation. Minor redundancy with annotations keeps this 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?
The description is front-loaded with purpose and usage, but the provider list repeats the schema enum verbatim and 'Read-only, free' duplicates annotation info. These parts could be trimmed without loss. Still, every non-redundant sentence serves a clear purpose, so it is not bloated enough for a lower score.
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 only one parameter, no output schema, and annotations covering safety, the description provides nearly everything an agent needs: what the tool returns (identities and allowed flags), why it matters, and how to use it with set_connector_accounts. It could mention expected output structure or pagination, but those are less critical given the tool's straightforward nature.
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 an enum and description, so the baseline is 3. The description adds value by mapping provider values to specific account types (e.g., Google Ads customers, LinkedIn company Pages), which helps the agent understand what 'accounts' means for each provider. The long provider list duplicates the enum but still reinforces the semantic scope.
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 opens with a specific verb and resource: 'Show every identity a connected account can act as, and which ones this BRAND is currently allowed to use.' It names concrete account types (Facebook Pages, Instagram, Meta ad accounts, etc.), making the tool's purpose unmistakable. It also implicitly differentiates from the sibling set_connector_accounts by saying 'Call this before set_connector_accounts.'
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 explicitly states when to use this tool: 'Call this before set_connector_accounts, and let the USER pick — never guess.' This gives a clear sequencing rule and behavioral instruction for the agent. It also indicates the tool is read-only and free, helping the agent decide when it is safe to invoke.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_connectorsList connectorsARead-onlyInspect
List the third-party accounts connected to this workspace (Meta, Google Ads, Google Drive/Sheets/Docs, YouTube, LinkedIn, OneDrive, Slack, …) — provider, status and the connected account label — PLUS which providers are available to connect. IT ALSO FLAGS A CONNECTION WHOSE PERMISSIONS ARE OUT OF DATE: a provider writes its granted permission set into the token at consent time, so a connection authorized before a permission was approved does not carry it and never will — those calls are refused by the provider and no retry or wait can change it. Check this FIRST when a connected provider starts refusing things. The fix is a browser: the user reconnects under Workspace ▸ Connectors. Read-only, free.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, and the description explicitly says 'Read-only, free,' aligning with and reinforcing that. Beyond annotations, it discloses a subtle behavioral trait: connections with out-of-date permissions are flagged, explaining why retries or waits cannot help and directing the user to the reconnect path. This adds substantial context not encoded in structured fields.
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 longer than typical, but every sentence serves a purpose: it enumerates the output, explains the permission flag, gives a diagnostic trigger, and indicates the remediation path. The core purpose is front-loaded, and the extra detail is directly useful, not filler. It could be trimmed slightly, but it earns its length.
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 listing tool with no parameters and no output schema, the description is highly complete. It tells the agent exactly what the output includes (provider, status, label, available providers), what the special flag means, when to call it, and how to fix the underlying issue. Nothing essential is missing 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 input schema is empty (0 parameters), so the baseline is 4. The description correctly spends no space on parameters and instead focuses on output and behavior, which is appropriate for a zero-parameter 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?
The description clearly states the exact action (list connected third-party accounts) and the specific resources included (Meta, Google Ads, Google Drive/Sheets/Docs, YouTube, LinkedIn, OneDrive, Slack, etc.), along with the returned fields (provider, status, label) and the additional capability (available providers). It is specific enough to distinguish from sibling tools like list_connector_accounts, even without an explicit comparison.
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 a concrete usage trigger: 'Check this FIRST when a connected provider starts refusing things.' It also explains the underlying cause (permission set baked into the token at consent time) and the fix (reconnect in the browser). It does not explicitly name alternatives or when not to use it, but the scenario is clear and actionable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_creatorsList saved creatorsARead-onlyInspect
List this workspace’s SAVED CREATORS — the reusable on-camera cast (AI creators made here, a person pulled from a social profile, a consented photo upload). Read-only, FREE. Each entry gives the name, the PORTRAIT URL, where the portrait came from and whether a real person’s likeness consent is on file, how many extra pose plates exist, and any chosen or cloned voice. TO PUT ONE IN A FINISHED AD, pass their id or name as render_ad’s creator — that casts them for the whole spot (and skips the character-portrait render, so it costs less than not casting anyone). THE PORTRAIT URL IS THE REUSE HANDLE for the raw lanes — pass it as generate_avatar’s image (a talking clip of them), generate_video’s refImage (they star in the scene), recast_motion’s image (they perform a reference clip’s motion), or generate_image’s refImages. CALL THIS BEFORE OFFERING TO GENERATE A NEW PERSON: re-casting somebody the workspace already has keeps the SAME face across every ad, while a fresh person costs credits and breaks that continuity. An empty answer means the workspace genuinely has no cast yet — say so and offer generate_avatar / save_creator, never invent a roster.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | max creators to return (default 24) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond annotations (readOnlyHint=true, destructiveHint=false), the description adds behavioral context: it's 'FREE', explains the return fields (name, portrait URL, consent status, pose plates, voice), and notes empty-result behavior. It also reveals cost implications of casting vs. not casting. The description fully overloads the annotation safety profile with practical details.
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 long but every sentence earns its place: it front-loads the purpose, then packs essential routing and cost information in a logical flow. There's no filler or redundancy; each clause serves a distinct decision an agent must make.
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 compensates by detailing the exact fields returned. It also covers edge cases (empty roster), downstream usage across sibling tools, and cost/continuity rationales. For a simple list tool with one optional param, this is comprehensive beyond expectations.
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 only parameter (limit) is already fully documented in the schema with 100% coverage; the description adds nothing extra about it. Since the schema is self-sufficient, the baseline of 3 is appropriate—the description doesn't need to repeat what's structured.
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 explicitly states the action (list) and resource (saved creators in the workspace), and defines what a 'creator' is (AI creators, social pulls, consented photos). It clearly distinguishes itself from siblings by naming downstream tools (render_ad, generate_avatar, etc.) and the alternative save_creator. The scope and purpose 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 gives explicit when-to-use guidance: 'CALL THIS BEFORE OFFERING TO GENERATE A NEW PERSON' and explains the trade-off (continuity vs. cost). It also names alternatives for the empty case (generate_avatar / save_creator) and instructs not to invent a roster. This is direct, actionable routing advice.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_drive_filesList Google Drive filesARead-onlyInspect
List the Google Drive files & folders Hermoso can reach — the ones it created, plus any the user handed over with the Google file picker in the app (the drive.file scope exposes nothing else, never their entire Drive). This is how you find the id of a file the user picked. Filter by query (name contains …), folderId (contents of a folder), or onlyFolders:true. Paginate with pageToken. Read-only.
| Name | Required | Description | Default |
|---|---|---|---|
| query | No | only files whose name contains this | |
| folderId | No | list the contents of this folder id | |
| pageSize | No | rows per page (1–200, default 50) | |
| pageToken | No | cursor from a previous call | |
| onlyFolders | No | list folders only | |
| includeTrashed | No | include trashed files (default false) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, and the description reinforces this with 'Read-only.' It adds valuable context beyond annotations by explaining the scope limitation (drive.file scope only exposes created files and user-picked files, never the entire Drive). This sets clear expectations about what data is accessible, which is not visible from annotations alone. No contradiction.
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 concise and well-structured, starting with the primary purpose, then scope, then usage details. Each sentence earns its place: scope clarification, use case, filter options, pagination, and read-only note. No fluff or redundancy.
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 listing tool with no output schema, the description covers essential aspects: scope, filters, pagination, and read-only nature. It hints at return contents (file ids) but does not describe the response format. Given the annotations and simplicity of the tool, this is fairly complete, though a short note on return shape would make it more 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 100%, so all six parameters are documented in the schema. The description mentions query, folderId, onlyFolders, and pageToken but essentially restates the schema descriptions ('filter by query', 'contents of a folder'). It does not add new semantics, examples, or edge-case behavior beyond what the schema already says. Baseline of 3 applies because the schema carries the load.
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 the tool lists Google Drive files and folders that Hermoso can access, specifying the scope (created files plus user-picked ones) and explicitly distinguishes from the full Drive. It also says this is how to find the id of a user-picked file, giving a concrete use case. This is specific and differentiates from sibling tools like get_drive_file or save_to_drive.
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 clear context on when to use the tool (finding file ids, filtering by name/folder/type, paginating) and implies it is for listing rather than other operations. It does not explicitly name alternative tools or state when not to use it, but the purpose is obvious. The mention of pagination and filters gives practical guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_errorsList errors users hitARead-onlyInspect
The errors actually recorded against this workspace, GROUPED by fingerprint — the same failure at the same call site is one row with a hit count and first/last seen, sorted defects-first. Each row says whose side it is: ours (a defect worth fixing), user (a refusal we deliberately authored, e.g. not-connected or out-of-credits), or unknown (a vendor 4xx we cannot attribute — never guessed). Free text, tokens, emails and creative are redacted before anything is stored, so an input echo shows shapes and lengths, not content. Filter by surface (http/mcp/agent/job/client) or kind. Read-only, 0 credits. Scoped to your own workspace; an operator whose client carries the admin key sees every account.
| Name | Required | Description | Default |
|---|---|---|---|
| kind | No | 'ours' = a defect; 'user' = a refusal we authored; 'unknown' = we could not tell | |
| limit | No | how many groups to return (default 50, max 200) | |
| since | No | ISO timestamp — only groups last seen at or after this | |
| surface | No | where it happened: http (an API route), mcp (an agent tool), agent (the in-app Studio agent), job (an async render/publish), client (a browser crash) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate read-only and non-destructive, and the description reinforces this with 'Read-only, 0 credits'. It also discloses critical behaviors beyond the annotations: redaction of free text/tokens/emails/creative, grouping by fingerprint with side classification, sorting defects-first, and the workspace scoping with an admin-key exception. These details materially inform the agent's expectations about data safety, output shape, and access boundaries.
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 composed of several dense sentences, each adding a distinct fact (grouping, side classification, redaction, scoping, filters, credits). It is longer than the bare minimum, but every sentence contributes actionable information and the most defining trait (grouping) is front-loaded. It is structured well but could be tightened without losing meaning.
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 that there is no output schema, the description thoroughly explains what the returned rows represent (grouped, with hit count, first/last seen, side, redaction behavior) and how to filter. It also covers access scoping and the read-only nature. An agent has everything needed to call it correctly and interpret the response, making it complete for a list-diagnostics tool.
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 input schema covers 100% of the parameters with per-parameter descriptions (kind, limit, since, surface). The tool description mostly references the filter values ('surface', 'kind') without adding new semantics beyond the schema. Since the schema already does the heavy lifting, a baseline of 3 is appropriate; the description does not deepen parameter understanding further.
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 verb ('list'), a precise resource ('errors recorded against this workspace'), and clarifies the grouping by fingerprint with hit counts and side classification. It distinguishes itself from the many publishing/social tools and even from the sibling 'error_detail' by its aggregate, grouped nature.
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 conveys that this is a read-only, zero-credit diagnostic tool scoped to the workspace, which implies when it might be used. However, it does not explicitly contrast it with alternatives like 'error_detail' or state when not to use it. The usage context is present but not framed as a when/when-not decision, leaving the selection to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_hooksThe hook + setting libraries, and which hooks are workingARead-onlyInspect
The curated menu of VISUAL scroll-stop HOOKS (how an ad opens) and SETTINGS (where it is staged) that plan_ad and render_ad accept, PLUS this brand's measured traction per hook. Call it before planning an ad to pick a hook deliberately instead of letting the model improvise one, and call it after publishing to see which ones are actually landing. Three things it will not do: it never recommends a hook from thin data — a verdict is SUPPRESSED below 5 measured posts and the reason is stated; it never compares across channels; and it reports hooks you have NEVER TRIED as a fact, not as advice, because 'you haven't tried this' is an observation and 'you should' would be a verdict drawn from zero data. A hook marked unusable in this brief says WHY (an on-screen-text hook cannot ride an authentic/UGC render, which carries zero on-screen text). Read-only, 0 credits.
| Name | Required | Description | Default |
|---|---|---|---|
| tier | No | product tier, used with category — changes the FINISH of the room, never the room. Default premium. | |
| channel | No | restrict the performance half to one channel (facebook, instagram, threads, x, linkedin, youtube, tiktok, reddit, pinterest) | |
| category | No | the product category (e.g. 'skincare serum', 'protein powder', 'sunglasses') — returns the setting our Location x Tier matrix puts that category in, with the reason | |
| authentic | No | true if the planned ad is an authentic/UGC/creator-register render — on-screen-text hooks are then reported unusable, with the reason |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes beyond the readOnlyHint annotation by explaining dynamic behavior: verdict suppression below 5 measured posts with reason, no cross-channel comparison, and treatment of never-tried hooks as observation not advice. It also explains why hooks are marked unusable (on-screen-text hooks incompatible with authentic renders). These are valuable behavioral details not conveyed by annotations alone.
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 a single long paragraph but is dense and front-loaded with the core purpose. Each sentence adds meaningful content (what it returns, when to call it, limitations, behavior). It could be broken into more readable bullets, but it is not wastefully verbose relative to the complexity it explains.
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 lookup tool with 4 optional parameters and no output schema, the description fully covers what an agent needs: what it returns (menu, settings, traction), how the verdicts are gated, which params affect what, and its place in the ad-planning workflow. 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?
Schema descriptions cover all 4 parameters, so baseline is 3. The prose adds context: tier changes the 'FINISH of the room' and authentic flag makes on-screen-text hooks 'unusable with the reason.' This clarifies the interaction between parameters and the tool's output, going beyond the schema. Slight deduction for not elaborating the category parameter more explicitly, but it's adequately covered.
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 precise purpose: a curated menu of visual scroll-stop hooks and settings, with measured traction, that plan_ad and render_ad accept. It names the consumers and differentiates itself from other tools by being a deliberate selection aid rather than an improvisation tool. It is clear what the tool does and its scope 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?
The description explicitly states when to call it: 'before planning an ad' and 'after publishing,' giving concrete usage timing. It also lists three things it will not do (no recommendation from thin data, no cross-channel comparison, never-tried hooks reported as fact not advice), which effectively tells the agent what not to expect and when to avoid using it. This is excellent guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_jobsList render jobsARead-onlyInspect
List the most recent render jobs + how many are currently running, so you can report on or resume in-flight work.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is covered. The description adds that it returns recent jobs and a running count, which is helpful context, but does not disclose other behavioral aspects like pagination limits or ordering details. With annotations covering the main traits, this adds some value but not extensive disclosure.
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 a single, front-loaded sentence that states the main action first, then the additional information, and ends with the intended purpose. It is concise, efficient, and free of any filler. Every word contributes to meaning.
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 list tool with no parameters, no output schema, and annotations covering safety, the description is complete. It clearly states what the tool returns (recent jobs and running count) and the purpose. It doesn't need to explain the data format since the title and name make the resource type clear. A 4 is appropriate as it covers the essentials.
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, and the schema is empty with 100% coverage. Per the rubric, the baseline is 4. The description does not need to explain parameters, and adds nothing beyond that baseline.
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 verb ('List') and resource ('render jobs'), and adds the distinct capability of reporting how many are currently running. This clearly distinguishes it from the sibling get_job (singular) and other job-related tools like list_youtube_report_jobs. An agent can infer exactly what to expect.
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 use case ('so you can report on or resume in-flight work') which implies when to use it. However, it does not explicitly contrast with alternatives like get_job for a specific job's details, nor does it state when not to use this tool. The guidance is implied rather than explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_libraryList libraryARead-onlyIdempotentInspect
Browse this workspace's Library — every image/video generated in the Studio, newest first (the same Library the web app shows). Returns served URLs you can open directly or hand to fetch_asset for a download link, plus each asset's kind, model, and age. Free, read-only.
| Name | Required | Description | Default |
|---|---|---|---|
| kind | No | filter by asset kind (default 'all') | |
| limit | No | max assets to return (default 20, max 60) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses key behaviors: it returns assets with kind, model, age, and served URLs, and orders them newest first. It also states it is 'Free, read-only', which aligns with and reinforces the annotations (readOnlyHint, idempotentHint, destructiveHint). It adds value beyond annotations by describing the output content and ordering.
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 a single, efficient sentence that front-loads the purpose and includes all essential details without redundancy. Every clause earns its place, covering scope, ordering, return fields, and a pointer to a related 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 simple listing tool, the description is complete: it explains what is listed, the ordering, what is returned, and how to use the results (open URLs or pass to fetch_asset). Since annotations already cover safety and schema covers parameters, nothing an agent needs 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?
The input schema already provides complete descriptions for both parameters (kind with enum and default, limit with default and max). The description does not add new information about the parameters, but given 100% schema coverage, the baseline of 3 is appropriate. It does not need to compensate for any gaps.
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 the tool's function: browse the workspace's Library and list image/video assets generated in the Studio, newest first. It is specific about what is returned (URLs, kind, model, age) and distinguishes itself from related tools like fetch_asset by noting it returns served URLs rather than download links.
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 clear context on when to use this tool (browsing the Library) and explicitly mentions fetch_asset as the alternative for obtaining download links, which guides the agent on differentiation. It does not explicitly state when not to use it, but the alternative mention and 'read-only' note offer sufficient guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_linkedin_lead_eventsLinkedIn lead events received in real timeARead-onlyIdempotentInspect
The lead events LinkedIn has PUSHED to Hermoso for this brand (new lead / deleted lead, with the form and the lead id), newest first. Empty means none have arrived, not that none exist — list_linkedin_leads reads every lead regardless, and subscribe_linkedin_leads is what starts delivery. Read a lead’s answers with get_linkedin_lead. Read-only, free.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, and the description adds meaningful behavioral nuance: events are pushed, ordered newest first, and empty means no events have arrived rather than no leads exist. The read-only claim is consistent with 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?
Three concise, front-loaded sentences cover the core purpose, the empty-result semantics, and the relevant sibling tools. Every sentence adds information without redundancy or 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?
The description covers purpose, ordering, empty semantics, and related tools, and annotations cover safety and idempotency. However, it does not explain the 'limit' parameter or describe the exact event payload structure, which is a minor gap given 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 description coverage is 0%, so the description must compensate for parameter meaning, but it never mentions the 'limit' parameter or how it affects results. The single parameter is left entirely to the schema's bare name and type.
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 verb and resource: it lists lead events that LinkedIn pushed to Hermoso for the brand, including new/deleted leads with form and lead ID, newest first. It clearly distinguishes itself from related tools like list_linkedin_leads, subscribe_linkedin_leads, and get_linkedin_lead.
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 explicit context for when this tool is appropriate: it reads pushed events only, and it clarifies that empty results mean no events arrived, not that no leads exist. It also names alternatives for related needs: list_linkedin_leads for all leads, subscribe_linkedin_leads to start delivery, and get_linkedin_lead to read answers.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_linkedin_lead_formsList LinkedIn lead gen formsARead-onlyIdempotentInspect
The LEAD GEN FORMS a LinkedIn company Page or ad account owns — id, name, state, version and the fields each one asks for (firstName, email, company …). Forms are created in Campaign Manager or on the Page; this API reads them and cannot create one. If it answers that the connection must be reconnected, say exactly that: the lead-sync permission is granted at authorise time. Read-only, free.
| Name | Required | Description | Default |
|---|---|---|---|
| pageId | No | the company Page that owns the form — from list_linkedin_pages; omit when one Page is shared | |
| adAccountId | No | read forms owned by an AD ACCOUNT instead of a Page |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare readOnlyHint, idempotentHint, and destructiveHint false, so the safety profile is known. The description adds meaningful behavioral context beyond that: the lead-sync permission is granted at authorization time, a specific reconnection error requires an exact user-facing response, and the operation is free. No contradiction with annotations exists.
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 resource and return fields, and each subsequent sentence adds context: creation source, read-only nature, error handling, and cost. It is slightly dense and repeats the read-only point in more than one place, but it remains under ~65 words and earns its length.
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 appropriately compensates by naming the return fields (id, name, state, version, form fields). It also covers ownership scope, how forms come to exist, authentication permission timing, and read-only/free behavior. For a list-style tool with two optional parameters, this is complete enough for an agent to invoke 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 description coverage is 100%, so both pageId and adAccountId are already well explained in the schema. The description's mention of 'Page or ad account' aligns with the parameters but does not add meaning beyond what the input schema already provides. 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 clearly identifies the verb and resource: it lists LinkedIn lead gen forms owned by a Page or ad account, and it enumerates what is returned (id, name, state, version, requested fields). It also distinguishes itself from creation by stating this API only reads and cannot create a form, which separates it from related lead-related sibling 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?
The description gives a clear context for use: retrieving lead gen form definitions owned by a Page or ad account, and it explicitly notes that forms are created elsewhere (Campaign Manager or the Page), so this tool is not for creation. It lacks an explicit 'for actual leads, use list_linkedin_leads' style exclusion, but the context is strong enough for an agent to route correctly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_linkedin_leadsList LinkedIn leads (form responses)ARead-onlyIdempotentInspect
The LEADS a LinkedIn lead gen form collected — every response with its answers keyed by field (firstName, lastName, email, company, …), the campaign and creative that produced it, the consents ticked, and whether it was a test lead. Newest first. Filter by formId, a since/until window (ISO date or epoch ms — LinkedIn takes epoch), or testLeadsOnly. THIS IS PERSONAL DATA: show it to the user, hand it to the CRM they name, never repeat it into a post or an unrelated tool. Pass start for the next page. Read-only, free.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | per page, max 100 | |
| since | No | ISO date or epoch milliseconds | |
| start | No | offset for the next page | |
| until | No | ||
| formId | No | only this form (from list_linkedin_lead_forms) | |
| pageId | No | the company Page that owns the form — from list_linkedin_pages; omit when one Page is shared | |
| leadType | No | defaults by owner: SPONSORED for an ad account, COMPANY (organic Page form) for a Page; EVENT for event forms. LinkedIn refuses SPONSORED on a Page owner | |
| adAccountId | No | read forms owned by an AD ACCOUNT instead of a Page | |
| formVersion | No | default 1 | |
| testLeadsOnly | No | true returns ONLY test submissions |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark readOnlyHint=true and destructiveHint=false, which the description's 'Read-only' reinforces consistently. The description adds genuinely new behavioral context: a personal-data handling directive ('never repeat it into a post or an unrelated tool'), output shape, newest-first ordering, and the LinkedIn-epoch nuance for date filters.
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?
Single dense paragraph that front-loads the purpose before filtering details. The personal-data warning earns its capitalization, and the read-only/free note is a one-word add. Slightly long, but with 10 parameters and no output schema, every clause carries weight.
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 optional parameters and no output schema, the description compensates well: it enumerates return contents (answers, campaign/creative, consents, test flag), ordering, filters, pagination, and data-handling constraints. The schema handles parameter documentation at 90% coverage. Minor gap: no pointer to get_linkedin_lead for single-lead lookups.
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 90%, so the baseline is 3. The description adds value on top: it flags that LinkedIn actually consumes epoch ms for since/until, explains that formId scopes to a specific form, and identifies start as the pagination parameter. Some params (leadType, adAccountId, pageId, formVersion) are left to the schema, which already documents them.
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: 'The LEADS a LinkedIn lead gen form collected.' It enumerates what each response contains (answers keyed by field, campaign/creative, consents, test-lead flag), which distinguishes it from siblings like list_linkedin_lead_forms (forms, not responses) and get_linkedin_lead (single lead). Ordering ('Newest first') adds further precision.
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?
Provides clear context for when to use it: retrieving responses from a LinkedIn lead gen form, with concrete filter scenarios (formId, since/until, testLeadsOnly) and a pagination instruction ('Pass start for the next page'). It does not explicitly name alternatives or state when not to use it, so it falls 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.
list_linkedin_lead_subscriptionsList LinkedIn lead webhooksARead-onlyIdempotentInspect
The lead notification webhooks registered on a LinkedIn Page or ad account, with the id delete_linkedin_lead_subscription takes. Read-only, free.
| Name | Required | Description | Default |
|---|---|---|---|
| pageId | No | the company Page that owns the form — from list_linkedin_pages; omit when one Page is shared | |
| leadType | No | ||
| adAccountId | No | read forms owned by an AD ACCOUNT instead of a Page |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, openWorldHint, idempotentHint, and destructiveHint false, so the safety profile is covered. The description adds value beyond annotations by stating the call is free and that the returned data contains the id that delete_linkedin_lead_subscription consumes. It does not mention pagination or auth details, but these are less critical given 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 description is compact: one sentence plus the 'Read-only, free' tag, with no filler. The clause 'with the id delete_linkedin_lead_subscription takes' is grammatically awkward, but the resource is front-loaded and the whole definition is appropriately sized for a simple list operation.
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 list tool with no required parameters and no output schema, the description tells the agent what is listed, the Page/ad-account scope options, that it is read-only and free, and that results contain the id needed for deletion. It omits leadType semantics and pagination, but openWorldHint and the absence of required parameters reduce the risk of incorrect 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 schema documents pageId and adAccountId, and the description reinforces the Page-versus-ad-account axis with 'registered on a LinkedIn Page or ad account.' However, it adds no guidance for the undocumented leadType parameter, leaving 33% of parameters without semantic coverage. The description is helpful but largely redundant with the schema's existing parameter notes.
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 precisely identifies the resource as lead notification webhooks registered on a LinkedIn Page or ad account, clearly distinguishing it from sibling tools like list_linkedin_lead_forms, list_linkedin_leads, and list_linkedin_lead_events. It also notes the returned id feeds delete_linkedin_lead_subscription, reinforcing what the tool returns. The grammar is slightly awkward, but the purpose is unmistakable.
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 makes clear this is for inspecting existing webhook registrations on either a Page or ad account, and the reference to delete_linkedin_lead_subscription signals it as the lookup step before deletion. It does not explicitly contrast with subscribe_linkedin_leads or list_linkedin_lead_events, but the registered-webhooks framing provides clear context without exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_linkedin_pagesList the LinkedIn company Pages this account administersARead-onlyInspect
List the LinkedIn COMPANY PAGES the connected account administers — id, name and the role held on each. ALWAYS call this before post_to_linkedin_page when there is more than one Page: publishing to the wrong company Page is a public mistake and Hermoso never chooses for the user. If it comes back empty, the account holds no Page admin role, or LinkedIn has not granted this app the organization scopes — say that plainly rather than guessing an id. Read-only, free.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint annotation, the description adds rich behavioral context: it details the return fields (id, name, role), the empty-case interpretation, and the policy that Hermoso never chooses the page for the user. It also notes the 'free' nature and the possibility of missing organization scopes, which is not covered by 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 description is concise and efficient: the primary purpose is front-loaded, followed by a critical usage directive and empty-case handling, with no redundant sentences. Every sentence adds value.
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, parameterless read-only list tool, the description is fully complete. It covers the return shape, when to call it, what an empty result means, and how to respond. No output schema exists, but the described return fields suffice.
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 parameters, so the description correctly provides no parameter-level detail. Baseline 4 applies since the schema is empty and the description does not need to compensate for undocumented params.
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 the verb 'List', the resource 'LinkedIn COMPANY PAGES', and the specific output (id, name, role). It explicitly differentiates from the sibling post_to_linkedin_page by mandating this call before publishing when multiple pages exist, making the purpose 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?
It gives explicit when-to-use instructions ('ALWAYS call this before post_to_linkedin_page when there is more than one Page'), explains the empty-return meaning (no admin role or missing scopes), and advises against guessing IDs. This fully routes the agent to the correct behavior.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_memoryList memoryARead-onlyInspect
List the durable facts & preferences saved in this workspace’s Memory (what the studio remembers about the brand, audience, taste, and do/don’t rules) — the same Memory the web app shows. These shape every future ad. Read-only, free.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | max items (default 50, max 200) | |
| category | No | filter to one bucket (Brand/Audience/Taste/Do/Don’t/Preference) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false. The description adds value by explaining memory is 'durable' and 'shape every future ad', which provides behavioral context beyond the safety profile. It also explicitly states 'Read-only, free', consistent with annotations. No contradiction, and it adds useful context about the tool's impact.
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 with zero waste. The core purpose is front-loaded, then the definition of memory, its significance, and the read-only/free notes. Every clause 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 listing tool with no output schema and two optional parameters, the description adequately explains what memory is and that the tool lists it. It doesn't describe the return format, but that's not required without an output schema. The schema covers parameter details. It's complete enough for an agent to call 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 description coverage is 100%, so the schema already documents both parameters (limit with default/max, category with allowed values). The description adds no additional meaning about parameters; it doesn't reference them. Baseline of 3 is appropriate given full 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 clearly states the tool lists the workspace's Memory, a specific resource, and explains what that memory contains (brand, audience, taste, do/don't rules). This distinguishes it from other list tools like list_brands or list_playbooks, and from memory-related siblings like remember and forget.
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 this is for viewing memory in a read-only manner and notes it's 'free', but it does not explicitly state when to use this over alternatives like remember (save) or forget (delete). It provides good context about memory's role in future ads but lacks explicit when-not/alternative guidance. Since siblings are well-known, the purpose implies usage clearly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_meta_pagesList Meta pages & ad accountsARead-onlyInspect
List the Facebook Pages (with any linked Instagram business account) and ad accounts on the connected Meta account — use before post_to_meta / create_meta_campaign to pick the target. Requires the user to have connected Meta (Settings ▸ Connectors ▸ Meta); returns a connect hint if not.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false. The description adds that it returns a connect hint if the user hasn't connected Meta, which is useful behavioral context. It doesn't contradict annotations and provides additional info beyond what structured fields convey, though it doesn't detail other behaviors like 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 two sentences, front-loading the core action and scope, then adding usage context and a prerequisite. Every clause serves a purpose, with no redundancy or 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 simple listing tool with no parameters and no output schema, the description covers the essential context: what it returns (a list of pages/ad accounts), when to use it, and a prerequisite. Could mention return format or connection-failure behavior in more detail, but these are minor for this scope.
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, and the schema coverage is 100% with an empty object. The description adds nothing about parameters because there are none to explain. Baseline for 0 params is 4, and the description appropriately avoids extraneous detail.
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 the specific action ('List') and resource ('Facebook Pages with any linked Instagram business account and ad accounts') on the connected Meta account. It also provides context for its use, distinguishing it from posting tools by naming post_to_meta and create_meta_campaign. This is unambiguous and differentiates the tool from siblings.
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 instructs to use before post_to_meta/create_meta_campaign to pick the target, providing clear when-to-use context. It also notes the prerequisite of having Meta connected. However, it does not mention alternatives or when not to use this tool, so it falls short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_meta_postsList the Page’s / Instagram account’s own postsARead-onlyInspect
List the connected Facebook Page's or Instagram account's OWN existing posts — id, caption, permalink, publish date and format. THIS IS THE TOOL THAT GETS YOU THE postId every other Meta read needs: meta_post_insights, list_meta_comments and manage_meta_post all require one, and until now the only way to have a postId was to have just published it yourself with post_to_meta. Use it for "how did our last few posts do", to find a post the user describes loosely, or before backfill_posts. Pass target:'instagram' for the linked IG account (Stories are excluded — Meta's media edge does not return them); Facebook hides unpublished drafts unless you ask for them. Only ever reads a Page the brand has connected. Read-only, 0 credits.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | how many posts (default 25, max 100) | |
| cursor | No | paging cursor returned by a previous call | |
| pageId | No | which connected Page — omit when the brand has only one | |
| target | No | default facebook; 'instagram' reads the Page's linked IG business account | |
| account | No | which Instagram account — an @handle or id from list_connector_accounts("instagram"). Needed when several are linked, and the way an Instagram Login (standalone) account is reached; omit for the one Page-linked account. | |
| includeUnpublished | No | Facebook only — also return unpublished drafts (hidden by default) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint=true and destructiveHint=false annotations, the description adds valuable behavioral specifics: it is read-only and costs 0 credits, Instagram Stories are excluded, Facebook unpublished drafts are hidden unless explicitly requested, and it only reads a brand-connected Page. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense and front-loaded with purpose, followed by the critical postId role, use cases, platform caveats, and safety status. It is longer than average, but each sentence carries distinct information and there is minimal redundancy.
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 6 parameters, full schema coverage, no required fields, and no output schema, the description provides enough context to select and call the tool effectively. It lists return fields, use cases, platform caveats, and read-only/credit behavior. Minor gaps such as pagination details are covered by the schema.
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 the baseline is 3. The description adds meaningful semantics for target (Instagram reads the linked IG account, Stories excluded) and includeUnpublished (Facebook drafts hidden by default). It doesn't add much for limit, cursor, pageId, or account, but the schema already covers those.
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 uses a specific verb and resource: 'List the connected Facebook Page's or Instagram account's OWN existing posts', enumerates the returned fields (id, caption, permalink, publish date, format), and emphasizes this is the tool that provides the postId needed by other Meta read tools. This clearly differentiates it from siblings like post_to_meta, backfill_posts, and list_meta_pages.
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 concrete use cases: 'how did our last few posts do', finding a post the user describes loosely, and before backfill_posts. It also explains that it is the source of postId for other Meta reads, giving clear routing context. It doesn't explicitly list when not to use it, but the guidance is strong.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_onedrive_filesList OneDrive filesARead-onlyInspect
List files & folders in the user’s OneDrive — the root by default, a folder’s contents (folderId), or a name search (query). onlyFolders:true lists folders only. Paginate with pageToken (the cursor from a previous call). Read-only.
| Name | Required | Description | Default |
|---|---|---|---|
| query | No | search — only items whose name matches this | |
| folderId | No | list the contents of this folder id | |
| pageSize | No | rows per page (1–200, default 50) | |
| pageToken | No | cursor from a previous call | |
| onlyFolders | No | list folders only |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false. The description adds 'Read-only' and explains pagination and search semantics, which are beyond the annotations. It does not contradict annotations and provides useful behavioral context about how the tool operates.
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 three concise sentences with no redundant wording. It front-loads the primary purpose and then covers the key modes and pagination in a logical order. Every sentence 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 read-only listing tool, the description covers the necessary modes, pagination, and filtering. It lacks details on error handling or sorting, but these are not critical for a basic list operation. The sibling list_drive_files differentiates Google Drive, and the mention of 'OneDrive' clearly sets the scope.
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 the parameters are already documented. The description adds value by explaining how the parameters combine (e.g., root vs. folder vs. search, pageToken as cursor) and emphasizes the default behavior. This transcends mere schema repetition.
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 specifies the verb 'list' and the resource 'files & folders in the user's OneDrive', and enumerates three distinct modes (root, folder, search) plus a folders-only filter. This makes it easy to understand what the tool does and how it differs from generic 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?
Usage modes are clearly explained: 'root by default', 'folder’s contents (folderId)', 'name search (query)', and pagination with pageToken. It does not explicitly mention alternatives like get_onedrive_file or save_to_onedrive, but the self-contained guidance is sufficient for typical listing use cases.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_pinterest_boardsList Pinterest boardsARead-onlyInspect
List the boards on the user’s connected Pinterest account — id, name, privacy and pin count. ALWAYS call this before post_to_pinterest and let the USER pick: Pinterest requires a board and Hermoso never chooses one for them. Read-only, 0 credits. Needs Pinterest connected (Settings ▸ Connectors ▸ Pinterest).
| Name | Required | Description | Default |
|---|---|---|---|
| privacy | No | filter by board privacy; default is everything the connection can see |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint=true and openWorldHint=true, but the description adds valuable behavioral context beyond that: it explicitly says 'Read-only, 0 credits' (cost disclosure) and 'Needs Pinterest connected' with a settings path. It also explains the interaction pattern (must let user pick) which is behavioral. No contradiction; the description complements the annotations well.
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-loaded: it opens with the core function, then the critical workflow note, then cost and prerequisites. Every sentence carries useful information with no redundancy or fluff. It is structured logically from action → workflow → constraints.
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 low-complexity tool with one optional parameter and no output schema, the description covers everything essential: what it returns (fields), when to use it (before posting), prerequisites (connection), and cost (0 credits). It even flags a non-obvious requirement (user must pick). No significant information gap remains.
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% — the schema already documents the 'privacy' parameter with its enum and meaning. The tool description does not add any additional parameter semantics beyond what the schema provides. Since coverage is high, the baseline of 3 applies; no extra value is required.
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 'List the boards on the user’s connected Pinterest account' — a specific verb, resource, and scope. It enumerates the output fields (id, name, privacy, pin count), which differentiates it from sibling tools like create_pinterest_board or post_to_pinterest. The purpose is unambiguous and distinct.
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 explicit usage guidance: 'ALWAYS call this before post_to_pinterest and let the USER pick' — it specifies the prerequisite workflow and why (Pinterest requires a board, Hermoso never chooses). It also states the connection requirement (Settings ▸ Connectors ▸ Pinterest) and notes it's read-only with 0 credits. This is exactly the kind of when-to-use and why info an agent needs.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_playbooksList playbooksARead-onlyInspect
List the PLAYBOOKS saved in this workspace — the reusable strategy cards (winning hooks, angles, formats and the concrete plays to run) kept from teardowns, angle mining and creatives worth repeating. The same Playbooks the web app's Playbooks tab lists. Read one before planning an ad so you re-run what already worked instead of starting cold. Read-only, free.
| Name | Required | Description | Default |
|---|---|---|---|
| full | No | true to return every hook/angle/play in the text, not just the headline counts | |
| limit | No | max playbooks to return (default 25, max 100) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is covered. The description adds value by confirming 'Read-only, free' and noting it matches the web app's Playbooks tab, but doesn't disclose return format, pagination behavior, or default ordering. Given the annotations cover safety, a 3 is appropriate.
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 sentences with no waste. The first sentence front-loads the core functionality, the second ties it to a familiar surface (web app tab), the third gives usage guidance, and the fourth restates safety. Every sentence 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?
This is a simple list tool with 2 optional params, no output schema, no nested objects, and annotations covering the safety profile. The description covers what playbooks are, when to use it, and what the params do via schema. Nothing essential is missing for an agent 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?
Both parameters (full, limit) have schema descriptions with 100% coverage: 'full' explains it returns every hook/angle/play and 'limit' documents default and max. The description doesn't add parameter-specific details beyond the schema, so baseline 3 is correct.
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 precise verb+resource ('List the PLAYBOOKS saved in this workspace') and then defines what playbooks are (winning hooks, angles, formats, concrete plays) with operational context (kept from teardowns and angle mining). It is clearly distinct from sibling list_swipefile, which targets a different asset type.
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 usage context: 'Read one before planning an ad so you re-run what already worked instead of starting cold.' This tells an agent when to call it, though it doesn't explicitly name alternative tools to consider or state when NOT to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_product_photosList product photosARead-onlyInspect
List the product photos ALREADY saved in your workspace — the brand's product library plus any app-store screens (also surfaces photos locked in your OTHER creations, since a set product lands in the shared library). FREE — returns each photo's url + label. Call it before set_product_image to see the existing photos you can reuse. Reads YOUR saved brand (pass brandId to target a specific brand — that switches this key's active brand like use_brand).
| Name | Required | Description | Default |
|---|---|---|---|
| brandId | No | a brand id/name from list_brands whose product library to list; omit to use the active brand |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotation Contradiction: The description states that passing brandId 'switches this key's active brand like use_brand,' which is a side effect modifying the tool's active state. This contradicts the readOnlyHint=true annotation, which implies the tool does not modify any state. Thus the description directly contradicts the annotation.
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 concise and front-loaded, covering the main purpose, scope, cost, return value, and usage trigger in four sentences. Every sentence adds distinct value, with no redundancy, making it efficient for agents to parse.
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 tool with one optional parameter and no output schema, the description is complete: it states the return type (url + label), explicitly mentions cost (FREE), explains the scope, and addresses the side-effect of brand switching. Nothing critical is missing for an agent to invoke 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?
Although the schema already describes the brandId parameter with 100% coverage, the description adds important semantics beyond the schema: it explains that passing brandId also switches the active brand for the key, similar to use_brand. This additional behavioral detail is not present in the schema and helps agents understand the side effect.
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 the tool lists already-saved product photos, including the brand's product library and app-store screens, and notes it surfaces photos from other creations. It distinguishes itself from set_product_image by explicitly saying to call it before that tool, giving a specific verb and resource.
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?
Provides explicit guidance: 'Call it before set_product_image to see the existing photos you can reuse.' Also clarifies when to pass brandId and that it switches the active brand like use_brand, giving clear context on how to use the tool relative to siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_published_postsList what this brand has publishedARead-onlyInspect
List every post Hermoso has recorded publishing for this brand — channel, permalink, caption, format, the HOOK and SUBJECT it was written to, and its measured engagement. This is the brand's own publishing history across all nine channels in one place, and it is the memory that makes 'which hook worked?' answerable at all. Each row says how it was recorded: 'captured' (written at publish time — the hook is what the author actually intended) or 'backfilled' (reconstructed from the platform afterwards, where the hook is only known if the post matched a Hermoso creation). A dash for engagement means the platform reported no number — that is NOT zero engagement. Read-only, 0 credits.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | max posts (default 50, max 200), newest first | |
| channel | No | filter to one channel: facebook, instagram, threads, x, linkedin, youtube, tiktok, reddit, pinterest, google_business |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, and the description consistently states 'Read-only, 0 credits,' so there is no contradiction. Beyond annotations, it discloses important data semantics: the 'captured' vs 'backfilled' distinction explains how the hook was derived, and the dash-for-engagement caveat ('that is NOT zero engagement') prevents misinterpretation. This is valuable behavioral context that the schema and annotations do not provide.
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 rich but not bloated. It front-loads the core listing purpose, then adds the provenance and dash annotations, and ends with a concise read-only flag. Every sentence earns its place, though the first sentence is slightly long with the full field enumeration. It is well-structured and readable rather than a wall of text.
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?
The tool is complex due to cross-channel scope and data provenance, but the description covers the essential interpretive points: what fields are returned, the captured/backfilled distinction, and the dash-not-zero rule. It does not mention pagination behavior (beyond the limit parameter) or what happens when no posts exist, but those are minor. The absence of an output schema is compensated by the explicit field list. Overall it is sufficiently complete for correct invocation and result interpretation.
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 description coverage is 100%: both 'limit' and 'channel' are fully documented with defaults, max values, and the list of channel options. The description adds only a mild reinforcement ('across all nine channels') but does not explain parameter formatting or edge cases beyond the schema. Since the schema carries the full burden, a 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?
The description opens with a specific verb and resource: 'List every post Hermoso has recorded publishing for this brand.' It enumerates the exact fields returned (channel, permalink, caption, format, hook, subject, engagement) and states it is the brand's history 'across all nine channels in one place,' which distinguishes it from channel-specific siblings like list_meta_posts or list_threads_posts. This makes the tool's role 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 a primary use case (
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_scheduledList scheduled and past postsARead-onlyInspect
Show what is queued to post and what already went out. Each fired item reports PER-CHANNEL outcomes, so you can see that (say) Instagram published and TikTok failed on the same item rather than a single misleading verdict. Read-only, 0 credits.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, and the description reinforces read-only behavior with 'Read-only, 0 credits.' It adds valuable context beyond annotations by explaining the per-channel outcome reporting ('Each fired item reports PER-CHANNEL outcomes'), which tells the agent exactly how results are structured and avoids a misleading single verdict. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences. The first sentence immediately states the core purpose, and the second adds a crucial behavioral detail (per-channel outcomes) plus a cost note. Every word earns its place, with no fluff. Front-loaded and efficient.
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, parameterless listing tool, the description covers the key purpose and the most important nuance (per-channel outcomes). It also mentions read-only and 0 credits. However, it omits potential details like pagination, date ranges, or whether all items are included, but given the simplicity and the absence of an output schema, these are not critical 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?
The tool has zero parameters, and the schema coverage is 100% trivially. Per the rubric, a baseline of 4 is appropriate for 0-parameter tools. The description adds no parameter information, but none is needed.
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 the tool's scope: 'Show what is queued to post and what already went out.' It uses a specific verb (show) and resource (scheduled and past posts). However, it does not differentiate from the sibling list_published_posts, which might overlap with 'what already went out', so an agent may not know which to pick without further investigation.
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 explicit guidance on when to use this tool versus alternatives like list_published_posts, schedule_post, or cancel_scheduled. It does not state when not to use it or mention any exclusions. The only hint is the implicit purpose, but that is not sufficient for an agent to confidently choose this tool over siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_sheet_tabsList the tabs in a Google SheetARead-onlyInspect
The tabs in a Google Spreadsheet, each with its name, numeric sheetId, row/column count and position. Call this BEFORE naming a tab in update_sheet / clear_sheet_range / manage_sheet_tabs / format_sheet, and before proposing to delete one — it is how you learn what the file actually contains instead of guessing at a name. Read-only, free.
| Name | Required | Description | Default |
|---|---|---|---|
| sheetUrl | No | a Google Sheets URL — the id is extracted from it | |
| spreadsheetId | No | the spreadsheet id (from create_sheet, or list_drive_files for one the user picked) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false. The description adds 'Read-only, free,' reinforcing safety and cost behavior, plus explains its role as a discovery step. It doesn't contradict annotations and adds modest extra context beyond what annotations already provide.
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 efficiently convey purpose, usage guidance, and safety, with the core function front-loaded and no redundant content. Every sentence 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?
Without an output schema, the description compensates by enumerating the fields returned (name, sheetId, row/column count, position) and explaining its role relative to other sheet operations. It provides all necessary context 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?
Schema coverage is 100%: both sheetUrl and spreadsheetId are described in the schema. The description does not add any new parameter semantics beyond what the schema already specifies, so 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?
The description clearly states the tool lists tabs in a spreadsheet with specific fields (name, sheetId, row/column count, position). It also differentiates itself as a prerequisite for several sibling tools, making its purpose and scope 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?
Explicitly instructs when to call this tool: before naming a tab in update_sheet, clear_sheet_range, manage_sheet_tabs, format_sheet, and before proposing deletion. It also explains the reasoning (to learn actual content instead of guessing names), giving clear contextual guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_skillsList skillsARead-onlyInspect
List the bundled Hermoso SKILLS — multi-step workflow instructions (SKILL.md) that orchestrate the other tools (research an ad space, plan+render a finished ad, product photoshoot, raw generation) — plus the in-app strategy skills and creative recipes. Call get_skill to load a bundle. Read-only, free.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is covered. The description adds value by stating 'Read-only, free' and explaining what skills are and how they relate to other tools. It does not contradict annotations and gives useful behavioral context beyond the 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?
The description is two sentences with no fluff. It front-loads the core purpose ('List the bundled Hermoso SKILLS') and then adds relevant context and a call-to-action. Every word earns its place, making it highly efficient.
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 list tool with no parameters and no output schema, the description is complete. It tells the agent exactly what is listed, what those items are, and how to get more detail (get_skill). There is no missing information an agent would need to invoke this tool 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?
The tool has zero parameters and the schema is empty with 100% description coverage. Since there are no parameters to explain, the description is not required to add parameter details. The baseline for 0 parameters is 4, and the description fully compensates by explaining what the tool lists and why.
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 the verb 'List' and the resource 'bundled Hermoso SKILLS', and elaborates that these are multi-step workflow instructions (SKILL.md) that orchestrate other tools. This distinguishes it from sibling tools like get_skill and list_playbooks by specifying the exact content being listed.
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 explicit next-step guidance ('Call get_skill to load a bundle'), which helps an agent understand when to use this tool and what to do after. However, it does not explicitly contrast this with other list tools (e.g., list_playbooks, list_creators) or state when NOT to use it, so it falls short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_swipefileList the swipefileARead-onlyInspect
List this workspace's SWIPEFILE — the saved-ad research board: every named collection and the ads/creatives kept in it (advertiser, headline, body copy, media URL, platform, when it was saved, and any taste tags). The SAME board the web app's Swipefile tab shows. Use it to answer "what have we saved?", to mine the user's own taste before planning an ad, or to find a reference to remix. Read-only, free.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | max ads to return (default 50, max 500) | |
| collection | No | only list ads in this collection (by name or id) — omit for every collection |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, covering the safety profile. The description adds that it lists 'every named collection' and the exact fields returned, plus the note that it's the 'SAME board' as the web app. It also says 'free,' which is not in annotations. While these are useful, they don't go far beyond what a read-only list operation implies given the schema. No auth, rate limits, or pagination details are mentioned, but those are not critical given 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 description is front-loaded with the core action and resource, then lists returned fields, ties it to the web app, gives use cases, and concludes with read-only/free. Each sentence adds value, though it could be slightly trimmed. Overall, it's well-structured and not bloated.
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 list tool with no output schema, the description adequately covers what the tool returns (explicit field list), when to use it (use cases), and its read-only nature. It doesn't describe errors or edge cases, but the schema handles parameters. Given the low complexity and schema coverage, this is sufficient.
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 covers both parameters (limit and collection) with descriptions, so schema_description_coverage is 100%. The tool description does not elaborate on parameter behavior beyond what the schema states. The phrase 'every named collection' implicitly relates to the collection filter, but it adds no new semantics. 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?
The description states a specific verb ('List'), a clear resource ('this workspace's SWIPEFILE'), and defines what that resource contains: every named collection and the ads/creatives with fields like advertiser, headline, body copy, media URL, platform, save date, and taste tags. It also explicitly ties it to the web app's Swipefile tab, making the scope unambiguous. This clearly distinguishes it from siblings like save_to_swipefile, which writes, and export_swipefile_deck, which exports.
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 explicit use cases: answering 'what have we saved?', mining the user's own taste before planning an ad, or finding a reference to remix. It also notes the tool is read-only and free. However, it does not explicitly name alternative tools for contrasting use or state when not to use this tool, though the use cases are concrete enough to guide an agent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_teamList team membersARead-onlyInspect
List the members of the current brand workspace — email, role (admin/member) and status. Read-only, free.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and destructiveHint, and the description reinforces this with 'Read-only' while adding the extra 'free' (cost) information not present in annotations. It also discloses the returned fields, providing useful behavioral context beyond the 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?
The description is a single, concise sentence that front-loads the core action and scope. It contains no fluff and every word adds value, earning a top score.
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 list tool, the description is largely complete: it states what is listed and the returned fields. It does not mention pagination or error handling, but these are not critical for a simple list operation, and the description covers all essential information an agent needs to invoke 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?
The tool has zero parameters and the schema description coverage is 100% (empty schema). With no parameters to document, the description correctly omits parameter details, and the baseline for 0-parameter tools is 4.
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 the specific action ('List') and resource ('members of the current brand workspace') and enumerates the fields returned (email, role, status). It is unambiguous and distinguishes itself from sibling mutation tools like invite_member or remove_member.
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 clear context by specifying the scope ('current brand workspace') and implies read-only usage, but it does not explicitly name alternatives or state when not to use it. Since the action is straightforward, the context is sufficient for an agent to decide when to call it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_telegram_chatsFind Telegram chat idsARead-onlyIdempotentInspect
Find the chat ids this Telegram bot can be addressed by. STATE THE LIMIT WHENEVER YOU USE IT: this is NOT the list of chats the bot belongs to — the Bot API publishes no such method — it is every chat that SENT the bot an update in the last 24 hours, which is as long as Telegram keeps an update. A channel the bot posts to every day but nobody messages will NOT appear here, and its absence means nothing at all: post to it by @username or numeric id anyway. If the bot has an outgoing WEBHOOK configured the list is empty for that reason alone (Telegram: getUpdates "will not work if an outgoing webhook is set up"), and the reply says so rather than reading as an empty account. Nothing is consumed — no update offset is confirmed, so this cannot eat the bot’s pending updates. Free, 0 credits.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | how many recent updates to scan, 1–100 (default 100) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, openWorldHint, idempotentHint, and destructiveHint=false. The description adds significant behavioral context beyond that: it explains the 24-hour update window, the webhook caveat, and explicitly states 'Nothing is consumed — no update offset is confirmed, so this cannot eat the bot’s pending updates.' This directly addresses side-effect concerns and data source limitations, going well beyond what annotations provide.
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 longer than average, but every sentence earns its place: it front-loads the purpose, then delivers critical caveats (non-exhaustive list, webhook effect, non-destructive nature). It is structured to lead with the answer and then preempt misinterpretations. A bit verbose, 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?
With no output schema, the description fully covers what the tool returns and when it might be incomplete or empty. It addresses edge cases (no messages, webhook), explains the update window, and reassures about side effects. An agent has all necessary information to use 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?
The schema has 100% coverage for the single parameter 'limit' with a description of range and default. The tool description does not mention this parameter or add any additional meaning. Since the structured schema already documents it, the baseline of 3 is appropriate; the description adds no extra value here.
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 verb (find) and resource (chat ids), and explicitly scopes it as 'this Telegram bot can be addressed by'. It immediately distinguishes itself from a full chat list by saying 'this is NOT the list of chats the bot belongs to', differentiating it from potential sibling tools like list_telegram_dms.
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 clear guidance on when to use it: to get addressable chat ids, and warns when it will fail to show chats (channels without message activity, webhook configuration). It even advises 'post to it by @username or numeric id anyway' for absent channels. It does not explicitly name sibling tools but effectively tells the agent what this tool is and is not for.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_watch_findingsRead the competitor watchARead-onlyInspect
Read what the standing COMPETITOR WATCH has found — the new ads each watched brand has launched since the last check, plus the watch's own state (who is watched, when it last ran, when it runs next, and whether the last run actually succeeded). The same board the web app's Ad Spy ▸ Watching tab renders. Use it to answer "what are our competitors running that's new?", to feed a teardown, or to save something worth keeping with save_to_swipefile. Findings marked seed:true are NOT new launches — the first check of a brand has nothing to diff against, so it seeds the board with what that brand is running right now; only later runs surface genuine changes. Read-only and free — it returns the stored results of past runs and never triggers a check (set_competitor_watch({runNow:true}) is what runs one).
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | max findings to return (default 25, max 75 — the server keeps at most 75, and at most 15 per brand) | |
| competitor | No | only findings for this watched brand (exact name as returned in `watching`) — omit for all of them |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint and destructiveHint, but the description adds critical behavior beyond that: it clearly states 'Read-only and free — it returns the stored results of past runs and never triggers a check.' It also explains the seed:true semantics, which is essential to correctly interpret results. These nuances are not present in annotations, so the description fully covers 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 a dense paragraph of about five sentences, but every sentence contributes necessary context (scope, state fields, seed semantics, read-only behavior, and pointer to set_competitor_watch). It is not as tight as a two-sentence version, but there is no fluff or repetition. Front-loading the core read action keeps the most important info first.
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?
The tool has a non-trivial return shape (findings plus watch state) and an ambiguity around seed:true. The description explains both the content and the seed nuance, clearly states what it does NOT do (trigger a check), and even references the web app's Ad Spy tab for orientation. Given there is no output schema, this description is sufficient for an agent to know when and how to use 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 description coverage is 100%, so the schema already documents both parameters (limit and competitor) thoroughly. The description does not add any additional parameter-specific detail beyond what the schema provides; it only mentions the behavior generically. Thus baseline 3 is appropriate since the schema carries the semantic weight.
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 opens with a specific verb and resource: 'Read what the standing COMPETITOR WATCH has found' and details exactly what is returned (new ads plus watch state). It also distinguishes itself from siblings like set_competitor_watch by explicitly stating it never triggers a check, so an agent can tell them apart 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?
The description gives concrete use cases: 'Use it to answer "what are our competitors running that's new?", to feed a teardown, or to save something worth keeping with save_to_swipefile.' It also names the alternative for triggering a check explicitly: 'set_competitor_watch({runNow:true}) is what runs one.' This provides clear when-to-use guidance and exclusion.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_whatsapp_accountsWhatsApp Business accounts and numbersARead-onlyInspect
The WhatsApp Business Accounts SHARED WITH THIS BRAND and the phone numbers registered on each — the ids every other WhatsApp tool needs, plus each number’s QUALITY RATING, which is what decides how many messages Meta will let it send. Start here. A WABA with no number cannot send anything and the reply says so: Hermoso does not register or verify numbers, that is WhatsApp Manager. A business portfolio that could not be read is REPORTED rather than dropped — an account missing from this list would read as "the brand has no WhatsApp", which is a claim about their business and not about our read. TWO ACCOUNTS CAN CARRY THE SAME DISPLAY NAME — always quote the display field or the id when naming one to a user, never the bare name. ONLY THE ACCOUNTS SHARED WITH THIS BRAND ARE REACHABLE. One Meta login often administers WhatsApp for several businesses, so a human ticks which belong to this brand under Settings ▸ Connectors ▸ Meta ▸ Manage accounts (or set_connector_accounts(provider:"meta")); nothing else here can see or touch the rest. With none ticked every WhatsApp tool refuses and names that as the way out. With exactly ONE ticked, wabaId is optional — pass it only to disambiguate. Read-only, 0 credits (WhatsApp conversations are billed by META to the business directly, never in Hermoso credits). Needs Meta connected.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes far beyond the readOnlyHint and openWorldHint annotations. It discloses read-only and zero-credit behavior, explains that only brand-shared accounts are reachable, that failed reads are reported rather than dropped (which could cause misinterpretation of missing accounts), and warns about duplicate display names. This is rich behavioral context not in 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?
Although the description is longer than typical, every sentence earns its place by conveying critical operational details. It is structured to front-load the core purpose, then sequentially covers caveats, configuration, and billing. No fluff or redundancy; each sentence adds unique 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?
Given there is no output schema, the description thoroughly explains what the tool returns (IDs, phone numbers, quality rating) and the implications of that data (send limits, needed by other tools). It also covers error behaviors, naming pitfalls, account selection rules, and credit billing. Everything an agent needs to correctly call and interpret this tool is present.
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 parameters, so the description has no need to elaborate on them. The baseline is 4 for tools with no params. The description does not waste space repeating nonexistent parameters and instead focuses on output semantics, which 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 explicitly states the tool lists WhatsApp Business Accounts shared with the brand, including phone numbers, IDs, and quality ratings. It clearly distinguishes itself from other WhatsApp tools by naming them as consumers of these IDs, and it is unambiguous about the resource and verb.
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?
Provides explicit 'Start here' guidance, explains when to use it versus alternatives (e.g., WhatsApp Manager for number registration), and details the behavior when no accounts are ticked, including the way to configure via set_connector_accounts. It also covers the case of a single account making wabaId optional, giving clear actionable context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
make_explainerMake an explainer videoAInspect
Turn a TOPIC into a finished narrated explainer video. Writes a sectioned script, paints a BURST of pictures per section (about one every 1.5s — most of them one-detail edits of the frame before, so it reads as movement rather than a slideshow), narrates each section with TTS, holds each picture PERFECTLY STILL for its own slice of the narration (the motion is the CUT RATE — a slow move on a still shimmers), then composites the end card (and any on-screen text you asked for) with the Chrome+ffmpeg engine the ads use (text is never model-painted, so it never garbles). BURNED ON-SCREEN TEXT IS OFF BY DEFAULT — the narration carries the point and the pictures carry the story, so the film ships clean unless the user asks otherwise; captions:true adds held key points and subtitles:true adds narration-timed CAPS (see both). It is an image film WITH motion, not N video-model renders — that's what keeps it affordable. style picks the visual family: the default 'cinematic' is photoreal editorial; every other id is a STYLED, strictly non-photoreal look (illustrated / collage / clay / pixel …) that first renders ONE style-key image and then locks every scene to it, so the whole film holds one look. Cost at the default frame density: a ~130-credit hold for a 60s explainer on the default style, ~100 styled; frameDensity:'lean' roughly halves it and 'minimal' (one picture per section) is ~30. All settle to the exact per-frame image + narration spend (a longer target = more sections = more). Takes SEVERAL minutes — one image render per frame; independent frames are painted concurrently, so it is far faster than the frame count suggests. Needs the writing model and a narration voice engine connected. NOT the tool for a short product ad — use render_ad or generate_video for those, and make_template_ad for the deterministic native formats.
| Name | Required | Description | Default |
|---|---|---|---|
| music | No | music bed under the narration, measured to sit about 14 dB under the voice and sidechain-ducked beneath it. Omit and the KIDS and FAIRYTALE channels get their recommended bed COMPOSED for this film — those two are the only channels a bed is due on unasked, and it costs a small flat fee; every other channel ships dry. 'off' forces silence. 'library' takes a free curated track only, and ships dry when none is on file. NAME A MOOD — upbeat / calm / warm / epic / tense / playful / elegant / hype / chill / dramatic — to compose one on ANY channel, at the same fee. hermoso_capabilities reports the exact figure as explainerMusicCredits; quote it before you turn a bed on or pick a mood. | |
| style | No | visual style. 'cinematic' (default) is photoreal; the rest are non-photoreal styled looks — editorial_collage (halftone cutouts + marker accents), flat_vector, stickman, whiteboard, ink_marker, silhouette, storybook (gouache), paper_diorama, isometric, claymation, pixel_art, watercolor, fluffy_toy (felted plush), low_poly, stylized_3d (matte clay render), studio_3d (preschool toy 3D on a white sweep — the Kids default), mannequin (clay-render reenactment figures — a History alternate). Ask the user which they want rather than picking silently; a styled pick costs more (see the cost note). | |
| topic | Yes | what the explainer should teach or explain — a topic or a short brief | |
| voice | No | narration voice name — omit for the default warm read | |
| channel | No | the CHANNEL TYPE — it sets the pacing, the narration register and the default look, and is orthogonal to `style` (a named style always wins): explainer (casual second-person, fast cuts), history (witty chronological retelling / documentary), kids (fastest, question-first, warm teacher), fairytale (slow, atmospheric myth or folklore). Default 'explainer'. | |
| endCard | No | append the branded end card (default true) | |
| upscale | No | optional FINAL upscale — 2 doubles each side, 4 quadruples. Captions and the end card are burned BEFORE it so they upscale with the frame. It is priced BY LENGTH and it is the expensive part — several times the cost of rendering the film itself. hermoso_capabilities reports the exact figures per length as explainerUpscaleCredits. Never turn it on unasked: quote the number and let the user choose. | |
| captions | No | turn ON-SCREEN TEXT on. DEFAULT FALSE, and leave it false unless the user asks — the narration already says the point and the pictures carry it, so the clean film is the better default. `captions:true` on its own burns SUBTITLES (see below), because that is what a caption is for: showing what is being said when the phone is on mute. Slim white CAPS, thin black outline, bottom safe band, no plate, no box. | |
| brandName | No | brand name for the end card — omit to leave it unbranded | |
| subtitles | No | which on-screen text, once `captions` is on. LEAVE IT UNSET (or true) for SUBTITLES — every spoken word, in order, timed to the narration; free, no extra render, no extra credits, and there is NO cue limit, so the whole film is subtitled however long it runs (at most 5 words / 32 characters a line). Set it FALSE only if the user explicitly wants section HEADINGS instead: one short summary label held over each ~7-15s section. That is NOT what is being said — it is a label about it — so it is the wrong answer to "add captions" and to anyone watching on mute. `subtitles:true` also implies `captions:true`. TIMING: each cue is anchored to that section’s REAL measured narration length and distributed inside the section by character count — exact at every section boundary, approximate to a few tenths of a second within one. It is not a word-level speech clock, so never promise frame-accurate sync. | |
| aspectRatio | No | '9:16' default | |
| frameDensity | No | how many pictures per second of narration, and therefore what it costs. 'standard' (default) is a frame about every 1.5s — the density a stills film needs to read as a film rather than a slideshow; 'lean' is one about every 2.5s (the longest hold that still reads as a film, ~40% of the frames and ~40% of the cost); 'minimal' is ONE picture per narration section, which is cheapest and is frankly a slideshow. Only drop below the default if the user asked for something cheaper. | |
| durationSeconds | No | target length 20-120s (default 60); drives the section count — ~10s of narration each, 3-8 sections |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations are minimal (all four hints are false), so the description carries the full burden — and it delivers extensively. It discloses the long-running nature ('Takes SEVERAL minutes — one image render per frame'), the concurrency trait ('independent frames are painted concurrently, so it is far faster than the frame count suggests'), the cost model with concrete credit figures per style and density tier, the motion mechanics (hold-still + cut rate + shimmer), the text pipeline that avoids garbling ('text is never model-painted'), and the on-screen text default. No contradiction with annotations: readOnlyHint=false correctly matches a tool that produces a new artifact.
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 long (~450 words), but for a 13-parameter video-generation tool with subtle defaults, a cost model, and sibling differentiation, nearly every sentence earns its place. Structure is logical: purpose → motion model → text defaults → style → cost → performance → prerequisites → disambiguation. It drops to a 4 rather than 5 because a few passages (e.g., the 'slow move on a still shimmers' physics and the parenthetical on one-detail edits) add flavor more than agent decision value, and the length makes front-loading slightly harder to absorb at a glance.
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 tool of this complexity with no output schema and sparse annotations, the description is remarkably complete: it covers outcome, cost, timing, prerequisites, defaults, and disambiguation. The one genuine gap is the return value — for a multi-minute asynchronous operation, the agent is never told what comes back (a job handle? a URL?) or how to retrieve the result. Given sibling tools like get_job imply an async job pattern, this is a meaningful omission that keeps it from a 5.
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?
Even with 100% schema coverage (baseline 3), the description adds substantial meaning beyond the schema. It explains the music default behavior (which channels get a composed bed unasked, mood-name composition on any channel, dry shipping, and how to look up exact credits), the captions-vs-subtitles-vs-section-headings distinction with timing approximation caveats, the upscale pricing warning and quote-before-acting rule, the cost implications of each frameDensity tier and what makes a stills film read as a film, and per-style visual descriptions. This materially improves the agent's ability to set parameters correctly.
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, unambiguous statement of purpose: 'Turn a TOPIC into a finished narrated explainer video.' It then walks through the full production pipeline (script → pictures → TTS narration → end-card composite), and explicitly differentiates itself from siblings: 'NOT the tool for a short product ad — use render_ad or generate_video for those, and make_template_ad for the deterministic native formats.' An agent can immediately tell what this tool does and how it differs from the closest alternatives.
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?
Provides explicit when-to-use and when-not-to-use guidance with named alternatives (render_ad, generate_video, make_template_ad). It also gives strong default-handling instructions: leave captions/subtitles off unless the user asks, never enable upscale unasked and quote the credit figure first, 'Ask the user which [style] they want rather than picking silently,' and only drop frame density below default when the user asks for cheaper. Prerequisites are stated ('Needs the writing model and a narration voice engine connected'). This is unusually actionable routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
make_template_adMake template adAInspect
Render a NATIVE-STYLE TEMPLATE ad from pure HTML — no AI video/image model in the loop, renders in ~30 seconds for a couple of credits. Perfect for native-feel social ads at volume. YOU author the content (short, casual, believable — never marketing-speak). Templates (pass as config.template): 'imessage-chat' (VIDEO ~15s: a real-looking iMessage thread where a friend reveals the product as a rich-link card; config: { thread: { contactName, messages: [{from:'them'|'me', text?, product?:{image,title,domain}}] }, theme?:'dark'|'light', endCard:{headline,cta,domain,logo?,color} } — 4-6 short lowercase bubbles, product card mid-thread from 'me', 1-2 excited replies after); 'chatgpt-chat' (VIDEO: a ChatGPT answer streams the punchline; config: { question, answer (may bold the brand), productImage?, endCard }); 'apple-notes' (VIDEO: an iPhone note types itself out; config: { title, lines: string[], theme?, endCard }); 'value-prop' (VIDEO ~17s kinetic typography: config: { hook (≤40 chars), claims: string[] (3-5 COMPLETE phrases, ≤6 words / ≤34 chars each — a finished thought, NEVER a clipped clause like 'Looks good on any'), productImages: string[] (2-3 DISTINCT photos — one rotates per card), palette: string[], endCard }); 'static-mockup' (IMAGE: config: { style:'imessage'|'notes'|'card', size?:{w,h}, ...style fields }); 'airdrop-carousel' (VIDEO ~10s: an iOS AirDrop share card springs up and cycles 3-16 REAL product photos to a full-lineup payoff; config: { brandName, products: [{image, title?}], contactLine?, endCard }); 'app-ui-tour' (VIDEO ~12-16s for APP brands: floating-iPhone mockup walks through REAL app screenshots with kinetic captions; config: { hook?, appName, iconImage?, beats: [{screenImage, caption}] (2-6), palette?, fontStack?, endCard }); 'imessage-cascade' (VIDEO ~12s: iOS notification banners spring in and stack over a blurred backdrop; config: { notifications: [{sender, text}] (4-8), backgroundImage?, endCard }); 'photo-grid' (VIDEO ~8s: collage assembles real photos one at a time; config: { title?, photos: [{image, label?}] (4-9), palette?, fontStack?, endCard }); 'vignette' (VIDEO ~12s: cinematic Ken-Burns hero film; config: { hook, lines: [2-4 ≤40ch], heroImage, palette?, fontStack?, endCard }); 'kinetic-type' (VIDEO ~9-15s typographic motion design with NO VOICEOVER — it is NOT a silent asset: it always carries its own synthesised SFX (whoosh/tick/chime) and, once a curated track is on file, the family's loudest music bed at -16 LUFS; config.music:'off' silences the bed but never the SFX: 3-6 short phrases each land word by word on a full-bleed brand card (product beats caption the phrase over the photo instead), the longest word picked out in the brand accent, and a skewed accent slab wipes every cut; supply productImages and every OTHER beat becomes a full-bleed product shot with its phrase captioned over it — with none it renders as pure typography, so it needs NO photos; config: { phrases: string[] (3-6, ≤34 chars each — punchy, declarative, ONE idea per phrase, a finished thought never a clipped clause), productImages?: string[] (up to 4 DISTINCT photos), palette?: string[], fontStack?, endCard }); 'myth-vs-fact' (VIDEO ~15-26s VO-FIRST kinetic explainer with a real VOICEOVER — the family's ONE paid-audio format: a calm-authority read busts 2-4 myths, each MYTH line slamming in with a red per-line strike then the counter FACT line landing bold+affirmative, word-level KARAOKE lighting each word as the VO speaks it; config: { pairs: [{ myth (≤50ch, the common wrong belief), fact (≤60ch, the corrective truth — wrap its payoff phrase in [brackets] to accent it) }] (2-4), palette?, fontStack?, endCard }. Real product truths only — NEVER invent stats. Costs the flat template credits PLUS a small voiceover charge); 'carousel' (MULTI-IMAGE: 5-10 branded 1080×1080 PNG slides for Meta/LinkedIn/IG carousels — returns an images[] array, one PNG per slide; config: { cover: { hook?, title }, slides: [{ headline (≤8 words), support? (≤16 words), stat?: { value, label } }] (3-8; a stat slide is a REAL user-supplied number like '94%' or '40k+' + a label, never invented), cta: { headline, cta?, domain? }, productImage?, logo?, palette?, fontStack?, endCardColor? }). Every VIDEO format except myth-vs-fact (VO-first, deliberately dry) also gets a mood-matched MUSIC BED when a curated track is on file (the library ships empty — no track means no bed, never a paid generation) under its own SFX, from the curated library — free, no model, no extra credits; set config.music:'off' for a silent cut or a mood name (upbeat/calm/warm/epic/tense/playful/elegant/hype/chill/dramatic) to re-mood it. Image URLs may be any public URL — the server localizes them. Spends a couple of credits.
| Name | Required | Description | Default |
|---|---|---|---|
| config | Yes | the template config — MUST include config.template (one of the template ids above) plus that template's fields |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations are all-false, so the description carries the full burden — and it delivers richly. It discloses render time (~30 seconds), cost (a couple of credits), audio behavior (music bed only when a track is on file, never a paid generation; SFX always present unless silenced), output types per template (VIDEO/IMAGE/MULTI-IMAGE with a PNG images[] for carousel), and that image URLs are server-localized. Exceptionally thorough.
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 an enormous single paragraph of dense run-on text and deep parentheses that is hard to scan, even though nearly every sentence carries real information. It front-loads the purpose well, but 13 interleaved template specs, character limits, and style guidance would benefit from structured separation. Size is justifiable given complexity, but structure is not.
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?
Complete for a high-complexity tool with no output schema. It enumerates every template variant, its duration, config contract, content constraints (character/word limits, 'never invent stats'), audio behavior, and cost structure. Nothing an agent needs to call it correctly or to pick a template is missing, including the credit implications.
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's single config param is a bare '{}' object with no properties defined, so schema coverage is nominal. The description compensates overwhelmingly — it documents all 13 templates with their full config contracts (e.g., imessage-chat thread/messages/endCard, value-prop hook/claims limits, myth-vs-fact pairs with bracket escape hatch). An agent could construct a correct config purely from this text.
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 opens with a specific verb+resource ('Render a NATIVE-STYLE TEMPLATE ad from pure HTML') and immediately distinguishes itself from model-driven tools by stating 'no AI video/image model in the loop'. With siblings like render_ad, make_explainer, and product_sizzle present, this differentiation is essential and well-executed.
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 when to use it ('Perfect for native-feel social ads at volume') and imposes clear content authorship rules ('YOU author the content — short, casual, believable — never marketing-speak'). It does not name alternative tools or state explicit when-not-to-use conditions, which the parenthetical about the model-free approach partially covers.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
make_thumbnailMake video thumbnailAInspect
Render a click-driving YOUTUBE / Shorts / Instagram THUMBNAIL or video cover — the full production pipeline (concept framework → casting → scene → render → surgical tweaks → text), not a bare image prompt. Use this for any "thumbnail", "video cover", "video preview" or MrBeast-style packaging ask INSTEAD of generate_image. About 9 credits per variant; the headline overlay is free.
CONCEPT — every thumbnail must open an INFORMATION GAP (the image raises a question the title answers) while staying truthful to the video. Brainstorm ≥5 concepts across the 16 frameworks before you pick, and feel free to combine two. Frameworks (pass as framework): before_after · social_ui · three_step · screenshot · posed_portrait (the default) · posed_action · specific_day · graphical · landscape · map_aerial · product · adding_text · repetition · size_difference · news_clip · amplified_reality. Call hermoso_capabilities for each one's full 'realize it with' note plus the emotion, overlay-style, font and rim-colour catalogs.
THREE GATES, all BEFORE you render:
WHO IS IN FRAME — never assume and never silently substitute a stranger. If the framework puts a person in frame and no face photo is attached, the tool refuses (nothing rendered, nothing charged) and tells you to ask the user once: themselves (send a face photo → the identity gets locked), a generated person (
castGenericPerson:true), or a people-free framework.TEXT — the default is a CLEAN render with the headline TYPESET OVER THE TOP afterwards (free, always legible, correctly spelled). Just pass
headline. Only setbakeText:trueif the user explicitly asks for the words painted INTO the image — verified live, that renders the asked-for words correctly but leaks garbled invented text across the rest of the frame. Never infer text intent from the topic or the framework.HOW MANY — ask once whether they want one thumbnail or a SET (offer 4: the same concept at different emotions and/or camera takes). Default is 1;
variantscaps at 16.
IDENTITY LOCK is automatic for every attached face photo. emotion is the single biggest CTR lever on a face: shock · hype · fear · confusion · determination · smug · charisma · disgust · awe · rage · laugh (or your own phrase). Finished thumbnail needs a fix? Re-call with tweak + sourceImage for a surgical, pixel-faithful edit (emotion / background / background_color / rim_light) instead of re-rendering — tweaks chain. ALWAYS check the returned postRenderCheck against the image before you present it.
PROMPT LANGUAGE — write every DESCRIPTIVE field in ENGLISH (sceneBrief, keyElements, location, composition, background, topic, each person's describe, and every reference field), translating the user's wording where needed: the image models are trained on English and a non-English scene description renders noticeably worse. Text that gets BAKED OR TYPESET stays verbatim in the user's own language — headline, headlineLines and bakedUiText are never translated.
| Name | Required | Description | Default |
|---|---|---|---|
| font | No | headline font (default Anton). Alternatives incl. Bebas Neue, Oswald, Archivo Black, Montserrat, Inter, Playfair Display | |
| logo | No | a brand logo URL or path to place into the composition | |
| split | No | split/panel LAYOUT — only when the user asks for one ("split", "before/after", "versus screen"). "X vs Y" as a SCENE stays one unified frame | |
| takes | No | camera takes per emotion, 1–4: designed framing / low-angle hero / extreme close-up / wide dutch tilt | |
| topic | No | the video's topic — used to pick the hero object when you don't name keyElements | |
| tweak | No | surgical pixel-faithful edit of a FINISHED thumbnail — needs sourceImage | |
| logo3d | No | first turn the flat logo into a volumetric 3D render (one extra billed image), then composite that | |
| people | No | people described in prose instead of by photo (each still gets the chosen expression) | |
| emotion | No | the expression on the face (default 'shock') — a preset id or your own phrase | |
| bakeText | No | default false. true paints the headline INTO the generation — only on an explicit user ask; it leaks garbled text elsewhere in the frame | |
| emotions | No | render one variant per emotion (variants = emotions × takes, max 16) | |
| headline | No | 2–4 word headline. Typeset OVER the finished render by default (free, always legible); newlines split it into stacked lines | |
| location | No | place, time of day, weather, atmosphere | |
| rimColor | No | colored back+hair light — ONLY when the user names one: 'ice-blue' / 'neon-magenta' / 'toxic-lime' / 'amber-gold' / 'pure-white' | |
| variants | No | how many thumbnails to render (default 1, max 16). Each is its own billed render — offer a set of 4 rather than assuming | |
| framework | No | concept framework id (default 'posed_portrait'); see the list in this description / hermoso_capabilities | |
| reference | No | fields YOU extracted by eye from a reference thumbnail. Extract ALL of: brief (one dense sentence on the concept), subject (pose/action generically, NEVER a specific identity), elements, location, composition, background, split (boolean), split_count, person_count (0-3), emotion (one of the 11 presets or 'other'), emotion_detail (one vivid sentence covering eyes, brows, mouth, head angle). emotion + emotion_detail carry the reference's actual facial performance, which is the single biggest CTR lever on a face; split/split_count reproduce its panel structure. The reference image itself is never sent to the model | |
| background | No | override the default bold saturated colour-field background | |
| faceImages | No | up to 3 face photos (URLs or local paths) — each becomes a locked CHARACTER identity, in order | |
| sceneBrief | No | what the thumbnail depicts — the concept in one dense sentence, rendered exactly | |
| aspectRatio | No | '16:9' (YouTube, default) / '9:16' (Shorts) / '4:5' (Instagram) / '4:3' / '1:1' | |
| bakedUiText | No | short label for a text-carrying framework (a chat bubble, a DAY N badge, a news lower-third, a map callout) — needs frameworkRequested:true | |
| composition | No | override the default large-foreground-subject composition | |
| keyElements | No | signature props / effects that make it pop — oversized, flying toward camera | |
| sourceImage | No | the finished thumbnail URL a `tweak` edits; tweaks chain, so feed each accepted output into the next | |
| overlayStyle | No | headline style: 'beast' (default, white + heavy black stroke) / 'fire' / 'neon-lime' / 'clean-glass' / 'marker' | |
| forceGenerate | No | render the 'screenshot' framework anyway (it is normally a real video frame, not a generation) | |
| headlineLines | No | explicit headline lines (up to 3) — overrides splitting `headline` on newlines | |
| headlinePlace | No | where the headline sits — never over the face (default 'bottom') | |
| restrainedGrade | No | true for a calm / premium / muted look instead of the default punchy poster grade | |
| castGenericPerson | No | pass true only after the user has explicitly chosen a generated stranger over their own face | |
| frameworkRequested | No | true ONLY when the USER named this framework — it is what authorizes a text-carrying framework (social_ui / news_clip / specific_day / map_aerial) to bake its short UI label |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the sparse annotations (readOnlyHint:false, destructiveHint:false), the description discloses rich behavioral traits: refusal behavior when no face photo is attached, credit pricing, free headline overlay, identity lock, bakeText's side effect of garbled text, the default typeset overlay, language translation quirks, tweak chaining, and the requirement to check postRenderCheck. This goes far beyond what annotations provide.
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 long but well-structured with clear headers (CONCEPT, THREE GATES, IDENTITY LOCK, PROMPT LANGUAGE) and bold keywords. It front-loads the purpose and then explains necessary behavioral nuances. It is appropriately detailed for a tool with 32 parameters, but a few sections could be tightened (e.g., the prompt language paragraph is dense). Overall, it's efficient relative to the complexity.
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 the tool's complexity, no output schema, and the need to guide agents through a multi-step production pipeline, the description covers all essential aspects: concept generation, framework selection, the three gates (identity, text, quantity), identity lock, tweaking, language rules, and the required post-render check. It leaves no significant operational gap for an agent to guess.
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 100% schema coverage, baseline is 3, but the description substantially enriches parameter meaning. It explains the interplay of framework with hermoso_capabilities, clarifies when castGenericPerson should be true (only after explicit user choice), expands on bakeText, tweak, sourceImage, and reference extraction fields with practical usage context, and grounds each parameter in the production workflow. This adds value well beyond the schema descriptions.
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 opens with a precise verb ('Render') and resource ('YOUTUBE / Shorts / Instagram THUMBNAIL or video cover') and explicitly differentiates itself from generate_image ('INSTEAD of generate_image'). It also conveys the full pipeline nature, making the tool's scope unmistakable even among a huge sibling set.
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 states when to use this tool ('for any thumbnail, video cover, video preview or MrBeast-style packaging ask') and names the alternative (generate_image). It also gives conditional guidance for related operations (tweak for edits, hermoso_capabilities for framework details) and clarifies the three gate decisions before rendering.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
manage_sheet_tabsAdd, rename or delete a sheet tabADestructiveInspect
Add, rename or delete a tab in a Google Spreadsheet. action:"add" + title · action:"rename" + tab + newTitle · action:"delete" + tab. Name the tab by its TITLE or its numeric sheetId (list_sheet_tabs gives both); an unknown tab is refused with the real list rather than a Google error nobody can map back. DELETING a tab destroys everything on it: call it without confirm first to get the filled-cell count, then confirm:true + confirmCells. Google does not allow removing the LAST remaining tab in a file, and that is refused by name with the way out (clear it, or delete the whole file with delete_drive_file). Every action is read back from the spreadsheet before it is reported as done.
| Name | Required | Description | Default |
|---|---|---|---|
| tab | No | which tab — its title or numeric sheetId (rename / delete) | |
| title | No | the name for the new tab (action:"add") | |
| action | Yes | ||
| confirm | No | ||
| newTitle | No | what to rename the tab to (action:"rename") | |
| sheetUrl | No | ||
| confirmCells | No | ||
| spreadsheetId | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate destructiveHint=true, but the description goes far beyond: it warns that deleting destroys everything, requires confirmation with confirmCells, explains the last-tab restriction and its workaround, and states that every action is read back before being reported. This is excellent behavioral disclosure with no contradictions.
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 dense but every sentence earns its place. It front-loads the purpose, then systematically walks through actions, error handling, safety mechanisms, and fallbacks. No fluff, well-organized, and easy to parse.
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 the tool's complexity (three actions, confirmation, destructions, last-tab edge case) and lack of output schema, the description is remarkably complete. It covers all key behaviors, error paths, and alternatives, leaving no obvious gap for an agent 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?
With only 38% schema coverage, the description compensates well by explaining action values, tab identifiers, and confirm/confirmCells semantics in the delete flow. However, it does not explicitly clarify sheetUrl or spreadsheetId, and confirm's role in rename/add is left implicit. The description adds meaning but does not fully cover all eight parameters.
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 the tool adds, renames, or deletes a tab in a Google Spreadsheet. It distinguishes itself from siblings like list_sheet_tabs by specifying the three mutation actions, making its purpose 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 gives explicit patterns for each action ('action:"add" + title', etc.), explains tab identification by title or sheetId, and details the delete confirmation flow. It also names alternatives (clear, or delete_drive_file for the last tab) and notes error handling with the real list, providing comprehensive usage guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mine_anglesMine customer anglesARead-onlyInspect
Mine ad ANGLES from real customer language: gathers the customer's own words (Reddit, TikTok, the brand's review page + review-site results) and returns a RANKED angle bank — each angle tagged (pain / outcome / identity / fear / competitive-displacement / social-proof / contrast), 2-5 VERBATIM proof quotes, a 0-100 score with breakdown, and a ready-to-run hook in the customer's own voice. Reads YOUR saved brand (pass brandId to target a specific brand — that switches this key's active brand like use_brand). To tear down a COMPETITOR use competitor_teardown instead. Spends a few credits.
| Name | Required | Description | Default |
|---|---|---|---|
| brandId | No | a brand id/name from list_brands to mine for; omit to use the active brand |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description contradicts the annotation readOnlyHint=true by stating that passing brandId 'switches this key's active brand like use_brand', which is a state mutation. Since annotations declare the tool read-only, this is a direct contradiction. The description also adds credit cost, which is useful, but the contradiction is severe and lowers this score to 1.
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 dense but well-structured, front-loading the core action and then using a dash list for the output components. Every sentence provides useful information, but it is somewhat long and could be trimmed without losing meaning. It is efficient and easy to scan, earning a 4 rather than a 5.
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?
The description fully explains what the tool returns (a ranked angle bank with tags, quotes, score, and hook) and the input (brandId or active brand). It also notes the credit cost. Since there is no output schema, the description carries the full burden of informing the agent about the result structure, and it does so comprehensively.
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 already fully describes the single parameter brandId (including the 'omit to use the active brand' behavior), so schema coverage is 100%. The description adds the nuance about switching the active brand, but that is more of a behavioral side effect than parameter semantics. It does not clarify formats or types beyond the schema, so a 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?
The description states a highly specific purpose: mining ad angles from real customer language across multiple sources, with a detailed output specification (ranked angle bank, tags, proof quotes, score, hook). It clearly distinguishes itself from the sibling competitor_teardown by naming it explicitly. The verb 'mine' and resource 'customer language' leave no ambiguity about what the tool does.
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 explicitly tells when to use this tool (for your own brand, with optional brandId) and when not to (for competitors, use competitor_teardown). It also notes the optionality of brandId and the side effect of switching the active brand, giving the agent clear decision criteria without needing to inspect other tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
multiply_adMultiply an adAInspect
MULTIPLY a winning video ad into N variants: each gets a NEW character, outfit, location and/or objects while the cut, the camera motion, the pacing and the ORIGINAL AUDIO stay exactly as they were (that is what made the ad work), and any burned-in captions are removed. Pass the source video URL (a previous render, a job result, list_library, or the top performer from post_performance / meta_insights). HOW: the source video itself DRIVES each variant (motion transfer from one image-edited opening frame), so every variant comes back the SAME LENGTH as the source with the same cut, the same performance and the original audio — only the person, outfit, set and props change. Sources up to 30 seconds work as they are; longer ones are refused for free with the way out (trim it first: post_edit with ops [{op:'trim', start:0, end:30}] — clip_video is the AI highlight clipper, not a trim). Returns the plan and ONE JOB PER VARIANT — call get_job on each until it reports done; do not describe a variant before its URL arrives. Cost is quoted per variant in the reply (use dryRun:true to see the plan and the quote without rendering). Regions: pass regions:['Berlin','Tokyo'] to restyle variants per market; translation is a separate, explicit step — dub_video on a finished variant.
| Name | Required | Description | Default |
|---|---|---|---|
| axes | No | which axes to vary (default: all four) | |
| count | No | how many variants, 1-12 (default 6) | |
| notes | No | anything the variants must respect, e.g. "keep it women 25-40", "no gyms" | |
| video | Yes | the source video URL | |
| dryRun | No | true = return the plan and the quote, render nothing | |
| regions | No | markets to restyle for, one or more variants each, e.g. ["Berlin","Tokyo","São Paulo"] — visuals only; audio is never translated here |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds substantial behavior beyond the sparse annotations: one job per variant requiring get_job polling, same-length output via motion transfer from an image-edited opening frame, removal of burned-in captions, free refusal for sources over 30 seconds, per-variant cost quotes, and dryRun preview semantics. Nothing contradicts the annotations, and readOnlyHint=false aligns with the render-producing behavior.
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?
Information-dense with every sentence earning its place and key constraints front-loaded (purpose, preserved elements, source URL). The single wall-of-text paragraph is harder to parse than structured breaks, but the density is justified by the tool's operational complexity — the length is appropriate rather than bloated.
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?
Comprehensive for a tool with no output schema: it discloses the return shape (plan plus one job per variant), the polling requirement, cost quoting, source constraints, region behavior, and the dryRun flag. An agent has everything needed to invoke it correctly and avoid describing a variant before its URL exists; only the exact contents of the returned plan go unspecified.
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; the description improves on it by adding concrete source options for the video parameter, a worked regions example (['Berlin','Tokyo']), and the practical dryRun usage pattern (see plan and quote without rendering). The remaining params (axes, count, notes) are left to the schema, which already documents them adequately.
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 ('MULTIPLY') and resource ('a winning video ad') with the exact outcome: N variants that change character, outfit, location, and/or objects while preserving cut, camera motion, pacing, and original audio. The scope is precise enough to distinguish it from siblings like render_ad, plan_variations, dub_video, and clip_video without consulting their 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?
Explicitly names alternatives and the conditions that select them: post_edit with a trim op for sources over 30 seconds, clip_video is ruled out ('not a trim'), and dub_video is named as the separate translation step. It also identifies valid video sources (previous render, job result, list_library, post_performance/meta_insights) and when to use dryRun:true for a plan-only preview.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
plan_adPlan an ad conceptAInspect
Creative director: turn a brand + product/brief into a finished ad CONCEPT — copy variants (headline/primary/cta) plus an image_concept.prompt OR a video_storyboard, with the resolved recipe + the model ids to render with. Renders nothing; chain its output into generate_image / generate_video. THE USER’S EXPLICIT LENGTH IS SOVEREIGN: when they name a duration ("a 30 second ad", "make it 45s"), pass it as durationSeconds — the board is then AUTHORED to that length (its scenes sum to it) and render_ad renders it as one clip or stitched acts accordingly. Leaving it out lets the planner pick its own default, which is how an explicit ask silently becomes a 15s spot. Spends credits.
| Name | Required | Description | Default |
|---|---|---|---|
| hook | No | force the VISUAL scroll-stop mechanic the opening beat is built on — a hook id from list_hooks (e.g. "direct_callout", "mid_problem", "macro_asmr"). Omit to let the planner pick. A hook that cannot be delivered in this brief is DROPPED with the reason rather than rendered wrongly — an on-screen-text hook on an authentic/UGC ad is the one that bites, because that register carries zero on-screen text. | |
| brand | No | brand name, or a brand profile object {name,domain,category,palette,products,…}. OMIT to use the workspace’s SAVED brand + memory automatically (see get_brand); use draft_brand to onboard a new one | |
| format | No | 'image', 'video', or 'auto' when unspecified | |
| recipe | No | a recipe id from hermoso_capabilities to force an archetype | |
| product | Yes | what to advertise + any angle/offer the user specified | |
| setting | No | force the WHERE — a setting id from list_hooks (e.g. "kitchen", "gym", or a surreal one like "volcano_rim" / "airplane_wing", which are played 100% straight and never acknowledged). Omit for a neutral setting. | |
| language | No | output language for the ad copy (e.g. Spanish) — default English | |
| reference | No | a reference ad URL to remix the angle from — Facebook Ad Library, LinkedIn Ad Library or Google Ads Transparency links (the real ad’s copy/advertiser are fetched and fed into the concept) | |
| durationSeconds | No | VIDEO ONLY — the total spot length the user explicitly asked for, in seconds, copied verbatim (30 for "a 30 second ad"). The planner authors the storyboard TO it: the scenes’ seconds sum to it and the script is word-budgeted for it. Supported range 4–180; anything outside is CLAMPED to it (the reply says so). A length that fits ONE clip of the render model renders as a single continuous pass; anything longer is STITCHED from acts filled to that model’s clip maximum with the remainder last (on a 15s-clip model, 40 → 15+15+10 and 17 → 13+4) — never time-compressed. The maximum is the model’s own: 15s on most, 30s on the longest-clip model, so a 30s ad can be one unbroken take rather than two acts. Omit when the user named no length; do NOT pass a guess, an omitted value keeps the recipe-aware default. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations provide only minimal info (readOnlyHint:false, destructiveHint:false). The description carries the burden and delivers rich behavioral context: 'Spends credits,' 'Renders nothing,' hook dropping behavior, duration clamping and stitching logic, and the word-budget behavior. This goes far beyond what annotations declare.
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 long but purposefully so—each paragraph adds crucial operational detail. It front-loads the core purpose in the first sentence, then expands on the most complex parameter (durationSeconds) with concrete examples. While not terse, the length is justified for such a multi-faceted 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 9 parameters, 1 required, no output schema, and no annotations, the description fully compensates. It covers the overall flow, chaining, parameter behavior, edge cases (dropping hooks, clamping, stitching), credit cost, and language handling. An agent has everything needed to invoke 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 100%, but the description adds substantial meaning beyond the schema. For durationSeconds, it explains clamping (4–180), stitching (15+15+10 for 40, 13+4 for 17), and the distinction between one-clip vs stitched rendering. For hook, it explains that specific hooks are dropped if undeliverable (e.g., on-screen text on UGC). For brand, it clarifies fallback to workspace memory. This is significant added 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 description states a specific verb (turn...into a finished ad CONCEPT), names the exact deliverables (copy variants, image_concept.prompt or video_storyboard, recipe + model ids), and explicitly disambiguates from generate_image/generate_video by stating 'Renders nothing; chain its output into...'. This is highly specific and distinguishes it from siblings.
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 the tool (planning phase) and how to chain its output (into generate_image/generate_video). It also covers when to omit durationSeconds based on user mention, when to omit brand to use saved brand, and warns against guessing. It names alternatives like draft_brand for onboarding.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
plan_variationsPlan ad variationsAInspect
Fan a brief into N DISTINCT ad angles (different hooks/mechanics/audiences), each with its own headline + visual brief — then render each with generate_image and rank with score_ad. LLM planning only; renders nothing itself.
| Name | Required | Description | Default |
|---|---|---|---|
| brand | No | brand name or profile object; OMIT to use the workspace’s saved brand | |
| count | No | how many distinct variants (default 6) | |
| product | Yes | what to advertise | |
| language | No | output language for the variant copy (e.g. Spanish) — default English |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations are all false (readOnlyHint, idempotentHint, destructiveHint all unset), so the description carries the full behavioral burden. It discloses the key trait beyond annotations: it is planning-only and renders nothing itself, which prevents an agent from expecting visual output. It also clarifies that distinct hooks/mechanics/audiences are produced. No contradiction with annotations; readOnlyHint=false is consistent with this being a plan-generating (not necessarily side-effect-free) operation.
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 primary purpose front-loaded. The pipeline to generate_image and score_ad is conveyed efficiently via the dash. Minor redundancy exists ('LLM planning only' and 'renders nothing itself' restate the same point), but there is no wasted verbiage overall.
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 planning tool with no output schema and uninformative (all-false) annotations, the description provides solid operational context: what it produces (distinct angles, hooks/mechanics/audiences, headlines, visual briefs) and how it fits the downstream pipeline. The main gap is that it never describes the return structure, which would be valuable absent an output schema, but the workflow context is otherwise sufficient 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?
Schema description coverage is 100% — all four parameters (brand, count, product, language) are already documented in the schema with their defaults and constraints. The description adds no parameter-level meaning, which is acceptable because the schema does the heavy lifting. Baseline 3 applies since the structured fields fully cover parameter semantics.
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 uses a specific, vivid verb ('Fan a brief into N DISTINCT ad angles') and names the resource and output artifacts (headlines + visual briefs). It differentiates itself from siblings by explicitly chaining to generate_image and score_ad and by stating 'LLM planning only; renders nothing itself,' which disambiguates it from render_ad and generate_image. An agent can distinguish this from plan_ad and mine_angles 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?
The description clearly implies usage — produce multiple ad-angle candidates from a brief, then hand each to generate_image and score_ad. The 'LLM planning only' clause sets a boundary for when this is the right tool (planning stage, not rendering). However, it does not explicitly name alternatives such as plan_ad or mine_angles, nor state when to prefer them, so exclusions are left implicit rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
post_editPost-production editAInspect
MECHANICAL post-production on an EXISTING rendered video (its served mp4 URL) — an ordered plan of whitelisted primitives executed by ffmpeg (+ Chrome for typeset cards) in seconds for ~2 credits flat, NO AI model, the original untouched (returns a NEW video). The lane for: append a branded end card ('add an end card with our logo and website' — ADDS its seconds, never re-renders), trim, speed (0.5-2x), mute (whole or a window), audio_gain (-20..+6 dB), fade_out, corner logo watermark, anti-AI film grain. Up to 6 ops per plan, applied in order. Brand assets (name/domain/logo/accent) load from the workspace brand automatically; override per-call if needed. NEVER use generate_video/render_ad for these mechanical asks.
| Name | Required | Description | Default |
|---|---|---|---|
| ops | Yes | the ordered edit plan (max 6 ops) | |
| accent | No | override the brand accent hex | |
| domain | No | override the brand website | |
| videoUrl | Yes | the served URL of the video to edit | |
| brandName | No | override the workspace brand name |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations are all-false flags (not read-only, not idempotent, not destructive), so the description carries most of the burden. It adds meaningful context: the operation returns a NEW video and leaves the original untouched (consistent with destructiveHint=false, and it creates output consistent with readOnlyHint=false), discloses flat cost (~2 credits), fast execution, and the explicit non-AI, non-generative nature. It does not cover failure modes, auth requirements, or delivery of the resulting video URL.
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 key distinguishing info is front-loaded ('MECHANICAL post-production on an EXISTING rendered video... NO AI model'), and every sentence carries information. However, it is one dense, run-on paragraph combining operations list, constraints, brand behavior, cost, and exclusions. Splitting the ops inventory from the routing/negative guidance would improve scannability, though 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 medium-complexity tool with 5 params fully described in the schema and no output schema, the description is fairly complete: input type (served mp4 URL), operations available, ordering/cap semantics, cost, brand override behavior, and the fact that it returns a new video. It could note how the new video is surfaced, but the bare 'returns a NEW video' plus 'get_job' sibling availability covers most agent needs.
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 the baseline is 3. The description adds some value on top: the ops are 'applied in order' with a 6-op cap (cap also in schema), and brand params (name/domain/logo/accent) auto-load from the workspace with per-call override. It explains the append_card behavior the schema partly implies. This is helpful, but it does not compensate for any missing schema coverage since none is missing.
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 first clause nails it: 'MECHANICAL post-production on an EXISTING rendered video (its served mp4 URL)' — specific verb, resource, and scope. It lists the exact whitelisted primitives (trim, speed, mute, audio_gain, fade_out, append_card, watermark, grain) and actively differentiates from generative siblings like generate_video and render_ad. An agent can immediately tell this from the video-rendering tools in the sibling list.
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 clearly defines the lane ('The lane for: append a branded end card...') with concrete example phrasing and gives an explicit negative rule: 'NEVER use generate_video/render_ad for these mechanical asks.' It does not, however, enumerate the closest mechanical cousins in the sibling list (edit_video, reframe_video, upscale_video) or state conditions that would route to them, so differentiation from those is left implicit rather than explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
post_performanceWhich hooks and subjects are getting tractionARead-onlyInspect
Aggregate this brand's published posts to answer WHICH HOOKS AND SUBJECTS WORK. Groups by hook (default), subject, channel, media format or posting hour, and reports the engagement RATE within each channel. THREE THINGS IT DELIBERATELY WILL NOT DO, and you should repeat them rather than paper over them: (1) it never sums metrics across channels — a LinkedIn impression and a TikTok view are different units, so every comparison is within one channel; (2) it SUPPRESSES a verdict below 5 measured posts and says so, because a confident recommendation from 3 posts is worse than none; (3) a post with no recorded hook (published outside Hermoso, or backfilled without a creation match) counts toward channel and format totals but never votes on which hook works. Present the finding verbatim if there is one, and the reason if there is not. Read-only, 0 credits.
| Name | Required | Description | Default |
|---|---|---|---|
| axis | No | what to group by — default hook | |
| channel | No | restrict to one channel |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, and the description reinforces that with 'Read-only'. Beyond that, the description adds significant behavioral context: it never sums metrics across channels, it suppresses verdicts below 5 posts, and it explains how posts without a recorded hook are counted. It also states it returns a `finding` or a `reason`. These details are not in the annotations and are crucial for correct interpretation of results. No contradiction exists.
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 longer than average, but every sentence earns its place. It front-loads the primary verb and purpose, then moves to a numbered list of exclusions, a presentation instruction, and a concluding note on read-only and credits. The structure is clear and purposeful; nothing is fluff. The length is justified by the tool's behavioral complexity, so it gets a 4 rather than a 5.
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 tool with no output schema, the description carefully explains what the output looks like (`finding` or `reason`) and when each appears. It covers aggregation scope, channel-scoping rules, confidence thresholds (5 posts), and data-exclusion semantics. Given the complexity of this analytic tool, the description is nearly exhaustive. An agent would know exactly what to expect and how to present results. No critical context 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 100% (both `axis` and `channel` are described). The description adds contextual meaning beyond the schema: it explains that grouping is by 'hook (default), subject, channel, media format or posting hour' (matching the enum) and clarifies that channel is meaningful because 'every comparison is within one channel'. This rationale is not in the schema and helps the agent understand why restricting by channel matters. It earns a 4 rather than a 3 because it adds interpretative 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 description states a specific verb ('Aggregate'), a resource ('this brand's published posts'), and a defined analytical goal ('which hooks and subjects work'), then enumerates the grouping axes. It clearly distinguishes itself from per-platform insight tools like meta_post_insights or x_post_metrics by framing it as a cross-channel aggregate. The purpose is unambiguous and specific, not a tautology.
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 explicitly lists three behaviors the tool deliberately will NOT do, with reasons, and instructs the agent to 'repeat them rather than paper over them'. It also gives direct presentation guidance ('Present the `finding` verbatim if there is one, and the reason if there is not') and notes the tool is read-only and costs 0 credits. This is strong usage direction, even though it does not name sibling tools, because it tells the agent how to act on the tool's output and what boundaries not to cross.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
post_to_blueskyPost to BlueskyAInspect
Publish a post to Bluesky as the connected account. Text up to 300 characters — Bluesky ALSO caps a post at 3000 UTF-8 bytes, so an emoji-heavy post can be under 300 characters and still be refused; Hermoso checks both before spending the round trip and says which limit and by how much. MEDIA: either up to 4 images (imageUrls + altText) OR one MP4 video (videoUrl + videoAlt), never both — a Bluesky post record carries a single embed and images and video are two different embed types. Video is MP4 only, up to 300MB at Bluesky's end (Hermoso can fetch up to 150MB from a URL), with optional WebVTT caption tracks; the aspect ratio is measured from the file. Bluesky requires a CONFIRMED EMAIL on the account before it will process any video — if it is unconfirmed you get a refusal saying so, and reconnecting will not help. Links in the text are made clickable automatically. LINK CARDS: Bluesky does NOT scrape links, so a URL posted bare renders as plain blue text — the client composing the post has to build the card. Hermoso builds one AUTOMATICALLY when the post has a URL and NO media: it fetches the page, uses its title/description and uploads its image as the card thumbnail. Pass linkCard:false to suppress it, or linkCard:{uri,title,description,thumbUrl} to control it (give both title and description and the page is not fetched at all). A POST CARRIES ONE EMBED, so a card and images/video cannot both ride: if you pass linkCard explicitly ALONGSIDE media the call is REFUSED by name rather than silently dropping one, and if the URL was merely in the text the MEDIA WINS and the reply says the card was skipped (the link stays clickable either way). Returns the post's public bsky.app URL. Connect at Settings ▸ Connectors ▸ Bluesky with a handle and an APP PASSWORD.
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | The post, up to 300 characters / 3000 UTF-8 bytes. | |
| langs | No | BCP-47 language tags, e.g. ['en']. | |
| account | No | WHICH connected account of this channel to post as — its @handle or id from list_connector_accounts. Needed only when the brand has more than one bluesky account connected (several and none named is refused by name, never guessed); omit when there is one. | |
| altText | No | Alt text — an ARRAY, one per image in the same order, or a single STRING to describe every image with it. WRITE ONE: Bluesky’s own lexicon makes `alt` a REQUIRED property of every image, so a post without it is undescribed by design rather than by omission, and Bluesky users expect it. No maximum length is published, so nothing is truncated. | |
| captions | No | Up to 20 WebVTT caption tracks: [{lang:'en', url:'https://…/en.vtt'}] or [{lang:'en', content:'WEBVTT\n\n00:00…'}]. Each file is capped at 20000 bytes. | |
| linkCard | No | Rich link card (`app.bsky.embed.external`). OMIT for the default (a card is built automatically when the post has a URL and no media). `false` never builds one. `true` builds one from the first URL in the text. An object {uri,title,description,thumbUrl} overrides any field — supply BOTH title and description and the page is never fetched. Cannot be combined with imageUrls/videoUrl: a post has ONE embed, so an explicit linkCard beside media is refused. | |
| videoAlt | No | Alt text describing the video, for accessibility. | |
| videoUrl | No | One public MP4 URL. Cannot be combined with imageUrls. Bluesky transcodes it, which takes a minute or two. | |
| imageUrls | No | Up to 4 public image URLs to attach. Cannot be combined with videoUrl. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations (readOnlyHint=false, idempotentHint=false, destructiveHint=false) are skeletal, and the description carries the full burden — and exceeds it. It discloses the dual 300-char/3000-byte validation performed before the round trip, the confirmed-email prerequisite where 'reconnecting will not help', the embed conflict outcomes (refusal by name vs. media-wins and card skipped), automatic link-card construction with page fetching, and the transcoding delay. This is exactly the failure-mode and side-effect context annotations cannot express.
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?
Long but appropriately dense — roughly one sentence per distinct behavior, front-loaded from core action through modes and edge cases to return value and setup. ALL-CAPS section markers (MEDIA:, LINK CARDS:, A POST CARRIES ONE EMBED) make it scannable. Minor redundancy exists ('a single embed' is stated twice and some constraints repeat schema text), but no sentence 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 9-parameter mutating tool with no output schema and sparse annotations, the description covers everything an agent needs: connection setup, prerequisites (confirmed email for video), all limits (characters, bytes, image count, video size, caption size), every conflict-resolution outcome, link-card behavior, and the return value (public bsky.app URL). The only parameter not elaborated in the description, langs, is fully covered by the schema.
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. The description still adds genuine semantics beyond the schema: the byte-limit enforcement behavior and error reporting for text, Hermoso's 150MB fetch ceiling for video (absent from the schema), and the nuanced linkCard conflict paths (explicit card + media refused; text-URL card silently skipped). It earns a 4 but not a 5 because the schema already documents most individual parameter meanings well.
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 'Publish a post to Bluesky as the connected account' — a specific verb, a specific resource, and an account-scoping qualifier. The platform name alone separates it from the many sibling post_to_* tools, and the body reinforces the purpose with platform-specific constraints (byte caps, embed types, link-card rules) that leave no ambiguity about what this tool does.
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 clear context for when to use this tool — posting to a connected Bluesky account — and provides richly explicit mode-selection guidance within it: images vs. video ('never both'), when to suppress or override a link card, and the confirmed-email requirement for video. It stops short of 5 because it never explicitly contrasts sibling posting tools, though the platform-specific name makes that selection self-evident.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
post_to_google_businessPost to Google Business ProfileAInspect
Publish a Post to the brand’s Google Business Profile — the panel that appears on Google Search and Maps for the business. Text, optionally ONE PHOTO, and a call-to-action button. Google’s Posts API accepts NO VIDEO, so pass a still image. This PUBLISHES immediately and publicly on the business listing — show the user the exact text, photo and button and get an explicit yes BEFORE calling. If the account manages several listings, call list_business_locations first and pass locationId. EVENT and OFFER posts both REQUIRE a title and a start date (Google’s rule). On an OFFER, Google IGNORES the button’s link — pass redeemOnlineUrl instead. A CALL button dials the number on the listing and takes no link. Needs Google Business Profile connected (Settings ▸ Connectors ▸ Google Business Profile).
| Name | Required | Description | Default |
|---|---|---|---|
| hook | No | WHAT ANGLE THIS POST IS BUILT ON — the single most valuable field here, and the only moment it can ever be recorded. post_performance groups on it to answer "which hooks work", and it needs 5 posts sharing ONE hook before it will call anything a winner, so REUSE THE SAME WORDING across a campaign instead of rephrasing it every time. Best of all, pass a hook id from list_hooks (e.g. "direct_callout", "mid_problem", "before_after") — those fold onto a stable key however they are spelled, so a whole brand accumulates evidence on one row. Your own wording is fine too; it just only groups when you repeat it exactly. Omitting it means this post can never vote on which hook works. | |
| link | No | the URL the button opens — not for CALL, and ignored on an OFFER | |
| title | No | headline — REQUIRED for EVENT and OFFER | |
| endDate | No | YYYY-MM-DD, defaults to startDate | |
| subject | No | WHAT THIS POST IS ABOUT — the product, feature, offer or theme (e.g. "winter coat", "free trial", "founder story"). The second grouping axis in post_performance. Same rule as hook: reuse the exact wording so posts about one subject land in one group. | |
| summary | No | the body text of the Post | |
| imageUrl | No | a Hermoso render image URL (or an upload_file url) to show on the Post | |
| startDate | No | YYYY-MM-DD — REQUIRED for EVENT and OFFER | |
| topicType | No | default STANDARD | |
| actionType | No | the button on the Post | |
| couponCode | No | OFFER only | |
| locationId | No | which listing, e.g. 'locations/123' from list_business_locations — only needed when the account manages more than one | |
| languageCode | No | BCP-47 language of the Post, default 'en' | |
| redeemOnlineUrl | No | OFFER only — this is the link Google actually uses on an offer | |
| termsConditions | No | OFFER only |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations are minimal (readOnlyHint false, destructiveHint false, etc.), but the description adds critical behavioral context: it publishes immediately and publicly, requires explicit user confirmation before calling, and explains platform quirks like Google ignoring the button link on OFFER posts and CALL buttons dialing the listing's number. These details are beyond the annotations and are essential for safe, correct usage.
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 dense but well-organized: it leads with the core action, then constraints (no video, immediate publish, consent), then usage hints (locationId, connection), then platform-specific rules. Every sentence contributes new information; it is lengthy but warranted given the tool's complexity. It is not tautological or 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?
For a 15-parameter publishing tool with no output schema, the description covers essentials: prerequisites (connection, locationId), behavioral caveats (immediate public publish, confirmation), special cases (event/offer requirements, offer link ignoring, call button), and points to schema for parameter details. Nothing an agent needs to call it correctly is omitted.
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 many parameters have rich descriptions (e.g., hook explains grouping semantics). The tool description supplements this by clarifying cross-parameter constraints: EVENT/OFFER require title and startDate, OFFER uses redeemOnlineUrl instead of link, and CALL ignores link. This adds meaningful meaning beyond the schema, though it does not enumerate every parameter—that is already handled by 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?
The description opens with a specific verb and resource: 'Publish a Post to the brand’s Google Business Profile'. It clearly distinguishes this from other post_to_* siblings by naming the platform (Google Search and Maps) and stating it accepts only text, one photo, and a CTA button. The 'NO VIDEO' note further narrows scope, making the tool's purpose unmistakable.
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 concrete usage guidance: call list_business_locations first when managing multiple listings, requires a connected Google Business Profile (with Settings path), and specifies that EVENT/OFFER posts need a title and start date. It does not explicitly name alternative tools for other platforms, but given the tool name and the ecosystem, this is implicitly clear. The guidance is thorough enough to route an agent correctly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
post_to_linkedinPublish to LinkedInAInspect
Publish a post to the user’s connected LinkedIn profile — text, and optionally an image (pass its served URL as imageUrl). The image does NOT have to be something Hermoso generated: LinkedIn is served the bytes from us, so the URL must be Hermoso-hosted, and upload_file turns ANY file the user already has into exactly that. This PUBLISHES immediately and PUBLICLY — ALWAYS show the user the exact text and get an explicit yes BEFORE calling. Needs a connected LinkedIn account (Settings ▸ Connectors ▸ LinkedIn).
| Name | Required | Description | Default |
|---|---|---|---|
| hook | No | WHAT ANGLE THIS POST IS BUILT ON — the single most valuable field here, and the only moment it can ever be recorded. post_performance groups on it to answer "which hooks work", and it needs 5 posts sharing ONE hook before it will call anything a winner, so REUSE THE SAME WORDING across a campaign instead of rephrasing it every time. Best of all, pass a hook id from list_hooks (e.g. "direct_callout", "mid_problem", "before_after") — those fold onto a stable key however they are spelled, so a whole brand accumulates evidence on one row. Your own wording is fine too; it just only groups when you repeat it exactly. Omitting it means this post can never vote on which hook works. | |
| text | Yes | the post text | |
| subject | No | WHAT THIS POST IS ABOUT — the product, feature, offer or theme (e.g. "winter coat", "free trial", "founder story"). The second grouping axis in post_performance. Same rule as hook: reuse the exact wording so posts about one subject land in one group. | |
| imageUrl | No | a Hermoso-hosted image URL to attach (≤12MB) — a Hermoso render, or ANY file of the user’s own put through upload_file first. An arbitrary external host is refused (we fetch the bytes ourselves). | |
| imageUrls | No | A CAROUSEL IS NOT AVAILABLE ON A PERSONAL PROFILE — LinkedIn's organic multi-image post publishes from a COMPANY PAGE. Passing several here is refused by name rather than posting slide 1; use post_to_linkedin_page instead. | |
| visibility | No | default PUBLIC | |
| allowDuplicate | No | post it even though an identical post was just made or attempted. Only pass this when the user genuinely wants the same thing posted twice, or when you have LOOKED at the account and confirmed a timed-out attempt did not land. | |
| idempotencyKey | No | SAFE RETRIES. Publishing can take minutes (a video upload, a carousel of ten slides) and a transport can time out while the post SUCCEEDS — retrying blind is how the same thing gets posted twice. Pass any stable string here and a repeat of the SAME publish returns the ORIGINAL post id instead of posting again (24h). You do not have to: an identical publish is auto-recognised for 10 minutes anyway. If a call times out or errors ambiguously, CALL AGAIN WITH THE SAME KEY — that is the safe move, and it will either report the original post or publish it for the first time. It never posts twice. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint=false and other simple flags. The description adds critical behavioral context: the post is published immediately and publicly, requires explicit user consent, and explains that the image must be Hermoso-hosted (upload_file converts any user file). It also covers idempotency behavior for retries and duplicate detection, providing transparency beyond 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 description is dense but every sentence earns its place: it front-loads the critical warning about immediate public publishing, then explains image hosting, duplication prevention, and prerequisites without redundancy. It uses clear formatting (capitalized warnings, explicit instructions) and avoids fluff, making it efficient and scannable.
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 8 parameters with no output schema, the description covers all necessary context: prerequisites (connected account), key behaviors (immediate publishing, public visibility, user confirmation), image constraints, and safe retry mechanisms. Nothing an agent needs to call the tool correctly is missing, and the rich schema descriptions complement the text.
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 detailed descriptions for each parameter including hook, text, subject, imageUrl, imageUrls, visibility, allowDuplicate, and idempotencyKey. The description itself adds extra context for imageUrl (must be Hermoso-hosted, upload_file converts) and idempotencyKey (retry safety), but most parameter meaning is already in the schema. Since the schema carries the heavy load and the description enriches a few, a 4 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 states a precise action: 'Publish a post to the user’s connected LinkedIn profile' with clear scope (text, optional image). It distinguishes from the sibling post_to_linkedin_page by explicitly mentioning that a carousel requires a company page and directing to that alternative, so an agent can immediately tell which tool to use.
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?
Provides explicit when-to-use and when-not-to-use guidance: requires a connected LinkedIn account (with Settings path), warns about immediate public publishing and mandates user confirmation. It also names the alternative post_to_linkedin_page for carousel images, giving a clear exclusion. No other tool alternatives are needed since the purpose is specific.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
post_to_linkedin_pagePublish to a LinkedIn company PageAInspect
Publish a post to one of the user’s LinkedIn COMPANY PAGES — text, plus optionally an image, a video, a 2–20 image CAROUSEL (LinkedIn calls it a MultiImage post; pass the slides in order as imageUrls[]), or a LINK POST with a real preview card (linkUrl). USE linkUrl WHENEVER THE POINT OF THE POST IS A LINK: LinkedIn disables URL scraping for API partners, so a url sitting in the text renders as plain text with no card, and the card’s title, description and image only exist if you pass linkTitle / linkDescription / linkThumbnailUrl — read them off the page and supply them. The media need not be a Hermoso render — it must be Hermoso-HOSTED because we upload the bytes to LinkedIn ourselves, and upload_file turns ANY file the user already has into such a URL. ORGANIC CAROUSELS ARE COMPANY-PAGE ONLY — a personal profile cannot publish one and is refused by name, so send a deck here rather than to post_to_linkedin. This is a DIFFERENT thing from post_to_linkedin, which publishes to the person’s own profile: pick the one the user actually asked for and never substitute. organizationId comes from list_linkedin_pages; omit it only when the account administers exactly one Page. This PUBLISHES immediately and PUBLICLY — ALWAYS show the user the exact text and get an explicit yes BEFORE calling. A VIDEO POST CAN CARRY CAPTIONS AND ITS OWN COVER, and both are attached only during the upload: pass captionsSrt (SubRip content — LinkedIn is watched with the sound off) and videoThumbnailUrl (otherwise LinkedIn picks a frame for you). LinkedIn does NOT allow the image, video, captions or thumbnail of a published post to be swapped afterwards, so get all of that right first (the copy can still be edited with manage_linkedin_post).
| Name | Required | Description | Default |
|---|---|---|---|
| hook | No | WHAT ANGLE THIS POST IS BUILT ON — the single most valuable field here, and the only moment it can ever be recorded. post_performance groups on it to answer "which hooks work", and it needs 5 posts sharing ONE hook before it will call anything a winner, so REUSE THE SAME WORDING across a campaign instead of rephrasing it every time. Best of all, pass a hook id from list_hooks (e.g. "direct_callout", "mid_problem", "before_after") — those fold onto a stable key however they are spelled, so a whole brand accumulates evidence on one row. Your own wording is fine too; it just only groups when you repeat it exactly. Omitting it means this post can never vote on which hook works. | |
| text | Yes | the post text | |
| title | No | video title | |
| altText | No | accessibility alt text (max 4086 characters, ~120 recommended). A STRING describes every image; an ARRAY describes each slide of a multi-image post separately, in slide order — LinkedIn stores altText per image, and their own sample request carries a different one on each. Not available on a PERSONAL-profile post: LinkedIn’s member posting API has no alt-text field at all. | |
| linkUrl | No | publish a LINK POST — LinkedIn renders a real preview card for this URL instead of leaving a bare link in the text. Mutually exclusive with imageUrl / videoUrl / imageUrls: LinkedIn’s content field is a union, so combining them is refused by name rather than one being dropped. | |
| subject | No | WHAT THIS POST IS ABOUT — the product, feature, offer or theme (e.g. "winter coat", "free trial", "founder story"). The second grouping axis in post_performance. Same rule as hook: reuse the exact wording so posts about one subject land in one group. | |
| imageUrl | No | a Hermoso-hosted image URL — a render (list_library), or ANY image of the user’s own passed through upload_file first. An arbitrary external host is refused. | |
| videoUrl | No | a Hermoso-hosted video URL — a render, or the user’s own footage via upload_file. LinkedIn processes it before publishing, which takes a minute. | |
| imageUrls | No | CAROUSEL — an ORDERED list of image (and, where the channel allows, video) URLs published as ONE post the viewer swipes through. THIS IS NOT “post several” — it is a single post with several slides, which is what a multi-slide creative (a listicle, a “1/6 · SWIPE” deck) actually needs; publishing only its first slide tells the viewer to swipe at something that cannot. The ORDER is the product. Limits per channel: Instagram 2–10 (images, videos or a mix), Threads 2–20 (mix allowed), Facebook 2+ (Meta publishes no documented maximum; Hermoso caps the upload fan-out at 30 and says so), LinkedIn company Pages 2–20 (images only), Pinterest 2–5 (images only), TikTok up to 35. One url here is simply an ordinary single post. Anything a channel cannot do is REFUSED with the real reason — nothing is ever quietly downgraded to one slide. | |
| linkTitle | No | the headline ON the preview card. LINKEDIN NEVER SCRAPES THE PAGE — their Posts API disables URL scraping for API partners outright — so if you do not pass this the card renders UNLABELLED. Fetch the page’s own title and pass it. | |
| visibility | No | default PUBLIC | |
| captionsSrt | No | CLOSED CAPTIONS for a videoUrl post — the SubRip (.srt) CONTENT itself, cue numbers and `00:00:00,000 --> 00:00:02,000` timing lines included, NOT a URL and NOT the plain script (a file with no timings is refused, because LinkedIn would accept it and then silently never show it). Most of LinkedIn is watched with the sound off, so an uncaptioned video is one most of the feed never hears. LinkedIn allows ONE caption file per video and ENGLISH ONLY; it can be attached only WHILE the video is uploaded, never added to a published post; and it is processed asynchronously, so the reply confirms it was UPLOADED and never that it is visible yet. Requires videoUrl — passing it on an image, carousel or link post is refused by name. | |
| allowDuplicate | No | post it even though an identical post was just made or attempted. Only pass this when the user genuinely wants the same thing posted twice, or when you have LOOKED at the account and confirmed a timed-out attempt did not land. | |
| idempotencyKey | No | SAFE RETRIES. Publishing can take minutes (a video upload, a carousel of ten slides) and a transport can time out while the post SUCCEEDS — retrying blind is how the same thing gets posted twice. Pass any stable string here and a repeat of the SAME publish returns the ORIGINAL post id instead of posting again (24h). You do not have to: an identical publish is auto-recognised for 10 minutes anyway. If a call times out or errors ambiguously, CALL AGAIN WITH THE SAME KEY — that is the safe move, and it will either report the original post or publish it for the first time. It never posts twice. | |
| organizationId | No | numeric Page id from list_linkedin_pages | |
| linkDescription | No | the sub-line on the preview card. Same rule as linkTitle: absent means blank, because LinkedIn will not fetch it. | |
| linkThumbnailUrl | No | a Hermoso-hosted image used as the card’s picture (uploaded to LinkedIn for you). Without it the card has no image. | |
| videoThumbnailUrl | No | the COVER IMAGE for a videoUrl post — a Hermoso-hosted image (a render, or any picture of the user’s via upload_file). Without it LinkedIn adds a system-generated thumbnail, which on an ad is usually whatever the first frame happens to be. Like captions this can only be set WHILE the video is uploaded, never afterwards. Requires videoUrl. This is NOT linkThumbnailUrl, which is the picture on a link-preview card. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the sparse annotations (readOnlyHint false, openWorldHint true, idempotentHint false, destructiveHint false), the description discloses crucial behavioral traits: it 'PUBLISHES immediately and PUBLICLY' and mandates user confirmation before calling; it explains that media must be Hermoso-hosted and uploaded to LinkedIn; it details the irreversibility of media attachments (image/video/captions/thumbnail cannot be swapped after publishing) while noting copy can be edited via manage_linkedin_post; and it explains link-preview behavior (LinkedIn never scrapes). These are exactly the kind of behavioral caveats an agent needs and the annotations do not provide. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but dense, with every sentence earning its place. It front-loads the core purpose and the most critical decision rules (link vs. text, sibling distinction, public nature) before diving into content-type specifics. The structure leads with the action, then the key caveats, then parameter-level detail, and ends with an alert about immutability. No redundant or filler text; it is appropriately verbose for a tool with 18 parameters.
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 tool with 18 parameters and no output schema, the description covers all critical usage dimensions: media constraints (hosting, mutual exclusion), link-preview requirements, organization selection, idempotency/safe retries, captions and thumbnails, alt text, visibility defaults, duplicate handling, and the distinction from the sibling. It even hints at response behavior (e.g., 'the reply confirms it was UPLOADED and never that it is visible yet' for captions, and idempotent retries return the original post id). Nothing essential is missing for an agent 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?
Although schema description coverage is 100%, the description adds substantial semantics beyond each parameter's own text. It explains cross-parameter relationships (linkUrl is mutually exclusive with image/video/carousel; captionsSrt requires videoUrl; videoThumbnailUrl is distinct from linkThumbnailUrl), prescribes how to source parameter values (linkTitle/linkDescription/linkThumbnailUrl must be read from the page; organizationId comes from list_linkedin_pages; media must be Hermoso-hosted via upload_file), and clarifies the meaning of array ordering for carousels. This goes well beyond what the schema descriptions alone provide, giving the agent actionable guidance on how to fill each field correctly.
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 verb and resource: 'Publish a post to one of the user’s LinkedIn COMPANY PAGES' and enumerates concrete content types (text, image, video, carousel, link post). It explicitly contrasts with the sibling post_to_linkedin ('which publishes to the person’s own profile'), naming the alternative and the selection condition. No ambiguity remains about what this tool does or how it differs from its 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?
The description gives explicit when-to-use guidance: 'USE linkUrl WHENEVER THE POINT OF THE POST IS A LINK' with the rationale (LinkedIn disables URL scraping), and it warns against using this tool for personal-profile carousels ('ORGANIC CAROUSELS ARE COMPANY-PAGE ONLY — a personal profile cannot publish one and is refused by name'). It also instructs the agent to pick the correct sibling 'and never substitute.' These are clear decision criteria with no reliance on inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
post_to_metaPost to Facebook, Instagram or ThreadsAInspect
Publish to a connected Facebook Page, its linked Instagram, OR the brand’s Threads account — text/link/image/VIDEO/CAROUSEL. A MULTI-SLIDE creative is a CAROUSEL, not several posts: pass the slides in order as imageUrls[] and they publish as ONE swipeable post (Instagram album, Threads carousel, Facebook multi-photo post). Never publish slide 1 of a deck on its own — the creative tells the viewer to swipe. target:"facebook" (default) posts to the Page; target:"instagram" publishes a photo or Reel to the linked IG business account (needs an image or video); target:"threads" posts to the connected Threads account (text, image, or video). Works with ANY media — a finished Hermoso ad OR an arbitrary user file: imageUrl/videoUrl accept a public https URL, a data: URI, or a Hermoso /generated path; for a LOCAL file (e.g. on the user’s desktop) call upload_file first and pass the url it returns. INSTAGRAM COLLAB: pass collaborators (up to 3 usernames) to invite other accounts to CO-AUTHOR the post — it then shows on their profile too once they accept, which is the reach play behind every creator partnership. This PUBLISHES immediately — confirm the copy + media with the user first. Needs a connected Meta account (Settings ▸ Connectors ▸ Meta) with posting permission; Threads needs its own connection.
| Name | Required | Description | Default |
|---|---|---|---|
| hook | No | WHAT ANGLE THIS POST IS BUILT ON — the single most valuable field here, and the only moment it can ever be recorded. post_performance groups on it to answer "which hooks work", and it needs 5 posts sharing ONE hook before it will call anything a winner, so REUSE THE SAME WORDING across a campaign instead of rephrasing it every time. Best of all, pass a hook id from list_hooks (e.g. "direct_callout", "mid_problem", "before_after") — those fold onto a stable key however they are spelled, so a whole brand accumulates evidence on one row. Your own wording is fine too; it just only groups when you repeat it exactly. Omitting it means this post can never vote on which hook works. | |
| link | No | a URL to attach (FB text post only) | |
| async | No | publish in the BACKGROUND and return a job id to poll with get_job, instead of waiting. USE THIS FOR VIDEO: a Facebook or Instagram video publish routinely outlives an agent transport, and a timeout on the synchronous path leaves you unable to tell whether the post is live. With async:true nothing can time out — the job reports the post id and url when it lands. | |
| pageId | No | target Page id (from list_meta_pages); omit = first Page | |
| target | No | default facebook; instagram → the Page’s linked IG; threads → the brand’s connected Threads account | |
| account | No | WHICH Instagram account when target is instagram and the brand has several — Page-linked and Instagram Login accounts alike; an @username or id from list_connector_accounts("instagram"). Several and none named is refused by name; omit when there is one. | |
| altText | No | ACCESSIBILITY — the description screen readers announce, and what the platform otherwise auto-generates badly or not at all. Describe what is actually IN the picture, never the caption. ONE STRING describes the picture; on a CAROUSEL it describes EVERY slide. Pass an ARRAY of strings instead to describe each slide separately, aligned to the slide order — that is strictly better on a multi-slide post, because one sentence read out over six different pictures is wrong for five of them. More descriptions than pictures is refused rather than dropped. WHERE IT LANDS, per Meta’s own docs: INSTAGRAM image posts and the IMAGE slides of an Instagram carousel (up to 1000 characters; dropped rather than sent on a Reel or a video slide, which Meta do not support); FACEBOOK Page photos including every photo of an album, via alt_text_custom (Meta publish no length for it, so nothing is truncated); THREADS on a single-image or single-video post ONLY — Meta document no way to attach alt text to a Threads CAROUSEL slide, so a Threads carousel publishes undescribed and the reply says so rather than risking the whole post on a guess. (Meta’s AI disclosure defaults from PROVENANCE: a Hermoso render is declared is_ai_generated; media that came through upload_file or an external URL, i.e. the user’s own photos or footage, is NOT. Pass `aiGenerated` to force it either way.) | |
| message | No | post text / caption | |
| subject | No | WHAT THIS POST IS ABOUT — the product, feature, offer or theme (e.g. "winter coat", "free trial", "founder story"). The second grouping axis in post_performance. Same rule as hook: reuse the exact wording so posts about one subject land in one group. | |
| imageUrl | No | public https URL, a data: URI, or a Hermoso /generated path (upload_file gives you one for a local file) | |
| topicTag | No | THREADS ONLY — one topic tag for discovery, 1–50 characters. A leading # is stripped for you; Threads refuses "." and "&". | |
| videoUrl | No | public https URL, data: URI, or /generated path — FB video post / IG Reel | |
| imageUrls | No | CAROUSEL — an ORDERED list of image (and, where the channel allows, video) URLs published as ONE post the viewer swipes through. THIS IS NOT “post several” — it is a single post with several slides, which is what a multi-slide creative (a listicle, a “1/6 · SWIPE” deck) actually needs; publishing only its first slide tells the viewer to swipe at something that cannot. The ORDER is the product. Limits per channel: Instagram 2–10 (images, videos or a mix), Threads 2–20 (mix allowed), Facebook 2+ (Meta publishes no documented maximum; Hermoso caps the upload fan-out at 30 and says so), LinkedIn company Pages 2–20 (images only), Pinterest 2–5 (images only), TikTok up to 35. One url here is simply an ordinary single post. Anything a channel cannot do is REFUSED with the real reason — nothing is ever quietly downgraded to one slide. | |
| trialReel | No | INSTAGRAM TRIAL REEL — publish this Reel to NON-FOLLOWERS ONLY at first, so a hook can be tested on a cold audience without spending it on the people who already follow the brand. Instagram then shows it to followers only if it graduates. MANUAL = the creator graduates it by hand in the Instagram app; SS_PERFORMANCE = Instagram graduates it automatically if it performs well. REELS ONLY and INSTAGRAM ONLY: an image, a carousel, a Facebook post or a Threads post is REFUSED BY NAME rather than quietly published as an ordinary post — a trial that silently goes to every follower is the exact opposite of what was asked for. Omit it for a normal Reel. | |
| locationId | No | Threads only — a place id from search_threads_locations, to geotag the post to a physical location (restaurant, storefront) | |
| scheduleAt | No | FACEBOOK ONLY — schedule instead of posting now. ISO timestamp (2026-08-01T09:00:00Z) or unix seconds; must be 10 minutes to 30 days ahead. Facebook holds the post and publishes it at that time, so nothing has to stay running on our side. Instagram and Threads have NO scheduling in Meta’s API — passing this for them is refused rather than silently posted immediately. | |
| aiGenerated | No | INSTAGRAM / FACEBOOK REEL — Meta’s is_ai_generated self-disclosure. OMIT IT and Hermoso decides from provenance: a Hermoso render is declared, media that came through upload_file or from an external URL (the user’s own photographs or footage) is NOT — a real photo must never carry Instagram’s “AI info” label. Pass true or false only to override: false strips the label from something Hermoso would otherwise declare, true declares a render the user uploaded themselves. | |
| productTags | No | INSTAGRAM SHOPPING — make the post SHOPPABLE by tagging products from the brand’s own catalog; tapping a tag opens the product’s price sheet inside Instagram. Instagram only. ON A PHOTO each tag is {product_id, x, y}, where x and y are FRACTIONS of the image from 0.0 (left/top) to 1.0 (right/bottom) — 0.5,0.5 is the middle — and BOTH are required, max 20. ON A REEL it is {product_id} ALONE with no coordinates, max 30. ON A CAROUSEL it is an array PER SLIDE ([[{…}], [], [{…}]]) because Instagram tags each slide’s own container, max 5 per slide and 20 across the post. Ids come from search_instagram_shopping_products; call list_instagram_shopping_catalogs FIRST, because tagging needs an APPROVED Instagram Shop and without one this fails after the media is already uploaded. A tag whose product is not “approved” is stored and shown to nobody. | |
| quotePostId | No | THREADS ONLY — the id of a post to QUOTE. A quote post is a distinct post type, not a formatting option. | |
| countryCodes | No | THREADS ONLY — restrict the post to these ISO 3166-1 alpha-2 countries. ⚠ This is an ALLOWLIST, so the post becomes INVISIBLE in every country not named — it narrows reach, it does not target. | |
| replyControl | No | THREADS ONLY — who may reply. Default is everyone. | |
| collaborators | No | INSTAGRAM COLLAB — up to 3 Instagram usernames invited to CO-AUTHOR this post. Once one accepts, the post appears on THEIR profile too, with both handles in the header and the likes and comments shared — it is how a brand reaches a creator’s audience without paying for placement, and it is the single most-asked thing a scheduler normally cannot do. Pass handles only ("hermosoai"), not profile links; a leading @ is fine. INSTAGRAM ONLY — Facebook and Threads have no collab post at all and are refused BY NAME rather than silently dropping the co-authors — and never on a Story. AN INVITE IS NOT A CO-POST: publishing SENDS a request the other account must accept in their Instagram notifications, and until they do the post is on this brand’s profile ALONE; they may also decline, and Instagram sends no notification either way. So never report the post as live on both accounts — read the invite status back out of the reply, and use instagram_collaborators later to find out whether they accepted. | |
| allowDuplicate | No | post it even though an identical post was just made or attempted. Only pass this when the user genuinely wants the same thing posted twice, or when you have LOOKED at the account and confirmed a timed-out attempt did not land. | |
| idempotencyKey | No | SAFE RETRIES. Publishing can take minutes (a video upload, a carousel of ten slides) and a transport can time out while the post SUCCEEDS — retrying blind is how the same thing gets posted twice. Pass any stable string here and a repeat of the SAME publish returns the ORIGINAL post id instead of posting again (24h). You do not have to: an identical publish is auto-recognised for 10 minutes anyway. If a call times out or errors ambiguously, CALL AGAIN WITH THE SAME KEY — that is the safe move, and it will either report the original post or publish it for the first time. It never posts twice. | |
| linkAttachment | No | THREADS TEXT POSTS ONLY — a full http(s) URL rendered as a clickable link card. This is how a Threads post carries a destination at all; without it a link is just text. Meta allows at most 5 links per post and refuses a link attachment on a post that also carries an image or video, so Hermoso refuses that combination up front rather than letting Meta silently drop it. | |
| crossreshareToIg | No | THREADS ONLY — ALSO share this Threads post to the linked Instagram account AS A STORY (not a feed post), in the same publish. NOT available on a Threads CAROUSEL, which is refused by name rather than silently dropped. THERE IS NO CONFIRMATION: Threads returns no field saying whether the Story was created, so report it as REQUESTED and tell the user to check their Instagram Stories — never that it is live. | |
| crossreshareDarkMode | No | THREADS ONLY — render that Instagram Story in dark mode. Only meaningful alongside crossreshareToIg; on its own it is refused rather than silently ignored, because a parameter that never reaches the wire must not look accepted. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the sparse annotations, the description discloses heavy behavioral context: publishing is immediate ('PUBLISHES immediately — confirm the copy + media with the user first'), auth is required ('Needs a connected Meta account... with posting permission; Threads needs its own connection'), and reply semantics are covered (crossreshareToIg 'returns no field saying whether the Story was created' so report it as REQUESTED). It also details refusal-by-name behaviors, 10-minute duplicate auto-detection, the 24h idempotencyKey window, and timeout-safe async video publishing — all beyond what readOnlyHint:false and idempotentHint:false convey, and nothing contradicts 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 description is front-loaded with the core purpose, and each subsequent sentence carries operational value — remarkable for a 27-parameter, 3-platform tool. It is, however, a single dense wall of text, and the collaborators/co-author explanation and the AI-disclosure provenance note are each duplicated almost verbatim in the corresponding parameter descriptions. The main description could be trimmed by roughly 15% 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 tool with 27 optional parameters, three platforms, no output schema, and no required fields, the description covers the critical operational surface: prerequisites, per-platform refusals, immediate-publish warning, async behavior, duplicate protection, and return semantics (post id, job id, invite status read back from the reply). The only gap is a consolidated statement of the return payload shape, but the description references post id, url, job id, and invite status in context, which is sufficient for an agent to invoke and interpret results 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 100%, so the baseline is 3, but the parameter descriptions go far beyond naming: hook explains grouping mechanics and the 5-post evidence threshold, scheduleAt states the 10-minute-to-30-day window, altText specifies where Meta drops or truncates per platform, imageUrls gives per-channel slide limits, and productTags explains coordinate fractions and the approved-shop failure mode. The description also adds cross-parameter constraints (crossreshareDarkMode refused without crossreshareToIg, linkAttachment refused on image/video posts) that the JSON schema alone cannot express.
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 opens with a specific verb and resource — 'Publish to a connected Facebook Page, its linked Instagram, OR the brand's Threads account' — and enumerates the content types (text/link/image/VIDEO/CAROUSEL). It names all three Meta targets explicitly, which distinguishes it from the numerous post_to_* siblings (LinkedIn, X, Bluesky, Telegram, Pinterest, YouTube, TikTok) by platform coverage alone. The internal target routing (facebook default, instagram, threads) further clarifies exactly what the tool does.
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 clear per-target conditions — instagram needs an image or video, scheduleAt is Facebook-only, Threads-only features are enumerated — and names one external alternative ('call upload_file first' for local files). It warns to confirm copy and media before publishing and states the Meta connector prerequisite. However, it never explicitly routes agents away from this tool toward sibling post tools for non-Meta platforms, so exclusion guidance is implied rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
post_to_pinterestCreate a PinAInspect
Create a Pin on one of the user’s Pinterest boards from any finished visual they have — image, video, or a 2–5 slide CAROUSEL (pass the slides in order as imageUrls[] and Pinterest publishes one swipeable Pin). Title, description and destination link ride along. The link is what makes a Pin drive traffic, so ask for it rather than omitting it, and the description is the text Pinterest search actually reads. boardId is REQUIRED: call list_pinterest_boards first and let the user choose. This PUBLISHES to their public profile — confirm the board, title and link before calling. Video Pins take a minute or two while Pinterest ingests the file. Needs Pinterest connected (Settings ▸ Connectors ▸ Pinterest).
| Name | Required | Description | Default |
|---|---|---|---|
| hook | No | WHAT ANGLE THIS POST IS BUILT ON — the single most valuable field here, and the only moment it can ever be recorded. post_performance groups on it to answer "which hooks work", and it needs 5 posts sharing ONE hook before it will call anything a winner, so REUSE THE SAME WORDING across a campaign instead of rephrasing it every time. Best of all, pass a hook id from list_hooks (e.g. "direct_callout", "mid_problem", "before_after") — those fold onto a stable key however they are spelled, so a whole brand accumulates evidence on one row. Your own wording is fine too; it just only groups when you repeat it exactly. Omitting it means this post can never vote on which hook works. | |
| link | No | destination URL the Pin clicks through to | |
| title | No | Pin title, max 100 characters | |
| account | No | WHICH connected account of this channel to post as — its @handle or id from list_connector_accounts. Needed only when the brand has more than one pinterest account connected (several and none named is refused by name, never guessed); omit when there is one. | |
| altText | No | accessibility alt text, max 500 characters. PIN-LEVEL: Pinterest’s API has no per-item alt text at all, so on a CAROUSEL the FIRST description is used for the whole Pin and the reply states that the others were not sent. | |
| boardId | Yes | numeric board id from list_pinterest_boards — the user picks it, never guess | |
| subject | No | WHAT THIS POST IS ABOUT — the product, feature, offer or theme (e.g. "winter coat", "free trial", "founder story"). The second grouping axis in post_performance. Same rule as hook: reuse the exact wording so posts about one subject land in one group. | |
| imageUrl | No | a Hermoso render image URL (or an upload_file url) | |
| videoUrl | No | a Hermoso render video URL — takes 1–2 minutes to ingest | |
| imageUrls | No | CAROUSEL — an ORDERED list of image (and, where the channel allows, video) URLs published as ONE post the viewer swipes through. THIS IS NOT “post several” — it is a single post with several slides, which is what a multi-slide creative (a listicle, a “1/6 · SWIPE” deck) actually needs; publishing only its first slide tells the viewer to swipe at something that cannot. The ORDER is the product. Limits per channel: Instagram 2–10 (images, videos or a mix), Threads 2–20 (mix allowed), Facebook 2+ (Meta publishes no documented maximum; Hermoso caps the upload fan-out at 30 and says so), LinkedIn company Pages 2–20 (images only), Pinterest 2–5 (images only), TikTok up to 35. One url here is simply an ordinary single post. Anything a channel cannot do is REFUSED with the real reason — nothing is ever quietly downgraded to one slide. | |
| slideText | No | PINTEREST CAROUSEL ONLY — per-slide title, description and destination LINK, one object per slide in slide order. This is the ONLY genuine per-slide caption on any channel Hermoso publishes to: slide 4 can send people to the product ON slide 4, where every other platform gives a carousel one shared caption. Omit any field to leave it unset; the Pin’s own title/description/link still describe the Pin as a whole. Pinterest publishes no length limit on these, so nothing is truncated. More entries than slides is refused rather than dropped. | |
| description | No | Pin description, max 800 characters — this is what Pinterest search reads | |
| coverImageUrl | No | video Pins only — a render to use as the cover frame | |
| allowDuplicate | No | post it even though an identical post was just made or attempted. Only pass this when the user genuinely wants the same thing posted twice, or when you have LOOKED at the account and confirmed a timed-out attempt did not land. | |
| boardSectionId | No | optional section within the board | |
| idempotencyKey | No | SAFE RETRIES. Publishing can take minutes (a video upload, a carousel of ten slides) and a transport can time out while the post SUCCEEDS — retrying blind is how the same thing gets posted twice. Pass any stable string here and a repeat of the SAME publish returns the ORIGINAL post id instead of posting again (24h). You do not have to: an identical publish is auto-recognised for 10 minutes anyway. If a call times out or errors ambiguously, CALL AGAIN WITH THE SAME KEY — that is the safe move, and it will either report the original post or publish it for the first time. It never posts twice. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations (readOnlyHint=false, idempotentHint=false, destructiveHint=false), the description discloses rich behavior: 'This PUBLISHES to their public profile' with a confirm-before-calling warning, video ingest latency of 1–2 minutes, carousel slides publishing as ONE swipeable Pin, and the connector prerequisite. The schema reinforces this with Pinterest API specifics (no per-item alt text, first description used). Nothing about the description contradicts 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?
Approximately five dense sentences, front-loaded with the core action, then carousel mechanics, link/description guidance, boardId requirement, publish warning, latency, and connector prerequisite in descending order of importance. Every sentence earns its place for a 16-parameter tool, and no content is redundant with structured fields.
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 high-complexity tool (16 params, multi-media, carousel, idempotency), the description covers the critical operational contexts: what it publishes, prerequisites, user-choice workflow, confirmation requirement, and latency. The one gap is that no output schema exists and the description never states the return value directly (though the schema hints at replies, e.g., 'the reply states that the others were not sent' and idempotencyKey 'returns the ORIGINAL post id'). Minor, but worth noting.
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 the schema's parameter descriptions are exceptionally detailed (hook grouping semantics, idempotencyKey retry behavior, carousel order and per-channel limits, slideText behavior). The tool description adds only marginal parameter value on top — emphasizing that link should be asked for and that boardId requires a prior list_pinterest_boards call — which is appropriate but does not meaningfully exceed the schema-driven baseline of 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?
The description states the specific verb and resource — 'Create a Pin on one of the user's Pinterest boards' — and details the supported media forms (image, video, 2–5 slide CAROUSEL). It clearly differentiates from the many sibling post_to_* tools by naming Pinterest and its unique mechanics (boardId selection, carousel-as-one-Pin). The title 'Create a Pin' and name post_to_pinterest are consistent with the stated action.
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 explicit operational context: boardId is REQUIRED, call list_pinterest_boards first and let the user choose, Pinterest must be connected (Settings ▸ Connectors ▸ Pinterest), and the user should confirm the board, title, and link before publishing. It also advises to ask for the link rather than omit it. It does not explicitly name alternatives or say when not to use this tool versus other post_to_* siblings, though channel routing is largely self-evident from the name.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
post_to_telegramPost to TelegramAInspect
Publish to a Telegram channel, group or chat as the brand's own bot. WHICH CHAT IS ALWAYS REQUIRED AND IS NEVER GUESSED: pass chatId as the public channel's @username (e.g. @hermosoai) or its numeric id (a group is negative; a supergroup or channel starts with -100). There is no default and there cannot be one — the Telegram Bot API publishes no method that lists the chats a bot belongs to, so Hermoso genuinely cannot know them. list_telegram_chats reports the chats that have MESSAGED the bot in the last 24 hours, which is a shortcut for finding an id and is NOT a roster: a chat missing from it can still be posted to. TEXT: up to 4096 characters on a text-only message, but only 1024 the moment ANY photo or video is attached — a caption is not a message, and Hermoso refuses the over-long one before spending the round trip and says which budget applied. MEDIA: one image (imageUrl), one video (videoUrl), or an ALBUM of 2–10 (imageUrls, in order) in which photos and videos may be MIXED — pass a videoUrl alongside imageUrls and it joins the album as one more item. Hermoso uploads the bytes rather than handing Telegram a link, which is what buys the larger ceilings: 10MB per photo and 50MB per video, where a link would be 5MB and 20MB. THE BOT MUST BE IN THE CHAT — an administrator with Post Messages for a channel, an unrestricted member for a group; if it is not, Telegram refuses and the error says to add it rather than to reconnect. Returns the message id and, for a PUBLIC chat, its t.me link — a private group has no public web link, so url comes back null rather than as a link that would 404 for whoever you hand it to. 0 credits. Connect at Settings ▸ Connectors ▸ Telegram by pasting a bot token from @BotFather.
| Name | Required | Description | Default |
|---|---|---|---|
| text | No | the message. ≤4096 characters on its own; ≤1024 once any image or video is attached. | |
| chatId | Yes | REQUIRED — the destination: a public channel's @username, or the numeric chat id. Never guessed; ask the user, or use list_telegram_chats. | |
| silent | No | deliver without a notification sound (Telegram’s disable_notification). This is NOT a visibility setting — the message is just as visible. | |
| account | No | WHICH connected account of this channel to post as — its @handle or id from list_connector_accounts. Needed only when the brand has more than one telegram account connected (several and none named is refused by name, never guessed); omit when there is one. | |
| imageUrl | No | one image (≤10MB after upload) | |
| videoUrl | No | one video (≤50MB). Passed alongside imageUrls it joins the album as one more item. | |
| imageUrls | No | an ALBUM of 2–10 media, in order. Photos and videos may be mixed — Telegram allows it. | |
| disablePreview | No | suppress the link-preview card on a text-only post. Default is Telegram’s own behaviour (previews on). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations are minimal (four hints only), so the description carries the full behavioral burden — and it over-delivers: refusal of over-long captions before the round trip, the bot-must-be-in-chat permission prerequisite with its specific error wording, byte-upload strategy with size ceilings, url returning null for private chats, 0 credits, and the connector setup path. This far exceeds what annotations disclose.
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?
Long, but every sentence earns its place — caps-labeled sections (CHAT, TEXT, MEDIA, THE BOT MUST BE IN THE CHAT) make it scannable, and the core purpose is front-loaded. The density is justified by the tool's complexity and the high cost of wrong guesses on chat destinations.
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 an 8-parameter, high-stakes tool with no output schema, the description is complete: return contract (message id, t.me link, url null for private groups), permission prerequisites, error behavior, cost, and connector setup are all specified. Nothing material is left to inference.
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?
Even though schema coverage is 100%, the description adds substantial meaning: why no chat default can exist (the Bot API has no chat-listing method), the negative/-100 numeric id conventions, album mixing rules (videoUrl joins imageUrls), and why upload-based limits (10MB/50MB) beat link-based ones (5MB/20MB). chatId and the media parameters are far better understood after reading this.
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 — 'Publish to a Telegram channel, group or chat as the brand's own bot' — and the 'own bot' qualifier pins down the posting identity, separating it from the many sibling post_to_* tools for other platforms. It also names list_telegram_chats in-body, further clarifying the division of labor.
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 guidance: never guess chatId, ask the user or use list_telegram_chats, and explicitly warns that list_telegram_chats is NOT a roster ('a chat missing from it can still be posted to'). It also states when the account parameter is needed (multiple connected accounts) and when to omit it, with refusal behavior if ambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
post_to_tiktokPost a video or photo post to TikTokAInspect
Publish to the user’s connected TikTok account — a finished VIDEO, or a PHOTO POST (TikTok’s photo/slideshow format). A photo post carries 1 to 35 images and ONE image is simply a one-slide photo post, so there is nothing special to do for a single picture: pass imageUrls, in the order the slides should appear, and optionally coverIndex. Pass videoUrl for a video. Never pass both — TikTok has no mixed post. TWO destinations either way: destination:"post" puts it LIVE on their profile now — that requires privacy, and you must call tiktok_creator_info first, show the creator’s real privacy options and get an explicit yes before calling. destination:"draft" (the default, and the safer one) sends it to TikTok for the user to finish and post themselves from the app. Pass Hermoso render URLs (or upload_file urls for local/external files). Needs TikTok connected (Settings ▸ Connectors ▸ TikTok).
| Name | Required | Description | Default |
|---|---|---|---|
| hook | No | WHAT ANGLE THIS POST IS BUILT ON — the single most valuable field here, and the only moment it can ever be recorded. post_performance groups on it to answer "which hooks work", and it needs 5 posts sharing ONE hook before it will call anything a winner, so REUSE THE SAME WORDING across a campaign instead of rephrasing it every time. Best of all, pass a hook id from list_hooks (e.g. "direct_callout", "mid_problem", "before_after") — those fold onto a stable key however they are spelled, so a whole brand accumulates evidence on one row. Your own wording is fine too; it just only groups when you repeat it exactly. Omitting it means this post can never vote on which hook works. | |
| title | No | the caption — hashtags go here (video ≤2200 chars, photo post ≤4000) | |
| account | No | WHICH connected account of this channel to post as — its @handle or id from list_connector_accounts. Needed only when the brand has more than one tiktok account connected (several and none named is refused by name, never guessed); omit when there is one. | |
| privacy | No | REQUIRED for destination:"post", for photos and video alike. Must be one the creator actually allows — read them from tiktok_creator_info, never guess. | |
| subject | No | WHAT THIS POST IS ABOUT — the product, feature, offer or theme (e.g. "winter coat", "free trial", "founder story"). The second grouping axis in post_performance. Same rule as hook: reuse the exact wording so posts about one subject land in one group. | |
| videoUrl | No | the video to post — a Hermoso render URL or an upload_file url. Omit for a photo post. | |
| imageUrls | No | a PHOTO POST: 1–35 image URLs in slide order. One url = a single-image photo post. Do not combine with videoUrl. | |
| yourBrand | No | discloses that this promotes the creator’s own brand | |
| coverIndex | No | photo posts: which slide is the cover, 0-based. Default 0 (the first slide). | |
| photoTitle | No | photo posts only: a short title above the caption (≤90 chars). Defaults to the caption’s first line. | |
| aiGenerated | No | TikTok’s is_aigc AI-generated-content label (video posts). OMIT IT and Hermoso decides from provenance: a Hermoso render is declared, a video that came through upload_file or an external URL (the user’s own footage) is NOT. true/false overrides. | |
| destination | No | "post" = live on the profile now (needs privacy + an explicit user yes); "draft" = to TikTok for the user to review and post themselves. Default "draft". | |
| disableDuet | No | video only — TikTok has no duet on a photo post | |
| autoAddMusic | No | photo posts only: let TikTok add a recommended track (default true — a silent slideshow reads as broken) | |
| disableStitch | No | video only — TikTok has no stitch on a photo post | |
| brandedContent | No | discloses a paid partnership — cannot be combined with SELF_ONLY privacy | |
| disableComment | No | ||
| coverTimestampMs | No | video only: which frame to use as the cover, in ms |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only indicate non-read-only and non-idempotent behavior, but the description adds meaningful behavioral context: it explains that "post" is immediately live, "draft" goes to the user for review, live posting requires explicit user consent, and TikTok must be connected. It does not mention return values or async job behavior, but it discloses the key 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?
The description is a single dense paragraph, but every sentence carries distinct operational guidance — media types, image count, destination semantics, consent requirement, URL formats, and connector requirement. It could be slightly better organized with bullets, but it is efficient and front-loaded with the core purpose.
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 an 18-parameter tool with no output schema, the description covers the major decision points: media type selection, destination choice, privacy requirement, connector prerequisite, and media URL sources. It does not describe the response/return value or job lifecycle, which would be useful since sibling tools like list_jobs exist, but this is a minor gap given the complexity already handled.
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 94%, so the baseline is high. The description adds valuable cross-parameter semantics not fully expressed in individual schema fields: the mutual exclusivity of videoUrl and imageUrls, the relationship between destination:"post" and the required privacy parameter, and the optional coverIndex behavior for single images. This goes beyond what the schema alone provides.
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 opens with 'Publish to the user’s connected TikTok account' and explicitly distinguishes between VIDEO and PHOTO POST formats, which are TikTok-specific concepts. It clearly differentiates this tool from the many sibling posting tools by naming TikTok and covering both media types.
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 explicit decision guidance: destination:"post" vs "draft", with the safety requirement to 'call tiktok_creator_info first' and get 'an explicit yes' before publishing live. It also states connector prerequisites and the rule 'Never pass both' video and images. This is strong when-to-use guidance beyond the schema.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
post_to_xPublish a post to X (Twitter)AInspect
Publish to the user’s connected X (Twitter) account — a single post, a post with an image or video render attached, a reply to an existing post, or a whole THREAD (pass thread as an array and each part is posted as a reply to the one before). This PUBLISHES immediately and PUBLICLY — ALWAYS show the user the exact text and get an explicit yes BEFORE calling. Can also run a POLL (2-4 options) instead of media, and restrict who may reply. LENGTH IS THE POSTING ACCOUNT’S, NOT A FLAT 280: 280 characters on an ordinary account, but UP TO 25,000 if that account has X Premium. Hermoso reads the account’s own subscription from X and sends the post rather than refusing something it may be entitled to; if X declines it on length, the reply says so and names the subscription X reported. Over 25,000 is refused for free — that is X’s own ceiling on every account. Text is NEVER truncated. AND A LONG POST IS CHEAPER THAN A THREAD: it is ONE billed X call where the same words split across five posts are five, so prefer one long post over threading when the account has Premium. Only the first ~280 characters show in the timeline; the rest sits behind “Show more”. Write altText whenever you attach a render. COSTS CREDITS: X charges per API request, so every post in a thread is billed, and a post containing a LINK costs roughly 13× one without — mention the cost before publishing a long thread. Each brand also has a rolling 24-hour ceiling on what it can spend at X, and a request that would cross it is refused WHOLE before anything publishes, so a batch of posts is bounded rather than open-ended. THIS TOOL POSTS ORGANICALLY — it does not create an ad campaign. X ads are built with create_x_ads_campaign → create_x_ads_line_item → create_x_ads_promoted_tweet, and a promoted post needs a post id, so publish here first and promote that post. Needs X connected (Settings ▸ Connectors ▸ X).
| Name | Required | Description | Default |
|---|---|---|---|
| hook | No | WHAT ANGLE THIS POST IS BUILT ON — the single most valuable field here, and the only moment it can ever be recorded. post_performance groups on it to answer "which hooks work", and it needs 5 posts sharing ONE hook before it will call anything a winner, so REUSE THE SAME WORDING across a campaign instead of rephrasing it every time. Best of all, pass a hook id from list_hooks (e.g. "direct_callout", "mid_problem", "before_after") — those fold onto a stable key however they are spelled, so a whole brand accumulates evidence on one row. Your own wording is fine too; it just only groups when you repeat it exactly. Omitting it means this post can never vote on which hook works. | |
| poll | No | run a poll on the post. X does not allow a poll and media on the same post, and a poll cannot ride on a thread. | |
| text | No | the post text. 280 characters without X Premium, up to 25,000 with it — write the full thing, it is never truncated. Use this OR thread, not both. | |
| thread | No | a thread: each string is one post, published in order, each replying to the previous. Max 25. Each part follows the same length rule as `text`, and on an X Premium account ONE long post is usually both better reading and cheaper than a thread. | |
| account | No | WHICH connected account of this channel to post as — its @handle or id from list_connector_accounts. Needed only when the brand has more than one x account connected (several and none named is refused by name, never guessed); omit when there is one. | |
| altText | No | accessibility description of the attached media, max 1000 characters — write one whenever you attach a render. Costs a small extra amount: X bills one metadata write PER media. With SEVERAL media, pass an ARRAY aligned to their order — X attaches alt text per media id, and a single string describes only the FIRST one (X renders up to four media as a GRID, not a carousel, so one sentence would be wrong for the other three). | |
| subject | No | WHAT THIS POST IS ABOUT — the product, feature, offer or theme (e.g. "winter coat", "free trial", "founder story"). The second grouping axis in post_performance. Same rule as hook: reuse the exact wording so posts about one subject land in one group. | |
| mediaUrl | No | a Hermoso render (image or video) to attach to the first post — pass its served URL, or an upload_file url for external media | |
| mediaUrls | No | UP TO FOUR Hermoso-hosted media attached to ONE post — X’s own schema caps media_ids at 4. X renders them as a GRID: every image visible at once, nothing to swipe to. That is NOT a carousel, and a numbered "1/6 · SWIPE" slide deck must still not be sent here — it would publish as a grid and the "swipe" instruction would make no sense. Order decides the layout. On a thread the media rides the FIRST post; give each later part its own post to attach more. Mutually exclusive with mediaUrl, and more than 4 is refused before anything is uploaded. | |
| replyToId | No | numeric id of an existing X post to reply to | |
| communityId | No | publish into an X COMMUNITY instead of the main timeline — the number in the community’s own URL (x.com/i/communities/<id>). The connected account must be a MEMBER of it; X answers a non-member and a non-existent id with the same refusal and does not separate them. | |
| quotePostId | No | numeric id of a post to QUOTE — X renders the quoted post inside yours. This is NOT replyToId: a reply sits under the original in its thread, a quote stands alone on your own timeline with the original embedded, which is the one you want for commentary. X makes a quote mutually exclusive with media and with a poll (their own schema), and a quote is billed at the higher LINK rate because X appends the quoted post’s t.co URL whatever your text says. | |
| replySettings | No | restrict who can reply — omit for everyone, which is the right default for a brand post | |
| paidPartnership | No | label the post a PAID PARTNERSHIP on X — the same disclosure Hermoso already ships for TikTok. OPT-IN ONLY: set it when the post is sponsored, gifted or otherwise paid for, and never assume it on the user’s behalf. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only signal non-read-only, non-idempotent, non-destructive; the description carries the real burden and exceeds it. It discloses immediate public publishing, the mandatory explicit-yes consent gate, subscription-dependent length limits with no truncation, per-request billing with a ~13x link multiplier, the 24-hour spend ceiling that refuses the whole batch, and the refusal messaging when X declines on length. None of this contradicts 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 description is long but front-loaded — consent, length, and cost appear immediately after the core purpose — and every sentence carries operational weight for a high-stakes public-posting tool. It loses a point for density: the caps-heavy style and a few re-statements (e.g., the long-post-cheaper point echoed in the thread parameter) could be trimmed 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 14-parameter, 0-required, no-output-schema publish tool, the description covers every deciding factor: what can be posted, the consent gate, account-dependent limits, billing and spend-ceiling refusal, organic-only scope with the ads alternative, and the connector prerequisite. Success/refusal behavior is described for length, spend ceiling, and community membership, and the post-id return is implied via 'publish here first and promote that post.'
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 genuine cross-parameter economics: a thread costs one billed call per part while one long post costs one call, and a link costs ~13x — which directly changes how an agent chooses values for text vs thread. It also unifies the 280/25,000 length rule across text and every thread part, beyond what the individual parameter descriptions 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?
The description opens with a specific verb and resource — 'Publish to the user's connected X (Twitter) account' — then enumerates the exact variants (single post, media attachment, reply, thread, poll). It explicitly scopes itself as organic ('does not create an ad campaign') and routes ads elsewhere, so an agent can distinguish it from the X ads pipeline and the post_x_article sibling 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 description gives explicit selection guidance: use this for organic posts and route ad intent to create_x_ads_campaign → create_x_ads_line_item → create_x_ads_promoted_tweet instead. It also dictates when to prefer a long post over a thread, mandates explicit user consent before calling, and names the prerequisite ('Needs X connected (Settings ▸ Connectors ▸ X)').
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
post_to_youtubePost a video to YouTubeAInspect
Publish a finished video to the brand’s connected YouTube channel. Pass a Hermoso render URL (or an upload_file url for a local/external file). DEFAULTS TO UNLISTED (link-only — not on the channel, not searchable, but shareable by link AND usable as a YouTube/Google ad). Pass privacy:"public" to put it ON the channel (a public publish — confirm with the user first) or privacy:"private" for eyes-only. Do NOT use "private" for anything meant to run as an ad — private videos CANNOT be used as ads; unlisted is the ad-ready setting. SCHEDULE it with publishAt, FILE it under the right categoryId (the default 22 "People & Blogs" is wrong for most ads), SUBSCRIBER NOTIFICATIONS FOLLOW PRIVACY — a public publish announces the video to the channel’s subscribers (YouTube’s own default), while unlisted/private uploads stay quiet; pass notifySubscribers explicitly to override either way. Needs a connected YouTube channel (Settings ▸ Connectors ▸ YouTube).
| Name | Required | Description | Default |
|---|---|---|---|
| hook | No | WHAT ANGLE THIS POST IS BUILT ON — the single most valuable field here, and the only moment it can ever be recorded. post_performance groups on it to answer "which hooks work", and it needs 5 posts sharing ONE hook before it will call anything a winner, so REUSE THE SAME WORDING across a campaign instead of rephrasing it every time. Best of all, pass a hook id from list_hooks (e.g. "direct_callout", "mid_problem", "before_after") — those fold onto a stable key however they are spelled, so a whole brand accumulates evidence on one row. Your own wording is fine too; it just only groups when you repeat it exactly. Omitting it means this post can never vote on which hook works. | |
| tags | No | up to 30 tags | |
| title | No | REQUIRED in practice — the headline every search result and the Shorts feed shows (≤100 chars); an upload with no title is refused | |
| account | No | WHICH connected account of this channel to post as — its @handle or id from list_connector_accounts. Needed only when the brand has more than one youtube account connected (several and none named is refused by name, never guessed); omit when there is one. | |
| privacy | No | default unlisted (anyone-with-link, ad-ready); public = live + searchable on the channel (confirm first); private = eyes-only (cannot run as an ad) | |
| subject | No | WHAT THIS POST IS ABOUT — the product, feature, offer or theme (e.g. "winter coat", "free trial", "founder story"). The second grouping axis in post_performance. Same rule as hook: reuse the exact wording so posts about one subject land in one group. | |
| videoUrl | Yes | the video to post — a Hermoso render URL or an upload_file url | |
| publishAt | No | SCHEDULE the publish — ISO 8601, e.g. "2026-09-01T15:00:00Z", and it must be in the future. YouTube only allows this on a PRIVATE video and makes it PUBLIC at that moment, so pass privacy:"private" (or leave privacy unset) — asking for a scheduled "unlisted" or "public" post is refused rather than half-honoured. | |
| categoryId | No | YouTube category id, NUMERIC — default "22" (People & Blogs), which is wrong for most ads. 1 Film & Animation · 2 Autos & Vehicles · 10 Music · 15 Pets & Animals · 17 Sports · 19 Travel & Events · 20 Gaming · 22 People & Blogs · 23 Comedy · 24 Entertainment · 25 News & Politics · 26 Howto & Style · 27 Education · 28 Science & Technology · 29 Nonprofits & Activism. The assignable set is region-specific, so the value is forwarded as given and YouTube has the last word. | |
| aiGenerated | No | YouTube’s “altered or synthetic content” declaration (containsSyntheticMedia). OMIT IT and Hermoso decides from provenance: a Hermoso render is declared, a video the user uploaded through upload_file or from an external URL is NOT — real footage must not carry the label. true/false overrides. | |
| description | No | REQUIRED in practice — what the video shows, a line about the brand, a link and a few #hashtags (≤5000 chars); YouTube search, suggested videos and the Shorts feed rank on it, so an upload with no description (and no caption) is refused | |
| notifySubscribers | No | THE DEFAULT FOLLOWS PRIVACY. privacy:"public" NOTIFIES the channel's subscribers — that is YouTube's own default and normally what someone publishing publicly wants. privacy:"unlisted" and "private" do NOT: the video is not on the channel, so announcing it is nonsense, and a blast to somebody's whole subscriber list cannot be undone. A scheduled publish (publishAt) is PRIVATE at upload, so it does not notify either — pass true to announce one. An explicit value ALWAYS wins in both directions: true announces an unlisted/private upload, false publishes publicly and quietly. The reply reports which way it went and why. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only say this is a non-read, non-destructive, open-world write. The description adds substantial behavioral detail: default unlisted upload, public/private semantics for ads, scheduled publishes being forced to private, subscriber notification defaults following privacy, aiGenerated auto-declaration based on provenance, and the fact that the reply reports the notification outcome. It also warns that certain invalid combinations are 'refused rather than half-honoured.' This goes far 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 description is long, but justifiably so for a tool with 12 parameters and many interacting constraints. It is front-loaded with the core purpose and default behavior, then covers privacy, scheduling, categories, notifications, and setup in a logical progression. The use of ALL-CAPS for key warnings is noisy but helps surface critical pitfalls.
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 the absence of an output schema and the high parameter count/complexity, the description covers all essential operational context: setup requirement, video source options, ad-readiness of privacy levels, scheduling constraints, category selection, subscriber notification behavior, aiGenerated auto-decision, and even a hint about the reply format. Nothing critical is missing for an agent to invoke the tool 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 description coverage is 100%, and each parameter already has a rich explanation in the input schema (privacy, publishAt, notifySubscribers, categoryId, aiGenerated, etc.). The tool description largely re-articulates that same information rather than adding new parameter-level meaning. It adds some cross-parameter synthesis, but per the rubric, no credit is given for repeating what structured data already provides.
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 opens with a specific verb+resource: 'Publish a finished video to the brand’s connected YouTube channel.' It clearly distinguishes this from sibling posting tools by platform (YouTube) and by workflow stage (finished video, not generation or upload). The scope is unambiguous and immediately actionable.
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 strong context: it names the required video source (Hermoso render URL or upload_file url), states the prerequisite of a connected YouTube channel, and explains when privacy/scheduling options apply. It does not explicitly compare itself to alternatives like schedule_post or post_to_tiktok, but the platform-specific name and 'connected YouTube channel' phrasing make the intended use clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
post_x_articlePublish a long-form Article to XAInspect
Publish a long-form ARTICLE to the user’s connected X (Twitter) account — X’s own long-form format, which is a different thing from a long POST. Give it a title and a body written in MARKDOWN (or plain prose) and Hermoso converts it into the DraftJS content_state structure X requires: headings, paragraphs, bulleted and numbered lists, blockquotes, bold / italic / strikethrough, links, horizontal rules, fenced code blocks and pipe tables all carry across. FORMATTING IS NEVER SILENTLY DROPPED — anything X Articles cannot represent (inline code, an inline image) REFUSES the article for free and names exactly what and why, and allowLossy: true is the explicit way to publish it as plain text anyway. THE HARD LIMIT TO PLAN AROUND: X allows only about 10 Article DRAFTS and 5 Article PUBLISHES per account per DAY, it publishes that cap nowhere, and it counts a FAILED attempt against them — so never iterate on an article by republishing it, and use publish: false to save a draft for the user to read in X’s own composer when they want to review before it goes out. This PUBLISHES immediately and PUBLICLY: show the user the full text and get an explicit yes first, because a published Article can NEVER be edited (X’s own rule — edit_x_post will refuse it) and the only remedy is to delete and republish, which costs another of the five. An Article appears in the timeline as a title card, not as body text; readers open it. Costs credits (X bills per API request, and this is three of them). Needs X connected (Settings ▸ Connectors ▸ X).
| Name | Required | Description | Default |
|---|---|---|---|
| body | Yes | the article body, as markdown or plain prose. Markdown headings, lists, quotes, links, emphasis, ``` code fences and | pipe | tables | are all converted to X’s own Article structure. | |
| hook | No | WHAT ANGLE THIS POST IS BUILT ON — the single most valuable field here, and the only moment it can ever be recorded. post_performance groups on it to answer "which hooks work", and it needs 5 posts sharing ONE hook before it will call anything a winner, so REUSE THE SAME WORDING across a campaign instead of rephrasing it every time. Best of all, pass a hook id from list_hooks (e.g. "direct_callout", "mid_problem", "before_after") — those fold onto a stable key however they are spelled, so a whole brand accumulates evidence on one row. Your own wording is fine too; it just only groups when you repeat it exactly. Omitting it means this post can never vote on which hook works. | |
| title | Yes | the Article title — X requires one and refuses a draft without it. This is what shows on the timeline card. | |
| publish | No | default true. Pass false to save it as a DRAFT in the account’s X Articles composer instead — nothing becomes public, the user can review and publish it from X, and it does not spend one of the five daily publishes. | |
| subject | No | WHAT THIS POST IS ABOUT — the product, feature, offer or theme (e.g. "winter coat", "free trial", "founder story"). The second grouping axis in post_performance. Same rule as hook: reuse the exact wording so posts about one subject land in one group. | |
| headings | No | how headings are rendered. “blocks” (default) uses X’s own heading block types, which is the faithful conversion. “text” renders each heading as a BOLD standalone paragraph instead: the words survive and the heading structure does not, the reply says so, and it is the documented fallback if X’s Articles service rejects heading blocks. | |
| allowLossy | No | publish even though part of the source cannot be represented on X, rendering those parts as plain text. OFF by default and it should usually stay off — silently publishing a user’s copy with formatting missing is worse than refusing and telling them. | |
| coverImageUrl | No | optional cover picture for the Article — a Hermoso render URL or an upload_file url. Must be a STILL image; X Article covers are not videos. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations provide minimal behavioral info (readOnlyHint: false, destructiveHint: false), so the description carries the full burden. It discloses crucial behaviors beyond annotations: formatting is never silently dropped, refusal conditions for unsupported elements, the hard limits (10 drafts, 5 publishes per day), counting failed attempts against caps, immediate public publishing, irreversibility, credit costs (three API requests), and connectivity requirements. This is exemplary transparency for a high-stakes mutation 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?
The description is long but every sentence contributes critical warnings or operational context, packing high information density without padding. It is reasonably front-loaded, leading with the core distinction and then covering conversion, limits, and pitfalls. While not as brief as the ideal, its length is justified by the tool's complexity and irreversible consequences—so it earns a 4 rather than a 3.
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 tool with this complexity (formatting conversion, daily caps, irreversible publishing, costs, connectivity), the description is remarkably complete. It covers what happens to unsupported formatting, how to avoid consuming daily publishes, how to use drafts for review, the impossibility of editing, credit costs, and prerequisites. No output schema exists, but the description explains the outcome (title card in timeline). Nothing needed 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 description coverage is 100%, so the baseline is 3. However, the description adds significant meaning beyond the schema: it explains the 'hook' field's grouping in post_performance and how to reuse wording or pass a hook id from list_hooks; it explains 'allowLossy' defaults and why it should usually stay off; it details the 'headings' enum behavior (blocks vs text) and the fallback purpose; and it clarifies 'publish' as a draft-saving mechanism. This exceeds baseline by adding actionable semantic context that the schema alone does not provide.
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 the tool publishes a long-form Article to X, explicitly distinguishing it from a long POST ('a different thing from a long POST'). It names the resource and the conversion process, and implicitly differentiates from sibling post_to_x. The key distinction is front-loaded, making it easy for an agent to select correctly.
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 explicit when-to-use guidance, including using publish:false to save drafts for review, avoiding republishing due to daily caps, and warning against iterating on published articles. It also names edit_x_post as refusing edited articles, guiding the agent to use delete and republish as the only remedy. This level of guidance fully covers when and when-not to use the tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
product_sizzleProduct sizzle (music-led)AInspect
Render an 18-30s music-led PRODUCT SIZZLE: ONE 15s Seedance 2.0 hero clip of the product, diced into fast cuts and intercut with typeset spec/CTA cards on a brand-coloured grain background, mixed to a music bed. Faceless by design — no people, no voiceover, no spoken lines; the cards carry every word, so nothing is left to a video model's spelling. Pass a real packshot as refImage or the label will not be yours. EXPENSIVE — the hero clip is the only paid leg and it is a full 15s Seedance render: ≈1,040 credits at the DEFAULT 1080p, ≈470 at 720p, ≈220 at 480p, ≈4,130 at 4k (call hermoso_capabilities for the live seedance-2 per-duration numbers; the dicing and the cards are free, and the music bed is already included in the quoted figure). Confirm the spend with the user before calling. For a talking/UGC ad use render_ad or generate_avatar; for a cheap deterministic format use make_template_ad.
| Name | Required | Description | Default |
|---|---|---|---|
| cta | No | closing CTA line, ≤30 chars | |
| specs | No | up to 4 spec lines for the typeset cards, ≤26 chars each | |
| prompt | Yes | what the sizzle should show — the product, the setting, the look | |
| seconds | No | finished length, clamped to 18-30s (default 25). The PAID hero render is always 15s regardless — this only changes how the cuts and cards are packed | |
| refImage | No | product packshot URL that anchors the real label — strongly recommended | |
| brandName | No | brand name on the cards — defaults to the workspace brand | |
| musicMood | No | music-bed mood, e.g. driving / cinematic / upbeat | |
| resolution | No | hero-clip resolution and therefore the whole cost — DEFAULT '1080p' (≈1,040 credits); '720p' ≈470, '480p' ≈220, '4k' ≈4,130 | |
| aspectRatio | No | '9:16' default; anything the seedance-2 catalog entry does not list falls back to 9:16 |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Despite no annotations (all false), the description fully discloses expensive nature (≈1,040 credits at 1080p), that the hero clip is the only paid leg, that dicing/cards are free, and that the music bed is included. It also reveals subtle behaviors like the paid hero always being 15s regardless of 'seconds', and the requirement for a real packshot to get the label right. No contradictions with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Though longer than typical, every sentence earns its place: purpose, mechanics, cost breakdown, prerequisites, and alternatives. The structure is front-loaded with purpose, then details, then cost, then exclusions. No fluff; the length is justified by the complexity and cost sensitivity.
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?
The description thoroughly covers purpose, usage, costs, and alternatives. The only gap is that it doesn't state what the tool returns (e.g., a job ID, a video URL, or a completion status). Given the presence of sibling tools like get_job and list_jobs, an agent might infer async behavior, but this is not explicit. Everything else needed to call it correctly is present.
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?
Although schema covers 100% of parameters, the description adds crucial meaning: resolution cost tables, the fact that 'seconds' only affects packing not the paid render, aspect ratio fallback behavior, and the explicit recommendation on refImage. This goes beyond the schema's simple type/format explanations and helps the agent make cost-aware decisions.
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 the verb 'Render', the resource 'PRODUCT SIZZLE', and precisely describes the output: an 18-30s music-led video made from a single 15s Seedance hero clip, diced into cuts with typeset spec/CTA cards. It clearly differentiates from siblings by naming render_ad, generate_avatar, and make_template_ad as alternatives with distinct use cases.
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: for talking/UGC use render_ad or generate_avatar, for cheap deterministic format use make_template_ad. Provides essential prerequisites: pass a real packshot as refImage, confirm spend with user before calling. Also clarifies cost implications and resolution trade-offs.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
publish_to_shopify_productPublish an image onto a Shopify productAInspect
Attach a finished image to one of the merchant's Shopify product listings, as product media. Pass productId (from list_shopify_products — the gid://shopify/Product/… form) and a PUBLIC https imageUrl, which is what every Hermoso render returns. Shopify fetches the image server-side and processes it asynchronously, so the media can come back status PROCESSING and appear on the listing a moment later — that is success, not a failure. Only works for accounts created by installing Hermoso from the Shopify App Store. Free — the render was already paid for.
| Name | Required | Description | Default |
|---|---|---|---|
| alt | No | alt text for accessibility and SEO; defaults to a generic credit | |
| imageUrl | Yes | any public https image URL — a Hermoso render works, and so does ANY file of your own brought in with upload_file | |
| productId | Yes | gid://shopify/Product/… from list_shopify_products |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond annotations (readOnlyHint=false, destructiveHint=false), the description discloses critical asynchronous behavior: Shopify processes the image server-side, so a PROCESSING status is success, not failure. It also explicates an account eligibility constraint and cost-free nature. This adds significant value beyond what annotations convey, with no contradictions.
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-loaded: the core action is stated in the first clause, followed by key parameter guidance, then critical async behavior, and finally constraints. Every sentence contributes essential information without repetition or fluff.
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 mutation tool with no output schema, the description covers the essential operational context: how to identify parameters, what async processing means, success criteria, and eligibility. It lacks details about the response structure (e.g., whether a media ID is returned) but given the async nature and that the agent mainly needs to know success, this is adequate. Minor gaps prevent a 5.
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 already provides full descriptions for all three parameters (100% coverage). The description adds minimal extra meaning: it reaffirms that imageUrl should be a public https URL (already in schema) and clarifies that productId comes from list_shopify_products (also in schema). The alt parameter is not elaborated further. Baseline 3 is appropriate since the schema carries the explanatory load.
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 the verb 'Attach' and resource 'finished image to Shopify product listing as product media'. It uses specific language that distinguishes it from general publish tools, naming the exact target resource (Shopify product listing). This differentiates it from similar sibling tools like set_product_image which may have broader scope.
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 operational constraints (pass productId from list_shopify_products, use public https imageUrl, only for Shopify App Store installs) but does not explicitly state when to use this tool versus alternatives. It does not mention when not to use it or name alternative tools for similar tasks, such as set_product_image. Guidance is implied but not explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pull_competitor_adsPull competitor adsARead-onlyInspect
THE FAST PATH for "show me the ads is running" — one named brand’s real live ads from the META (Facebook/Instagram) ad library, deduped, sorted, with the right page resolved. A single call, back in a few seconds. Prefer this over research_ads whenever the brand is named. Meta only, deliberately: it has by far the richest creative and is what people mean by "their ads". For Google or LinkedIn specifically, use search_google_ads or search_linkedin_ads. Spends credits.
| Name | Required | Description | Default |
|---|---|---|---|
| sort | No | 'longest_running' (default) etc. | |
| limit | No | max ads per platform (default 30) | |
| domain | No | the advertiser domain | |
| country | No | 2-letter, default 'US' | |
| companyName | No | the advertiser name |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, covering safety. The description adds valuable behavioral context: 'Spends credits,' 'Meta only,' 'deduped, sorted, with the right page resolved,' and 'real live ads.' This goes beyond the structured data without contradiction.
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 key purpose ('FAST PATH') and scope. The supporting rationale about Meta having the richest creative is useful but slightly verbose. Each sentence earns its place, and it avoids redundancy with 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 query tool with no required params and a complete schema, the description clearly conveys what it returns (real ads, deduped, sorted) and how to use it. It omits output structure, but that is not expected absent an output schema. It also flags credit cost, which is important for agent planning.
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 all parameters are already described. The description does not add new meaning beyond the schema (e.g., it restates defaults like limit 30 and country 'US'), providing marginal added value. 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 states a specific action ('pulls a named brand's real live ads from the META ad library') and distinguishes it from research_ads and Google/LinkedIn-specific tools. It immediately identifies the key scope (Meta only) and the differentiating factor (fast path for named brands), so an agent can select it correctly without ambiguity.
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?
Provides explicit routing: 'Prefer this over research_ads whenever the brand is named' and 'For Google or LinkedIn specifically, use search_google_ads or search_linkedin_ads.' This leaves no room for mis-selection and clearly states when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
read_docRead a Google DocARead-onlyInspect
Read the text of a Google Doc Hermoso can reach — one it created, or one the user handed over with the Google file picker in the app (that is how an EXISTING doc becomes readable; find its id with list_drive_files). Pass documentId (from create_doc) OR paste a Google Docs URL as docUrl. Under the drive.file scope it reaches nothing else in the user’s Drive; if Google answers that the file was not found, the user has not picked it yet — ask them to pick it in the app rather than retrying. Returns the plain text. Read-only, free.
| Name | Required | Description | Default |
|---|---|---|---|
| docUrl | No | a Google Docs URL to read — the document id is extracted from it | |
| documentId | No | the document id (from create_doc) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already carry readOnlyHint=true, destructiveHint=false, and openWorldHint=true, so the safety profile is known. The description adds meaningful context beyond that: the drive.file scope boundary ('reaches nothing else in the user's Drive'), the open-world dependency on a prior picker action, and the specific failure mode for unpicked files. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Longer than average, but every clause earns its place — scope, access model, parameter alternatives, error behavior, return type, and safety are all covered in service of a genuinely non-obvious usage model. The key constraint (what Hermoso can reach) is front-loaded. Slightly dense, 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?
Complete for a read-only tool. No output schema exists, but the description explicitly states 'Returns the plain text.' Error-handling guidance, access preconditions, both parameters, and the scope limitation are all disclosed. The openWorldHint is reinforced by explaining the picker mechanism. Nothing an agent needs to invoke this 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%, so both parameters are already documented in the schema. The description adds minor value by noting documentId comes from create_doc and that docUrl is a paste-able Google Docs URL with the id extracted from it, which slightly clarifies intent beyond what the schema states. Baseline 3 is appropriate given 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?
States a specific verb and resource — 'Read the text of a Google Doc' — and immediately defines the scope boundary ('Hermoso can reach'). It is clearly distinct from siblings like list_drive_files, create_doc, and append_to_doc, and tells the agent exactly what it returns (plain text) without needing to open any 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?
Excellent usage guidance. It explains the enabling precondition (doc must have been created by Hermoso or picked via the file picker), how to discover an id (list_drive_files), the two accepted input forms (documentId or docUrl), and even routes error handling ('file not found = user has not picked it, ask them to pick rather than retrying'). No exclusions are left implicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
read_sheetRead a Google Sheet rangeARead-onlyInspect
Read cells from a Google Sheet Hermoso can reach — one it created, or one the user handed over with the Google file picker in the app (that is how an EXISTING spreadsheet becomes readable; find its id with list_drive_files). Pass the spreadsheetId (from create_sheet) OR paste a Google Sheets URL as sheetUrl. If Google answers that the file was not found, the user has not picked it yet — ask them to pick it in the app rather than retrying. Returns a 2-D array of values.
| Name | Required | Description | Default |
|---|---|---|---|
| range | No | A1 range, e.g. "A1:D50" (default A1:Z1000) | |
| sheetUrl | No | a Google Sheets URL to read — the spreadsheet id is extracted from it | |
| spreadsheetId | No | the spreadsheet id (from create_sheet) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, but the description adds valuable behavioral context: the access prerequisite (user must have picked the file), the error behavior (file not found indicates user hasn't picked it), and the return type (2-D array). This goes beyond the annotations and helps the agent handle edge cases correctly.
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 concise and well-structured: it starts with the core action, explains access, then the parameter options, error handling, and return format. Every sentence adds value without redundancy. It is front-loaded with the most important information and avoids unnecessary detail.
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 the tool's moderate complexity (3 params, no output schema), the description covers all necessary aspects: what it does, how to specify the target, error handling, and return type. It even provides a pointer to list_drive_files for finding the ID. There are no obvious gaps for an agent to invoke this tool 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 100% with descriptions for all three parameters. The description adds meaning by clarifying that spreadsheetId and sheetUrl are alternatives and where each comes from, reinforcing the schema. It also explains the default range indirectly through the schema. The extra context about the relationship between parameters and the access model goes beyond the schema, so a score above baseline is warranted.
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 the action (read cells from a Google Sheet) and the scope (sheets Hermoso can reach, distinguishing from other sheet tools like append_to_sheet or update_sheet). It also explains the access model (created or user-picked) and provides the return format, making the tool's purpose 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 gives practical usage guidance: how to obtain the spreadsheetId (via create_sheet or list_drive_files) and that you can alternatively pass a URL as sheetUrl. It also advises on error handling (if file not found, ask user to pick it rather than retrying). While it doesn't explicitly contrast with other read tools, it covers the when and how effectively.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
recast_motionRecast motionAInspect
Motion transfer: re-perform a reference video's motion with a different person/character (supply their image). The reference clip drives the movement; the image supplies the identity. Paid render.
| Name | Required | Description | Default |
|---|---|---|---|
| image | Yes | the actor/character image URL (who should appear) | |
| video | Yes | the reference video whose motion to re-perform | |
| prompt | No | optional scene/style guidance | |
| orientation | No | which aspect to keep: the video's (default) or the image's |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations provide no safety hints (all false), so the description carries the burden. It discloses that it is a paid render, which is a meaningful behavioral trait (cost). It also clarifies the input roles (motion vs identity) but does not mention output format, async behavior, or other side effects. While it adds some value beyond annotations, it leaves significant behavioral gaps for a generation 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?
The description is three sentences, with the core purpose front-loaded ('Motion transfer'), followed by a clarifying analogy and a cost warning. Every sentence earns its place without redundancy. It is appropriately sized and easy to parse.
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 tool with 4 parameters and no output schema, the description covers the core concept and input roles but omits output expectations (e.g., whether it returns a video URL or a job ID) and potential prerequisites or limitations. Given the complexity of a paid generation task, more detail would be helpful, though the schema covers parameter specifics. This is adequate but not 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 description coverage is 100%, so the baseline is 3. The description adds conceptual clarification beyond the schema: 'The reference clip drives the movement; the image supplies the identity' reinforces the roles of the video and image parameters. This goes beyond the schema's literal descriptions and helps the agent understand the relationship, so a 4 is warranted.
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 the tool does motion transfer: it re-performs a reference video's motion with a different person/character, using the image for identity. This is a specific verb-resource pair that distinguishes it from other video tools like generate_video or generate_avatar. The mention of 'Paid render' adds a crucial operational detail. The description leaves no ambiguity about what the tool does.
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 the use case: when you have a reference video motion and want to apply it to a different subject. However, it does not explicitly state when to prefer this over alternatives, nor does it provide exclusions or conditions (e.g., when to use generate_video instead). The context is clear but there is no explicit guidance on alternative tool selection, so it earns a mid-range score.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
reframe_videoReframe videoAInspect
Reframe a video to a different aspect ratio (e.g. 16:9 master → 9:16 vertical) with smart subject tracking. Paid render; returns the served URL of the reframed video.
| Name | Required | Description | Default |
|---|---|---|---|
| video | Yes | the source video URL | |
| aspectRatio | Yes | the target aspect ratio |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint=false, so the agent knows it's a mutating operation. The description adds valuable behavioral details: it is a 'Paid render' and 'returns the served URL of the reframed video', which explains cost and output. This goes beyond the annotations and does not contradict 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?
Two concise sentences with zero waste. The first sentence states the core purpose and includes an example, the second adds cost and return information. Information is front-loaded efficiently.
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 only two parameters and no output schema, the description explains the return value (served URL) and cost (paid render). It does not mention potential limitations like supported formats or file size, but for a tool of this simplicity, the essentials are covered.
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% — both 'video' and 'aspectRatio' have descriptions. The tool description adds an example of aspect ratio conversion but no new parameter semantics beyond the schema. Per baseline, a score of 3 is appropriate when the schema already does the heavy lifting.
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 verb ('reframe'), a resource ('video'), and the exact purpose ('to a different aspect ratio') with a concrete example (16:9 → 9:16). This clearly distinguishes it from sibling tools like edit_video or clip_video, which focus on other video transformations.
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 for aspect ratio conversion and mentions 'smart subject tracking' and 'Paid render', but does not explicitly compare with alternatives or state when not to use. Since no sibling tool handles aspect ratio specifically, the intended use is clear, yet the lack of explicit exclusions prevents a perfect score.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
rememberRemember a factAInspect
Save a durable fact or PREFERENCE about the brand, audience, or the user’s creative TASTE (e.g. “audience is first-time homebuyers”, “prefers bold lime accents”, “always captions off”) into the workspace Memory so it shapes FUTURE ads. For lasting things, not one-off requests. Merges into the existing Memory (never overwrites); de-dupes on identical text. NEVER how Hermoso, a tool, a connector or a platform API behaves (what a call returns, errors, permissions, limits, ids) and never a phone number or email — those are refused.
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | the fact/preference, concise | |
| category | No | short bucket: Brand, Audience, Taste, Do, Don’t, or Preference (default General) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses that the tool merges into existing Memory, never overwrites, de-duplicates on identical text, and refuses disallowed content. This goes well beyond the annotations, which only signal non-read-only and non-destructive behavior, and there is no contradiction with the hinted values.
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 dense but front-loaded: the main action and examples come first, followed by usage constraints, merge/dedupe behavior, and exclusions. The final sentence is grammatically awkward and packs several caveats together, but every sentence 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 two-parameter memory-write tool with full schema coverage and no output schema, the description covers what to store, when to use it, how it mutates Memory, and what will be refused. Nothing necessary for selecting or invoking the tool 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?
Both parameters are already covered by the input schema (100% coverage), so the baseline is 3. The description adds meaningful value by giving concrete examples of acceptable text and by defining what is not allowed, which helps the agent populate the text parameter correctly.
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 the specific verb 'save' and identifies the exact resource: durable facts or preferences about the brand, audience, or user's creative taste, stored into workspace Memory. It clearly distinguishes this from one-off requests and from the many posting/scheduling siblings.
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 explicitly says 'For lasting things, not one-off requests' and lists hard exclusions: platform/tool/connector behavior, phone numbers, and emails are refused. It does not explicitly name alternatives like list_memory or forget, but the boundaries are clear enough for an agent to route correctly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
remix_staticRemix a static adAInspect
One-click STATIC-AD REMIX: rebuild a competitor/reference STATIC (image) ad as an on-brand version — SAME layout, composition and energy, but YOUR product, brand colours, logo and voice, with every trace of the source brand removed. Pass imageUrl = the static ad image to remix. Uses your saved brand (pass brandId to target a specific brand — that switches this key's active brand like use_brand). IMAGES ONLY — for video ads use render_ad. Bills as one image generation.
| Name | Required | Description | Default |
|---|---|---|---|
| brandId | No | a brand id/name from list_brands to remix for; omit to use the active brand | |
| imageUrl | Yes | the URL of the static ad image to remix |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
While annotations are all false (no readOnly, etc.), the description adds several behavioral details: it bills as one image generation, it switches the active brand as a side effect, and it ensures source brand traces are removed. These are beyond typical expectations and would affect the agent's usage, such as side effects and cost. It does not explicitly state any destructive actions, but given the tool is generative and the side-effect of brand switching is disclosed, it earns a 4 rather than a 3.
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 a single paragraph that front-loads the core purpose ('One-click STATIC-AD REMIX') before elaborating on behavior, parameters, and alternatives. It is reasonably concise, though slightly verbose with repeated emphasis ('STATIC', 'IMAGES ONLY'), but every sentence delivers value—it explains the branding outcome, parameter usage, side effect, alternative, and billing. It's well-structured and wouldn't benefit much from trimming.
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 tool with only two parameters and no output schema, the description covers all essential aspects: what it does, how to pass the required image, optional brand selection, the side-effect of brand switching, the billing implication, and a clear alternative for video. It does not specify the exact return format, but given the absence of an output schema and the simplicity of the operation, this is not a significant gap. The tool appears complete for an agent to invoke 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 100%—both `imageUrl` and `brandId` have descriptions in the schema—so the baseline is 3. The tool description adds meaningful extra semantics for `brandId`, explaining it switches the active brand like `use_brand`, which is not in the schema description. It also reinforces `imageUrl` as the input image. This goes beyond the schema, so a score of 4 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 clearly identifies the tool's function: rebuilding a static image ad as an on-brand version while preserving layout and energy. It explicitly states it is for STATIC images and names the sibling tool `render_ad` for video ads, making it distinguish from related tools. The inclusion of 'SAME layout, composition and energy' plus brand customization specifics leaves no ambiguity about what the tool does.
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 clear guidance on when to use this tool: for static (image) ads only, and explicitly points to `render_ad` as the alternative for video ads. It also explains the optional `brandId` behavior, noting it switches the active brand like `use_brand`, which helps the agent understand the context in which to provide that parameter. This meets the criteria for explicit when/alternative guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
remove_memberRemove a teammateADestructiveIdempotentInspect
Remove a member from this brand workspace by email — they lose access (you can re-invite them later). Confirm the exact person with the user, then call with confirm:true.
| Name | Required | Description | Default |
|---|---|---|---|
| Yes | the member’s email | ||
| confirm | No | REQUIRED true |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark destructiveHint:true and readOnlyHint:false. The description adds valuable context beyond annotations: the member loses access, it is reversible via re-invitation, and confirmation with the user is required. It does not contradict annotations and enriches the behavioral understanding, though it could detail side effects like data handling but that is not necessary given 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 description is two sentences with no redundancy. The main action and consequence are front-loaded, followed by the critical usage instruction. Every word adds value, making it highly efficient.
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 the destructive nature, the lack of an output schema, and the full schema coverage, the description covers the essential steps: what the tool does, the required confirmation, and the reversibility. It does not mention what happens to the member's associated data, but that is not critical for invoking the tool. The instruction to confirm with the user is a key safety measure that is included.
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 descriptions for both email and confirm. The description adds semantic value by explaining the confirm parameter's purpose ('REQUIRED true' in schema) and clarifying that the email is the identifier for the member. It goes beyond the schema by specifying the workflow: confirm with user, then call with confirm:true.
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 the exact action: 'Remove a member from this brand workspace by email' with the consequence 'they lose access'. It clearly differentiates from siblings like 'invite_member' and 'set_role' by specifying the remove operation and the email identifier. It is specific and 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 provides a clear usage instruction: 'Confirm the exact person with the user, then call with confirm:true.' It also implies the destructive nature and that removal is reversible ('you can re-invite them later'), giving context. However, it does not explicitly contrast with alternative tools, but the unique confirmation requirement and destructive nature make the usage clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
render_adRender ad videoAInspect
RECOMMENDED for finished video ADS: render a plan_ad concept through the SAME quality pipeline as the Hermoso web Studio — timed shot list, exact/clean speech (no garbled words), text composited in post (never model-painted), brand end card, licensed music bed, real product references. Pass plan_ad’s full structured output as creative. Honors the plan’s render_plan structure/duration: a storyboard that FITS ONE CLIP OF THE RENDER MODEL renders as a single continuous pass; anything longer automatically renders as STITCHED ACTS (the fewest balanced clips, each at most one model clip) — never time-compressed into one clip. That threshold is the render model’s own maximum, not a fixed number: most models cap a clip at 15s and the longest-clip one goes to 30s, so use dryRun:true to see the act split this plan will actually get, for free, before spending. CAST A SAVED CREATOR with creator so the SAME person stars in this ad as in the last one (list_creators is the roster) — otherwise every render invents a new face. Renders take 1–3 min; keep polling get_job if it returns still-rendering. Spends credits.
| Name | Required | Description | Default |
|---|---|---|---|
| model | No | video model id from hermoso_capabilities (default: the plan’s pick). Naming one is a DELIBERATE pick — the server asks before ever swapping it (no silent fallback) | |
| music | No | licensed music bed on/off (default on) | |
| dryRun | No | return the routing decision (single pass vs stitched acts, resolved model + act lengths) WITHOUT submitting a render — free, nothing charged | |
| lockup | No | persistent brand-logo lockup overlay on/off | |
| creator | No | CAST A SAVED CREATOR in this ad — their id from list_creators, or the name you know them by (“Sarah”). Their saved portrait becomes the on-camera identity for the whole spot, so the same face carries across every act and across every ad you render for this brand — and because we already have their picture, the character portrait this pipeline would otherwise generate is skipped, so casting somebody costs LESS than not casting them. Omit to let the ad cast a fresh person. Refused for free, with nothing rendered, if the name matches nobody or more than one creator, if the plan has nobody on camera, or if they are a REAL person with no likeness consent on file. | |
| endCard | No | branded end card on/off (default: on, except organic recipes) | |
| captions | No | burn the plan's per-scene on-screen words as caption pills. DEFAULT FALSE — leave it off unless the user asks for on-screen text (no captions, or true subtitles of what is said; never scene or emphasis labels); a recipe whose format IS on-screen text keeps its text either way | |
| creative | Yes | the FULL structured output of plan_ad (must contain video_storyboard) | |
| ttsVoice | No | voiceover voice name (e.g. Rachel / George) when the plan voices over | |
| resolution | No | '1080p' default (what we ship and bill for); '480p'/'720p' = cheaper draft passes, '4k' = premium final delivery (more credits). NOT EVERY MODEL OFFERS EVERY TIER — this enum is what the tool accepts, and each model's OWN `resolutions` list in hermoso_capabilities is what it can actually render (the longest-clip 30s model, for one, tops out at 720p). Ask for a tier the chosen model does not list and it is rendered at that model's best available tier instead, with nothing in the reply saying so — so check `resolutions` before promising anyone 1080p or 4k. | |
| aspectRatio | No | output aspect ratio, e.g. 9:16 (default) / 1:1 / 16:9 | |
| durationSeconds | No | total ad length in seconds (supported range 4–180; outside that it is clamped). Omit to honor the plan’s own duration — that is almost always right. This only RE-TIMES an already-authored board (its scenes are scaled to fit), it does NOT re-write it, so to change the length of the ad the user asked for, re-run plan_ad with durationSeconds instead. A length that fits ONE clip of the render model renders as one continuous pass; longer is stitched from acts filled to that model’s clip maximum with the remainder last — the maximum is 15s on most models and 30s on the longest-clip one, so use dryRun:true to see the exact act split for free before spending. | |
| allowGenericProduct | No | proceed even though this brand has NO product photo on file and the ad features a product — the packaging will be INVENTED. Only pass true after telling the user that and hearing they are fine with a generic stand-in |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses far beyond the minimal annotations: spends credits, 1–3 min latency with get_job polling, single-pass vs stitched-acts routing, model-dependent clip maxima, free dryRun preview, silent resolution downgrade 'with nothing in the reply saying so', creator refusal cases, and invented packaging for allowGenericProduct. Consistent with readOnlyHint:false and idempotentHint:false ('otherwise every render invents a new face').
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 — quality bar, routing threshold, dryRun, creator consistency, latency, cost — and key guidance is front-loaded. However, it is one dense ALL-CAPS block of run-on clauses; short labeled sections would make it substantially more scannable.
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 13-param, credit-spending, async tool with no output schema, the description covers the full invocation lifecycle: input contract, routing behavior, model-dependent limits, free preview, cost, latency, and silent fallbacks. The only gap, an explicit return-shape description, is mitigated by the 'keep polling get_job' guidance.
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 unusually rich per-parameter descriptions, so the baseline is 3. The description adds cross-tool operational meaning — creative must be plan_ad's full output, casting from list_creators gives same-face consistency, dryRun shows the actual act split free before spending — though some of this restates an already thorough 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 verb ('render') plus a specific resource ('a plan_ad concept') and a quality bar ('SAME quality pipeline as the Hermoso web Studio'). The 'RECOMMENDED for finished video ADS' framing clearly positions it against planning, generic generation, and post-processing siblings.
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?
Clear when-to-use context: finished video ads, pass plan_ad's structured output as creative, cast from list_creators, poll get_job. It names companion tools (plan_ad, list_creators, get_job, hermoso_capabilities) but never states explicit exclusions or names alternatives like finish_video/generate_video/stitch_video for when this tool is the wrong choice.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
report_bugReport a bugAInspect
Report a bug in Hermoso to the team. Use this when something in Hermoso genuinely misbehaves — a tool errors unexpectedly, returns a wrong or malformed result, a render comes back broken, or documented behaviour doesn't match what happened. Include what you were trying to do, the exact tool call and arguments, and what came back. Do NOT use it for out-of-credits, a policy refusal, or a missing capability (use request_feature for that). Free, no credits.
| Name | Required | Description | Default |
|---|---|---|---|
| details | Yes | what you were doing, the tool + arguments you called, what you expected, and what actually happened (paste the exact error) | |
| summary | Yes | one-line summary of the bug | |
| severity | No | high = blocks the task or loses paid work; medium = wrong output but workable; low = cosmetic |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=false and idempotentHint=false, covering the safety profile. The description adds beyond annotations: 'Free, no credits' clarifies cost, and 'Report a bug ... to the team' indicates it submits a report rather than performing a local action. This adds useful behavioral context without contradicting 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 description is front-loaded with the core purpose, then expands logically into when-to-use, exclusions, and submission guidance. Every sentence earns its place, and it avoids redundancy with the schema. It is informative without being verbose.
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 reporting tool with no output schema, the description covers everything an agent needs: what counts as a bug, when to use it, when not to, and what to include. The low complexity and clear annotations make this 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 100% — all three parameters are described in the schema with details for summary, details, and severity (including enum meanings). The description reinforces what to include in 'details' but does not add new meaning beyond the schema. It meets the baseline of 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 clearly states 'Report a bug in Hermoso to the team' — a specific verb, resource, and audience — then enumerates concrete examples of genuine misbehavior (tool errors, wrong/malformed results, broken renders, documented behavior mismatch). It explicitly differentiates from request_feature for missing capabilities, so an agent can immediately tell it apart from the 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?
It explicitly states when to use the tool ('Use this when something in Hermoso genuinely misbehaves') and when not to ('Do NOT use it for out-of-credits, a policy refusal, or a missing capability') and names the alternative (request_feature). This leaves no ambiguity about tool selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
request_featureRequest a featureAInspect
Ask the Hermoso team for a capability that doesn't exist yet. Use this when you need something Hermoso genuinely can't do — an unsupported platform or channel, a missing model, an export format, a tool that would have completed the user's task but isn't available. Say what the user was trying to achieve, not just the feature name — the use case is what gets built. Free, no credits.
| Name | Required | Description | Default |
|---|---|---|---|
| details | Yes | what the user was actually trying to achieve, why the current tools couldn't do it, and what you'd expect the capability to do | |
| summary | Yes | one line: the capability you need |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already convey that this is not read-only (readOnlyHint: false), not idempotent (idempotentHint: false), and not destructive (destructiveHint: false). The description adds the behavioral context that the request is 'free, no credits' and that 'the use case is what gets built,' which suggests the request has real-world impact on Hermoso's roadmap. However, it does not disclose what happens after submission (e.g., whether a confirmation is returned, how long it takes, or whether multiple submissions are allowed), which leaves some behavioral ambiguity.
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 (about 60 words) and front-loaded with the primary action. The first sentence states the tool's purpose, the second provides usage conditions and examples, and the third gives content guidance. Every sentence adds value: the 'Free, no credits' is a key differentiator, and the instruction on including the use case is critical for effective feature requests. There is no redundant phrasing or 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 tool whose sole function is to submit a feature request, the description covers the essential context: what it does, when to use it, and how to structure the request. With no output schema required, there is no need to describe return values. Annotations (openWorldHint: true) indicate external effects, and the sibling set clearly positions this tool as distinct from others like 'report_bug' and 'hermoso_capabilities.' Thus, the description is complete for an agent 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?
The input schema already provides thorough descriptions for both 'summary' and 'details' (schema coverage 100%). The description goes beyond this by reinforcing the importance of the use case over the feature name, explicitly instructing 'Say what the user was trying to achieve, not just the feature name.' It also echoes the details parameter's guidance, which helps the agent prioritize the content of the request. While it does not add new parameter-level details, it adds a strategic lens on how to fill them, thus improving parameter semantics.
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 opens with a clear verb and resource: 'Ask the Hermoso team for a capability that doesn't exist yet.' It then enumerates concrete examples (unsupported platform or channel, missing model, export format) and distinguishes itself from the sibling 'report_bug' by focusing on requests for new capabilities rather than defect reports. The statement 'Free, no credits' further clarifies its unique purpose among the large sibling set.
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 explicitly states 'Use this when you need something Hermoso genuinely can't do' and lists scenarios, which is strong usage guidance. It implicitly differentiates from 'report_bug' (which handles defects) but never names it directly. It also implies not to use it for existing capabilities, though an explicit 'when not to use' is absent. The guidance to 'Say what the user was trying to achieve' provides clear direction on framing the request.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
reschedule_postChange a scheduled postAIdempotentInspect
Change a post that is still QUEUED — move it to a different time, rewrite the caption, swap the media, add or drop a channel, or change which board / Page / company Page / listing it goes to. PASS ONLY WHAT CHANGES: an omitted field is left exactly as it was, and an explicit empty string CLEARS one (linkedinOrganizationId:"" moves a company-Page post back to the person’s own profile). The edited item is re-checked against the identical rules its create passed — visibility the channel can honour, per-channel length, media the channel can carry — so an edit can never slip past a refusal that a create would have caught. Get the id from list_scheduled. Something that already went out cannot be changed: a published post is edited or removed with manage_meta_post / manage_linkedin_post / delete_x_post, not rescheduled.
| Name | Required | Description | Default |
|---|---|---|---|
| at | No | the new time — ISO timestamp (2026-08-05T09:00:00Z) or epoch milliseconds. Must be in the future, at most 365 days out. | |
| id | Yes | the scheduled post id from list_scheduled | |
| link | No | ||
| poll | No | X — replaces the poll; an empty options list removes it. | |
| tags | No | YOUTUBE — replaces the WHOLE tag list; an empty array [] clears the tags. | |
| event | No | GOOGLE BUSINESS — replaces the whole event record {title, startDate, startTime, endDate, endTime}. | |
| offer | No | GOOGLE BUSINESS — replaces the whole offer record {couponCode, redeemOnlineUrl, termsConditions}. | |
| title | No | PINTEREST / YOUTUBE — replace the headline; "" clears it and goes back to deriving one from the caption | |
| chatId | No | TELEGRAM — send it to a different chat, group or channel (@username or numeric id). It can be changed but never cleared: telegram cannot publish without one. | |
| pageId | No | FACEBOOK / INSTAGRAM / THREADS — publish from a different connected Page (list_meta_pages) | |
| thread | No | X — replaces the WHOLE thread; an explicit [] drops back to a single post using the caption. | |
| altText | No | ACCESSIBILITY — replace the screen-reader description(s). A STRING describes every slide; an ARRAY describes them one at a time in slide order and REPLACES the whole list. "" clears it. | |
| boardId | No | PINTEREST — move the Pin to a different board (list_pinterest_boards) | |
| message | No | replace the caption used for every channel that has no override | |
| captions | No | replaces the WHOLE per-channel caption map — send every override you want to keep, not just the new one | |
| channels | No | replaces the channel list | |
| imageUrl | No | swap the image; "" removes it | |
| topicTag | No | THREADS ONLY — one topic tag, without the leading #. | |
| videoUrl | No | swap the video; "" removes it | |
| imageUrls | No | replace the CAROUSEL slides, in order; an empty array [] drops the carousel and goes back to a single image. Omit to leave the slides exactly as they are. The edited item is re-checked against the same carousel rules the create passed, so adding a channel that cannot swipe is refused now rather than posting slide 1 later. | |
| slideText | No | PINTEREST CAROUSEL ONLY — per-slide title / description / link, aligned to slide order. | |
| topicType | No | GOOGLE BUSINESS — the kind of Post; EVENT and OFFER both require `event`. | |
| trialReel | No | INSTAGRAM — replaces the trial-reel setting on a queued Reel (MANUAL or SS_PERFORMANCE); an explicit "" turns the trial off and it goes out as an ordinary Reel. Only takes effect while the post is still queued — a Reel already published cannot be converted into a trial. | |
| yourBrand | No | TIKTOK — the own-brand disclosure; false turns it off. | |
| actionType | No | GOOGLE BUSINESS — the call-to-action button; "" clears it. | |
| locationId | No | GOOGLE BUSINESS — a different listing (list_business_locations) | |
| madeWithAi | No | X — the AI-media label; false turns it off. | |
| visibility | No | NOTE: changing this without also naming visibilityByChannel clears any per-channel overrides, so "make it all draft" is not a no-op | |
| aiGenerated | No | INSTAGRAM / FACEBOOK REEL — Meta’s is_ai_generated self-disclosure. OMIT IT and Hermoso decides from provenance: a Hermoso render is declared, media that came through upload_file or from an external URL (the user’s own photographs or footage) is NOT — a real photo must never carry Instagram’s “AI info” label. Pass true or false only to override: false strips the label from something Hermoso would otherwise declare, true declares a render the user uploaded themselves. | |
| communityId | No | X — the community to publish into; an empty string goes back to the main timeline. | |
| description | No | YOUTUBE — replace the video description; "" clears it. Remember the caption is the TITLE, not the description. | |
| disableDuet | No | TIKTOK VIDEO ONLY — block Duets. | |
| quotePostId | No | THREADS ONLY — the id of the Threads post this one quotes. | |
| countryCodes | No | THREADS ONLY — two-letter country codes limiting who can see the post. | |
| privacyLevel | No | TIKTOK — WHICH PRIVACY LEVEL the post goes out at, in TikTok’s own vocabulary. TikTok requires the USER to choose this from the levels their own account allows: call tiktok_creator_info, show them the real options, and pass back the one they picked — never a default and never a guess, which TikTok refuses at init. Omit it and the post falls back to the coarse `visibility` (private → SELF_ONLY, otherwise PUBLIC_TO_EVERYONE), which cannot express MUTUAL_FOLLOW_FRIENDS or FOLLOWER_OF_CREATOR at all. It must agree with the TikTok visibility (SELF_ONLY is the private one) and it is refused on a TikTok DRAFT, which carries no post info. | |
| replyControl | No | THREADS ONLY — who may reply. | |
| xQuotePostId | No | X — the post this one QUOTES; an empty string removes the quote. Named apart from the Threads `quotePostId` on this same schedule. | |
| collaborators | No | INSTAGRAM — replaces the WHOLE collab list (up to 3 usernames); an explicit [] removes the co-authors and the post goes out as an ordinary single-author post. Only takes effect if the post has not fired yet — an invite already sent cannot be withdrawn from here. | |
| disableStitch | No | TIKTOK VIDEO ONLY — block Stitches. | |
| replySettings | No | X — who may reply; "" goes back to everyone. | |
| brandedContent | No | TIKTOK — the paid-partnership disclosure; false turns it off. | |
| disableComment | No | TIKTOK — comments off on this post. | |
| linkAttachment | No | THREADS ONLY — a full http(s) URL rendered as a link card on a TEXT-ONLY post. The only way a Threads post carries a destination. | |
| paidPartnership | No | X — the paid-partnership label; false turns it off. | |
| coverTimestampMs | No | TIKTOK VIDEO ONLY — cover frame in milliseconds. | |
| crossreshareToIg | No | THREADS ONLY — also share to Instagram as a Story when it fires; false turns it off. Refused on a carousel. | |
| commercialContent | No | TIKTOK — the COMMERCIAL CONTENT DISCLOSURE toggle: true when this post promotes a brand, product or service at all. TikTok requires at least one of yourBrand / brandedContent once it is on, and refuses a post that declares itself commercial without naming which kind. Either disclosure already implies it. | |
| visibilityByChannel | No | ||
| crossreshareDarkMode | No | THREADS ONLY — dark-mode that Instagram Story. Needs crossreshareToIg. | |
| linkedinOrganizationId | No | LINKEDIN — target a different company Page, or "" to post as the connected person instead |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds substantial behavior beyond the annotations: the partial-update model (omitted field left as-is, explicit empty string clears), re-validation against create-time rules, and the 'no published posts' boundary. It also discloses per-parameter defaults such as the aiGenerated provenance decision, the privacyLevel fallback, and collaborators already sent being unwithdrawable. Nothing contradicts the annotations (readOnlyHint false, destructiveHint false, idempotentHint true, openWorldHint true).
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 with zero filler. It front-loads the core action, then the partial-update rule, then id sourcing, then the exclusion — every sentence earns its place and nothing important is buried.
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 50-parameter, nested-object tool with no output schema, this is nearly complete: editing semantics, id source, and the published-post exclusion are all present, and the 96%-covered schema carries the parameter detail. The only gap is the shape of the return value, which is a minor omission for an edit tool.
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 96% schema description coverage, the schema already documents nearly every parameter, so the baseline is 3. The description earns the extra point by supplying the one cross-cutting rule that governs all 50 parameters — 'PASS ONLY WHAT CHANGES' with empty-string clear semantics — plus the re-validation guarantee, which per-parameter schema entries cannot express.
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: 'Change a post that is still QUEUED' and enumerates the kinds of changes (time, caption, media, channels, board/Page/company Page/listing). It explicitly names what it is not for by routing published posts to manage_meta_post / manage_linkedin_post / delete_x_post, and the id-sourcing reference to list_scheduled distinguishes it cleanly from cancel_scheduled and duplicate_scheduled.
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 ('a post that is still QUEUED') and when-not-to-use ('Something that already went out cannot be changed') with named alternative tools. It also instructs the agent where to obtain the required id (list_scheduled) and how to structure an edit ('PASS ONLY WHAT CHANGES').
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
research_adsResearch adsARead-onlyInspect
Open-ended ad research that needs JUDGMENT across platforms — comparisons, "what angle is working", "who else is doing this", anything where the right sources are not known up front. It is an agentic loop (several rounds of library pulls plus a written synthesis) and typically takes 30-60 seconds, so it is the WRONG tool for a question that names its own answer. For one named brand’s live ads use pull_competitor_ads; for one keyword or one advertiser on Meta use search_meta_ads — both are a single call and return in a few seconds. Spends credits — an agentic loop, so a handful rather than the one-call cost of a targeted search.
| Name | Required | Description | Default |
|---|---|---|---|
| brand | No | brand name or profile object to tailor the research to; omit to use the workspace’s saved brand | |
| query | Yes | what to research, e.g. "the longest-running protein-pancake ads on Meta" |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations provide readOnlyHint, openWorldHint, and destructiveHint=false, but the description goes beyond by disclosing that this is an agentic loop taking 30-60 seconds, that it spends credits (a handful vs. a single-call cost), and that it performs several rounds of library pulls plus a written synthesis. This behavioral context, including cost and latency, is critical and not available in the annotations, so the description fully carries its burden.
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 examples, then provides usage guidance and caveats in a logical flow. Every sentence earns its place—no filler, clear structure, and the critical warning ('WRONG tool for a question that names its own answer') is highlighted. It is appropriately length for the tool's complexity.
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 tool that is an agentic loop with no output schema, the description explains the behavior (multi-round, synthesis), the time cost, and the credit cost, and routes to faster alternatives for simpler queries. It doesn't explicitly describe the output format beyond 'written synthesis', but that is sufficient for an agent to know what to expect. The context is adequate for deciding when to invoke this tool, and the only minor gap is the absence of a precise return structure, which is acceptable given the open-ended nature.
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 input schema covers both parameters (query and brand) with clear descriptions, so the baseline is 3 per the rubric. The description adds an example of a query ('the longest-running protein-pancake ads on Meta') and implies that the query should be open-ended, but it doesn't explain the brand parameter beyond what the schema provides. Since schema coverage is 100%, the description's added semantic value is marginal, though it does reinforce what kinds of queries are 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 opens with 'Open-ended ad research that needs JUDGMENT across platforms' and gives concrete examples ('comparisons', 'what angle is working', 'who else is doing this'), making the tool's specific purpose unmistakable. It also names two sibling tools (pull_competitor_ads and search_meta_ads) and explicitly contrasts them, so an agent can distinguish this from the rest of the tool list.
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 explicitly states when to use this tool (open-ended questions where the right sources are unknown) and when NOT to use it ('a question that names its own answer'). It names the precise alternatives—pull_competitor_ads for a named brand's live ads, search_meta_ads for one keyword or advertiser on Meta—and notes they are single calls that return quickly, leaving no ambiguity about routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
retry_scheduledRetry a failed scheduled postAInspect
Send a post that FAILED again. A scheduled post fans out across its channels INDEPENDENTLY, so a failure is usually PARTIAL — LinkedIn 401s while Instagram published fine — and this re-fires ONLY the channels that did not succeed by default (list_scheduled reports them as retryable). It re-queues the same content as a NEW post that goes out RIGHT AWAY — the queue picks it up on its next pass, within seconds — and the original keeps its failure record so the history still shows what went wrong. Naming a channel that already published is REFUSED rather than quietly posting a second time. Two independent belts stop a double-post: a channel that genuinely published can only REPLAY (nothing is posted), and a channel whose outcome is UNRESOLVED — the platform timed out and may be holding the post — refuses with that reason instead of guessing. Retry after fixing the cause — and you can fix it IN THIS CALL: pass boardId, pageId, linkedinOrganizationId, locationId, message or captions to correct the value that failed, and the corrected post is re-validated exactly like a fresh schedule. That matters because the commonest cause is a field, not an outage: a Pin aimed at the wrong board fails identically however many times it is re-sent. Anything you do not name is copied from the original. To send the same thing again ON PURPOSE, use duplicate_scheduled.
| Name | Required | Description | Default |
|---|---|---|---|
| at | No | hold the retry until a later time — ISO timestamp or epoch milliseconds. Leave it out to retry immediately, which is almost always what you want. A time you name here must be at least a minute from now, exactly like any other scheduled post. | |
| id | Yes | the scheduled post id from list_scheduled | |
| chatId | No | CORRECT THE TELEGRAM DESTINATION on retry — the @username or numeric id of the chat. A post aimed at a chat the bot is not in fails every time it is retried until this changes. | |
| pageId | No | CORRECT THE PAGE on retry — which connected Facebook Page (and its linked Instagram/Threads) publishes, from list_meta_pages. | |
| boardId | No | CORRECT THE BOARD on retry — the Pinterest board the Pin goes on, from list_pinterest_boards. A Pin aimed at a board Pinterest refuses fails the same way on every retry until this is changed. | |
| message | No | CORRECT THE CAPTION on retry — use this when the original was refused for length or content. Anything not named here is copied from the original post. | |
| captions | No | CORRECT ONE CHANNEL’S CAPTION on retry, e.g. { "x": "..." } when only that channel refused the text. | |
| channels | No | retry only these channels (default: every channel that did not publish) | |
| locationId | No | CORRECT THE LISTING on retry — which Google Business Profile location, e.g. "locations/123" from list_business_locations. | |
| allowDuplicate | No | ONLY for a channel you have checked by hand and confirmed the post is genuinely NOT there. It bypasses the double-post protection and can publish a second public copy, so never set it to work around a refusal you have not investigated. | |
| linkedinOrganizationId | No | CORRECT THE LINKEDIN AUTHOR on retry — the company Page id from list_linkedin_pages. Set it to an empty string to fall back to the personal profile. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations provide only basic hints (readOnlyHint false, destructiveHint false), so the description carries the full burden of behavioral disclosure. It does this richly: explains partial failures, re-queues as a new post that goes out right away, keeps the original's failure record, refuses to double-post, and handles unresolved outcomes with explicit refusal. No contradiction with annotations; it goes far beyond 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 highly front-loaded, opening with the core purpose and then layering details. Each sentence adds crucial operational or safety information, but the overall length is considerable (600+ words). While dense and necessary for this complex tool, it could be tightened slightly without losing value; still, it eams its place overall.
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 the tool's complexity (multi-channel fan-out, partial failures, safety mechanisms), the description covers all essential behaviors: what happens on retry, what gets refused, how to correct fields, the copy behavior, and the timing of re-queueing. It references list_scheduled for identifying retryable channels, and explicitly names the sibling tool for intentional duplicates. No gaps 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?
Even though schema coverage is 100%, the description adds significant meaning: it identifies which parameters are for correcting failures (boardId, pageId, linkedinOrganizationId, locationId, message, captions), explains that unspecified fields are copied from the original, and gives detailed semantics for allowDuplicate including its bypass of double-post protection. This goes well beyond the schema's own descriptions.
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 opens with 'Send a post that FAILED again', a specific verb+resource that immediately distinguishes it from scheduling, rescheduling, or duplicating. It elaborates on partial failures and re-firing only failed channels, and explicitly names duplicate_scheduled as the alternative for intentional resends, so an agent can clearly tell it apart from siblings without inspecting 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?
The description gives explicit when-to-use guidance: after a failure, after fixing the cause, and for correcting specific fields in the same call. It also states when NOT to use it (for sending the same thing on purpose, use duplicate_scheduled) and warns about allowDuplicate misuse, leaving no ambiguity about the correct scenarios.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
run_post_refillRun the posting refillAInspect
Run the refill NOW instead of waiting for its daily turn. DRY BY DEFAULT: it returns the exact posts it WOULD queue — the caption, the creative, the channels and the per-channel visibility — without queueing anything or spending anything on creative. Pass dryRun:false to actually queue them. SHOW THE PREVIEW TO THE USER BEFORE EVER PASSING dryRun:false; these go onto real public accounts. Every caption is screened against the brand’s own voice rules and a failing one is dropped, so a plan can legitimately come back shorter than the cadence — the reason is in the notes.
| Name | Required | Description | Default |
|---|---|---|---|
| force | No | plan even while the refill is switched off — useful for showing someone what it would do before they turn it on. Combined with dryRun:false it still respects a stored dryRun. | |
| dryRun | No | default TRUE (preview only). false actually queues the posts. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes far beyond the annotations (readOnlyHint=false, idempotentHint=false, destructiveHint=false) by disclosing that dryRun defaults to true, that passing dryRun:false queues posts onto real public accounts, that captions are screened and dropped if they fail brand voice rules, and that the plan can be shorter than the cadence. This is rich, explicit behavioral context that annotations only hint at, making it highly transparent.
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-loaded with the purpose, then covers safety and behavioral details. It uses all-caps emphasis effectively to highlight critical warnings. It is slightly dense with multiple clauses, but every sentence earns its place. A small trim could improve readability, but overall it's well-structured and not overly verbose.
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 there is no output schema, the description does an excellent job of explaining what the tool returns: the exact posts it would queue, including caption, creative, channels, and per-channel visibility, and notes that dropped captions are explained in the notes. It also covers edge cases like force and stored dryRun. For a mutating tool of this complexity, 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?
The input schema already provides full descriptions for both parameters (force and dryRun) with 100% coverage. The tool description adds some context about the default and safety implications but does not materially extend the parameter semantics beyond what the schema already conveys. Per the rubric, a baseline of 3 is appropriate when schema coverage is high.
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 the tool's purpose: run the refill now instead of waiting for its daily turn. It specifies the action (run) and the resource (posting refill), and distinguishes it from related tools like get_post_refill (which likely reads the refill plan) and set_post_refill (which configures it) by emphasizing immediate execution. The purpose is unambiguous even 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 description gives a clear usage context: run now instead of waiting for the daily turn, and explicitly warns to show the preview before ever passing dryRun:false. However, it does not explicitly name alternatives like get_post_refill for preview-only scenarios, though the DRY BY DEFAULT feature effectively covers that. The guidance is present but not exhaustive about sibling differentiation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
save_creatorSave a creatorAInspect
Add a portrait to this workspace’s reusable CAST so the SAME person can star in future ads — the headless twin of the app’s + ▸ Pick a creator ▸ save. Pass the portrait’s public url (a generate_image render of a person, a headshot, any public photo) plus a name to call them by; from then on list_creators returns them and their url can be re-passed to generate_avatar / generate_video / recast_motion. Saving is FREE and renders nothing. LIKENESS — source says what the portrait IS: leave it "generated" for an AI-made person, and use "upload"/"social" ONLY for a REAL person. Pass consented:true only when the user has told you that person agreed to their likeness being used; never assert that on their behalf.
| Name | Required | Description | Default |
|---|---|---|---|
| look | No | their canonical wardrobe/appearance in words — reused to hold the look steady across ads | |
| name | Yes | what to call this creator (e.g. “Sarah”) — list_creators and the app’s picker match on it | |
| image | Yes | public https url of the portrait (an existing render’s url, or any public photo). Not a local file path — upload it with upload_file first and save the url that returns | |
| poses | No | up to 4 extra full-body / angle plates of the SAME person (public urls) — they make a wider shot hold the identity | |
| voice | No | a default voice name for this persona (engines + voices are in hermoso_capabilities) | |
| source | No | "generated" (default) = an AI-made person; "upload" / "social" = a REAL person | |
| consented | No | REAL people only: the user has confirmed that person consented to their likeness being used in ads |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations are all false (readOnlyHint, openWorldHint, idempotentHint, destructiveHint), so the description carries the full burden. It discloses key non-obvious behaviors: saving is FREE and renders nothing, and it explains the nuanced consent and source requirements for real people. This adds meaningful context beyond the annotation fields and helps the agent avoid misuse. It does not mention overwrite or duplicate behavior, but for a save action this is not a critical omission given the explicit 'Add a portrait' framing.
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 detailed but not bloated. It front-loads the core purpose and then adds necessary usage and constraint context. The use of all-caps 'LIKENESS' and 'REAL' draws attention to critical distinctions. Each sentence contributes information without redundancy. It could be slightly tighter, but it remains well-structured and readable.
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 tool with 7 parameters, 2 required, and no output schema, the description covers all essential aspects: main purpose, usage flow, prerequisites (public URL, consent), parameter semantics reinforcement, and behavioral notes (free, renders nothing). It even implies interactions with sibling tools (list_creators, generate_avatar). Nothing critical is missing for an agent to call it correctly and safely.
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 the baseline is 3. The description largely reiterates what the schema already states (e.g., image is a public URL, name is what to call the creator, look is canonical appearance). It adds emphasis on the source and consented constraints, but these are already in the schema. It does not introduce new parameter-level meaning beyond clarifying the relationship to other tools (e.g., URL reused in generate_avatar/video), which is more usage guidance than parameter semantics. Thus, 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 clearly states the tool's purpose: add a portrait to the workspace's reusable CAST so the same person can star in future ads. It explicitly identifies the API as the headless twin of the app's '+ ▸ Pick a creator ▸ save' flow, which distinguishes it from sibling tools like list_creators, delete_creator, and generate_avatar. The verb 'Add' plus the resource (portrait to CAST) is specific and 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 provides clear context on when to use the tool: anytime you need to save a person to the reusable CAST for future ads. It explains the flow (pass a portrait URL and name, then list_creators returns them and the URL can be reused in other tools). It gives a critical usage rule about source and consented parameters, and indicates that saving is free and renders nothing. It does not explicitly name alternatives or state when NOT to use it, but it implies that once saved, you should use list_creators to retrieve existing creators, which is adequate guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
save_playbookSave a playbookAInspect
Save a reusable PLAYBOOK — the strategy takeaways worth re-running: the hooks that work, the angles, the formats, and the concrete plays. Use it to keep what a competitor_teardown or mine_angles just found, or to bank a creative you want to repeat. Lands in the same Playbooks library the web app lists, runs and manages. Distinct from save_skill (a directive applied to every ad) and from the swipefile (raw saved creative). Free.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | the playbook headline — what it is, in a few words | |
| brand | No | which brand this is for (defaults to the workspace brand) | |
| hooks | No | the opening hooks worth reusing, verbatim | |
| plays | No | the concrete plays to run ({title, detail}) — the actionable half | |
| angles | No | the persuasion angles ({title, detail}) | |
| source | No | where it came from, e.g. “teardown · Ridge” | |
| formats | No | the formats/recipes this plays best in (e.g. ugc_selfie, cinematic, static) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations are minimal (readOnlyHint=false, destructiveHint=false, no idempotentHint), so the description carries load. It adds that the playbook lands in the same library the web app lists, runs and manages, and it notes 'Free.' at the end. It doesn't mention overwrite behavior or error cases, but it provides enough behavioral context beyond the empty 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?
Four sentences, front-loaded with the core purpose and destination. The sibling distinctions and the 'Free.' note are concise and each sentence adds value. No redundant phrasing or 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 tool with 7 params (some nested), no output schema, and sparse annotations, the description covers everything an agent needs: what to save, when to use it, how it differs from alternatives, where it lands, parameter semantics, and cost. 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?
Schema coverage is 100%, so baseline 3. The description adds meaning beyond the schema: it explains hooks are 'opening hooks worth reusing, verbatim', plays are 'the concrete plays to run ({title, detail}) — the actionable half', and angles are 'persuasion angles'. It also clarifies formats with examples. This makes parameters more actionable without repeating schema text.
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 the verb 'Save' and the resource 'PLAYBOOK', then explains what a playbook is and explicitly differentiates it from save_skill and the swipefile. It also names the landing library, so an agent can distinguish it from siblings 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?
It gives explicit when-to-use guidance: 'Use it to keep what a competitor_teardown or mine_angles just found, or to bank a creative you want to repeat.' It also names the alternatives (save_skill, swipefile) and describes where the data lands, which effectively covers when not to use this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
save_skillSave a skillAInspect
Save a reusable custom SKILL — a named creative directive/playbook applied to future ads (a hook formula, a UGC recipe, a compliance rule, a named specialist persona like “our founder-story style” or “short-form ad strategist”). Distill an imperative, self-contained directive. Merges into the workspace Skills library (list_skills shows built-ins + your custom skills).
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | short skill name, e.g. “Founder-story hook” | |
| directive | Yes | the full instruction the skill applies when used (1–6 sentences, imperative) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint=false, so it is clear this is a write operation. The description adds that it 'merges into the workspace Skills library', which is useful context about the state change. It does not disclose idempotency or behavior on duplicate names, but with annotations covering the basic write nature, this is acceptable.
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 two sentences, with the purpose front-loaded and concrete examples provided. It is efficient and contains no filler or redundancy.
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?
The description adequately explains what a skill is, how to formulate its directive, and how it integrates with the skills library via list_skills. For a simple two-parameter tool with no output schema, this provides sufficient context for an agent to call it correctly. Minor gaps, such as duplicate-name behavior, are not critical.
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%, with both name and directive fully described. The description adds a general guidance to 'distill an imperative, self-contained directive' which reinforces the schema but does not introduce new parameter-specific information. Baseline 3 is appropriate since the schema does the heavy lifting.
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 the tool saves a reusable custom SKILL, provides concrete examples (hook formula, UGC recipe, compliance rule, persona), and differentiates it from sibling tools like list_skills, get_skill, and delete_skill by referencing the workspace Skills library. It uses a specific verb+resource construction.
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 solid context: it is the save operation for reusable skills, and it mentions list_skills as the way to view built-ins and custom skills, which implies when to use it relative to viewing. However, it does not explicitly state when not to use this vs. other save tools (e.g., save_playbook) or provide exclusion conditions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
save_to_driveSave file(s) to Google DriveAInspect
Save a Hermoso render — or ANY file — into the user’s connected Google Drive. Pass a Hermoso render URL as url (or urls[] for several); for a local/external file, call upload_file first and pass the url it returns. Optional folder (created if new) + name. Returns the Drive file(s) with a webViewLink. Needs Google Drive connected (Settings ▸ Connectors ▸ Google Drive — one connection covers Drive, Sheets and Docs). NOTE: Hermoso uses the drive.file scope, so it reaches ONLY the files it created plus any the user explicitly handed over with the Google file picker in the app — never their whole Drive.
| Name | Required | Description | Default |
|---|---|---|---|
| url | No | a single Hermoso render URL to save | |
| name | No | file name (single save) | |
| urls | No | several render URLs (up to 20) to save in one call | |
| folder | No | Drive folder name to save into (created if new) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already signal write (readOnlyHint: false) and non-destructive (destructiveHint: false). The description adds crucial context beyond that: the drive.file scope limitation (only reaches files created by the tool or user-picked), the connector requirement, and the return of webViewLink. This significantly helps an agent anticipate behavior and constraints.
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 moderately long but every sentence provides value: purpose, parameter usage, prerequisites, return type, and a critical scope note. It is logically ordered, starts with the core purpose, and uses a NOTE to highlight the most important constraint. No fluff.
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 four optional parameters, no output schema, and the need to handle multiple file sources, the description covers all necessary details: different file input paths, connector prerequisite, scope limitation, return format, and folder behavior. It is complete enough for an agent to invoke correctly, though it doesn't detail error cases or pagination (not 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 descriptions cover the parameters (100% coverage), but the description adds meaning: it clarifies the single vs. multiple URL relationship (url vs urls), the required upload_file workflow for non-Hermoso files, and that folder is created if new. This goes beyond the schema's bare definitions.
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 exactly what it does: 'Save a Hermoso render — or ANY file — into the user’s connected Google Drive.' It names the primary resource and the alternative file types, and the verb 'save' clearly separates it from sibling tools like list_drive_files, get_drive_file, update_drive_file, and save_to_onedrive. The scope is 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?
Provides explicit instructions: use url/urls for render URLs, or call upload_file first for local files and pass the returned URL. Also notes the connector requirement and that one connection covers Drive, Sheets, Docs. Does not explicitly mention exclusions vs other Drive operations, but the intent is clear from the 'save' verb and the workflow.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
save_to_onedriveSave file(s) to OneDriveAInspect
Save a Hermoso render — or ANY file — into the user’s connected Microsoft OneDrive. Pass a Hermoso render URL as url (or urls[] for several); for a local/external file, call upload_file first and pass the url it returns. Optional folder (created if new) + name. Returns the OneDrive file(s) with a webViewLink. Needs OneDrive connected (Settings ▸ Connectors ▸ OneDrive).
| Name | Required | Description | Default |
|---|---|---|---|
| url | No | a single Hermoso render URL to save | |
| name | No | file name (single save) | |
| urls | No | several render URLs (up to 20) to save in one call | |
| folder | No | OneDrive folder name to save into (created if new) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate a non-read-only, non-destructive write operation. The description adds valuable extra context: it returns a webViewLink, requires OneDrive to be connected, and creates folders if new. This goes beyond the annotations and schema, though it doesn't cover error handling or duplicate-name behavior.
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 a single, front-loaded sentence that efficiently packs purpose, workflow, return value, and prerequisites. There is no filler or repetition, making it easy for an agent to parse quickly.
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 the tool's simplicity (4 params, no output schema), the description covers the necessary context: return value, prerequisites, and input handling. Minor gaps like explicit limits (up to 20 URLs, already in schema) and error behavior are not critical for successful 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?
Schema description coverage is 100%, so all parameters are documented. The description adds meaning by explaining the relationship between url and urls (singular vs. array) and the upload_file workflow, which clarifies when each parameter is used beyond the schema definitions.
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 verb ('Save') and resource ('Microsoft OneDrive'), and clarifies the scope ('a Hermoso render — or ANY file'). It clearly distinguishes from sibling operations like list/get/update/delete on OneDrive files, and from save_to_drive (Google Drive).
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?
Provides explicit guidance for different input types: pass a Hermoso render URL directly, or call upload_file first for local/external files. Also notes the optional folder (created if new) and the connection prerequisite. Doesn't explicitly name alternatives like save_to_drive, but the OneDrive-specific instructions are sufficient for correct selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
save_to_swipefileSave ads to the swipefileAIdempotentInspect
Save one or more ads/creatives to a named SWIPEFILE collection, creating the collection if it does not exist — the headless twin of the ♥ on every ad card in the web app. Use it whenever research turns up something worth keeping: a competitor ad from search_meta_ads / pull_competitor_ads, an organic post, or one of your own renders. Saved ads persist to the workspace board the web Swipefile tab shows, and feed the taste signal every future ad is planned against. De-dupes: re-saving the same ad (same key/link/media) MOVES it into the named collection instead of duplicating it. Free.
| Name | Required | Description | Default |
|---|---|---|---|
| items | Yes | the ads to save | |
| collection | Yes | the collection name — an existing one, or a new one to create |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate idempotentHint=true, but the description adds valuable behavioral detail: creates the collection if missing, de-dupes by moving rather than duplicating, and is free. It explains persistence and downstream effects on future ad planning. No contradiction with annotations. It stops short of describing error conditions or return values, but the added context is 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 information-dense, with each sentence carrying meaning: action, analogy, usage scenarios, persistence effect, dedupe behavior, and cost. It's longer than minimal but justified by the tool's complexity. The front-loading is good — the primary action and analogy come first. The final 'Free' is slightly extraneous but harmless.
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 tool with no output schema, the description covers the core aspects: what it does, when to use, behavioral details (creation, dedupe, persistence), and root sources. It lacks explicit error handling or return value info, but given that it's a save operation with idempotency hints, this is acceptable. It sufficiently equips an agent 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 description coverage is 100% for both `items` and `collection`, giving baseline 3. The description adds context about the collection being named and creatable, and clarifies the items array types with examples, but does not introduce parameter syntax beyond the schema. It adds nothing critical about the parameters themselves, so a 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 opens with a specific verb+resource ('Save one or more ads/creatives to a named SWIPEFILE collection') and immediately distinguishes itself from siblings by noting it's the 'headless twin of the ♥ on every ad card' — clear differentiation from list_swipefile and export_swipefile_deck. The purpose is singular and 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?
Explicitly states when to use it: 'Use it whenever research turns up something worth keeping' and lists concrete sources (competitor ad from search_meta_ads / pull_competitor_ads, organic post, own renders). It does not name alternative tools or say when not to use it, but the context is clear enough that an agent can decide. It also explains downstream effects (persists to workspace board, feeds taste signal).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
schedule_postSchedule a post for laterAInspect
Queue a post to go out at a future time, to one or more connected channels at once (facebook, instagram, threads, tiktok, youtube, linkedin, x, pinterest, bluesky, telegram — TEN channels, and every one of them is live. google_business is accepted by the schema too but is currently HELD BACK: Google allowlists that API per project and ours reads 0 QPM, so it is refused at enqueue rather than failing hours later). A MULTI-SLIDE creative goes in imageUrls[] as a CAROUSEL, in order — never schedule just its first slide. This is how you run a content calendar: schedule now, and Hermoso publishes at the time you set — you do not need to be around. Either name the exact time in at, or pass useQueue:true to take the brand’s next free POSTING SLOT (its saved posting times, skipping any already occupied) — that is what “just queue it” means and it saves the user picking a minute. Pass a Hermoso render URL as imageUrl/videoUrl (or an upload_file URL for external media). PINTEREST AND YOUTUBE ALSO SHOW A TITLE: pass title (max 100 chars) — omit it and Hermoso derives one from the caption’s first sentence rather than truncating the caption mid-word, which is what a Pin headline used to be. A YOUTUBE ITEM’S CAPTION IS ITS TITLE, NOT ITS DESCRIPTION: pass description (≤5000 chars) for the box under the video — the links, the CTA and everything YouTube search reads — plus tags (up to 30). Omit them and the upload lands with an empty description, which is not recoverable by the time anyone notices. Use captions to give each channel its own wording; anything not listed falls back to message. PER-CHANNEL SETTINGS, all carried straight through to the real publisher: TIKTOK takes the paid-partnership disclosure (brandedContent) and the own-brand one (yourBrand) — set them whenever the post is commercial, they are compliance declarations — plus disableComment and, on a video, disableDuet / disableStitch / coverTimestampMs. GOOGLE BUSINESS takes topicType (STANDARD / EVENT / OFFER / ALERT) with event and offer, and a real actionType button instead of the hard-coded Learn more. X takes a whole thread, a poll, replySettings and madeWithAi. INSTAGRAM takes collaborators — up to 3 usernames invited to CO-AUTHOR the post, which puts it on their profile too once they accept (the invite is sent when the post fires, and is pending until then). Channels are attempted INDEPENDENTLY, so one failing channel never blocks the others. SOME CHANNELS MUST BE TOLD WHICH ACCOUNT, and Hermoso never guesses one: a Pinterest pin needs boardId (list_pinterest_boards) or it is refused outright; a LinkedIn COMPANY PAGE post needs linkedinOrganizationId (list_linkedin_pages) and without it the post goes to the connected person’s own profile; a brand with more than one connected Facebook Page needs pageId (list_meta_pages) and an account managing more than one Google Business listing needs locationId (list_business_locations) — resolve those FIRST and let the user pick, because with several to choose from and no id the post is refused when it fires, hours later. A scheduled post GOES LIVE PUBLICLY by default on every channel — that is what scheduling means, and nothing is ever quietly downgraded to a draft or an unlisted upload. If the user genuinely wants something staged instead, set visibility (or visibilityByChannel for just one channel): ‘public’ (default, live) · ‘unlisted’ (YouTube only — link-only) · ‘private’ (YouTube private, or TikTok posted SELF_ONLY) · ‘draft’ (TikTok drafts, or an unpublished Facebook Page post for a human to publish). Ask for a weaker visibility only if the user asked for one. If a channel cannot do the visibility requested, the call is REFUSED right now with the reason, rather than posting something weaker later. Most channels publish publicly and nothing else: only YouTube has unlisted/private, only TikTok has private/draft, and only Facebook has draft.
| Name | Required | Description | Default |
|---|---|---|---|
| at | No | when to post — ISO timestamp (2026-08-01T09:00:00Z) or epoch milliseconds. Must be in the future, at most 365 days out. Give this OR useQueue, never both. | |
| hook | No | WHAT ANGLE THIS POST IS BUILT ON — the single most valuable field here, and the only moment it can ever be recorded. post_performance groups on it to answer "which hooks work", and it needs 5 posts sharing ONE hook before it will call anything a winner, so REUSE THE SAME WORDING across a campaign instead of rephrasing it every time. Best of all, pass a hook id from list_hooks (e.g. "direct_callout", "mid_problem", "before_after") — those fold onto a stable key however they are spelled, so a whole brand accumulates evidence on one row. Your own wording is fine too; it just only groups when you repeat it exactly. Omitting it means this post can never vote on which hook works. | |
| link | No | a link to attach (Facebook) | |
| poll | No | X — attach a poll: {options:["…","…"], durationMinutes}. 2–4 options of at most 25 characters each; voting runs 5–10080 minutes (7 days), default 1440. X makes a poll MUTUALLY EXCLUSIVE with media, so an item carrying an image or video is refused — schedule the poll as its own X-only post. | |
| tags | No | YOUTUBE — up to 30 search tags for the video (plain words, no #). | |
| event | No | GOOGLE BUSINESS — required for an EVENT or OFFER post: {title, startDate:"YYYY-MM-DD", endDate, startTime:"HH:MM", endTime}. `title` is the EVENT’s headline, a different thing from the post `title` (which is the Pinterest/YouTube one). Google documents its TimeInterval as needing all four date/time parts to be valid, so send the times whenever you know them. | |
| offer | No | GOOGLE BUSINESS — OFFER posts only: {couponCode, redeemOnlineUrl, termsConditions}. redeemOnlineUrl is where an offer actually sends people, since the button link is ignored on an Offer. | |
| title | No | PINTEREST / YOUTUBE — the headline, max 100 characters. Pinterest shows it in search and under the pin; YouTube requires one. Leave it out and Hermoso derives one from that channel’s caption (first sentence, cut on a word boundary, trailing hashtags dropped) — set a real one whenever the caption does not open with a usable headline. | |
| chatId | No | TELEGRAM — REQUIRED whenever telegram is a channel: WHICH chat, group or channel the bot posts to. A public channel’s @username (@hermosoai) or the numeric id (a group is negative; a supergroup or channel starts with -100). There is no default and there cannot be one — the Telegram Bot API publishes no method that lists a bot’s chats — so scheduling telegram without one is refused up front. list_telegram_chats finds ids for chats that have messaged the bot in the last 24 hours. | |
| pageId | No | FACEBOOK / INSTAGRAM / THREADS — which connected Facebook Page (and its linked Instagram) publishes, from list_meta_pages. Needed when the brand has more than one Page connected; with several and no id the post is refused at fire time rather than sent from the wrong brand. | |
| thread | No | X — publish a THREAD, one entry per post, each replying to the one before (at most 25). 280 characters per part without X Premium, up to 25,000 with it — nothing is truncated, and on a Premium account one long post is usually better AND cheaper than a thread. It REPLACES the X caption: with a thread set, `message`/`captions.x` is not sent to X at all. A thread cannot carry a poll. | |
| altText | No | ACCESSIBILITY — the screen-reader description of the attached image. ONE STRING describes the picture; on a CAROUSEL it describes EVERY slide. Pass an ARRAY of strings instead to describe each slide separately, aligned to the slide order — that is strictly better on a multi-slide post, because one sentence read out over six different pictures is wrong for five of them. More descriptions than pictures is refused rather than dropped. Write one whenever the post carries an image: describe what is IN the picture, never a repeat of the caption, which a screen reader already reads. CARRIED BY: X (max 1000, one per media), Pinterest (max 500 — PIN-LEVEL only, since its API has no per-item alt text, so slide 1’s description is used for the whole Pin and the result says the others were not sent), LinkedIn COMPANY PAGES (max 4086, one per slide), INSTAGRAM image posts and image slides (max 1000), FACEBOOK photos and albums, and BLUESKY, whose lexicon makes it REQUIRED on every image. The schedule is REFUSED if the LONGEST description exceeds the tightest of the channels on it, rather than truncated on the way out. NOT CARRIED, and none of these is a refusal — the post still publishes, just undescribed there, and the per-channel result says which: TikTok (its photo post has no alt field at any level), a THREADS CAROUSEL, an INSTAGRAM Reel or video slide, and a LinkedIn PERSONAL-profile post. | |
| boardId | No | PINTEREST — REQUIRED whenever pinterest is a channel: the board the Pin goes on, from list_pinterest_boards. The user picks it; a Pin on the wrong board is a public mistake. Scheduling pinterest without one is refused immediately. | |
| message | No | the caption/text used for every channel unless overridden in captions | |
| subject | No | WHAT THIS POST IS ABOUT — the product, feature, offer or theme (e.g. "winter coat", "free trial", "founder story"). The second grouping axis in post_performance. Same rule as hook: reuse the exact wording so posts about one subject land in one group. | |
| accounts | No | WHICH accounts of a multi-account channel to post to, e.g. { "tiktok": ["@a", "@b"] } or { "tiktok": "all" } — one row per account at fire time, each with its own result. Omit for channels with one account (several and none named is refused by name). | |
| captions | No | per-channel caption overrides, e.g. { "instagram": "…", "threads": "…" } — platforms want different lengths and hashtag conventions | |
| channels | Yes | one or more channels to post to at that time | |
| imageUrl | No | a Hermoso render URL (a /generated path, or what upload_file returned), a data: URI, or a public https URL. NOTE: only Facebook/Instagram/Threads accept an arbitrary public URL — X, TikTok, YouTube, LinkedIn, Pinterest and Google Business re-host the bytes and REFUSE anything that is not a Hermoso render, so run an external file through upload_file first and schedule that url. | |
| timezone | No | IANA zone for the queue, e.g. "America/New_York" — only meaningful with useQueue, and it overrides the brand’s saved zone for this one post. A saved slot of "09:00" is a WALL-CLOCK time, so the zone is what turns it into an instant; without either the brand’s saved zone or this, the queue resolves in UTC. | |
| topicTag | No | THREADS ONLY — one topic tag for the post, without the leading #. | |
| useQueue | No | instead of naming a minute, drop this into the brand’s POSTING QUEUE: Hermoso takes the earliest of its saved posting times that is still free (skipping any slot another queued post already holds). This is the natural answer to “just queue it” / “post it at my next opening”. Mutually exclusive with `at` — passing both is refused rather than one being silently preferred. If the brand has no posting times set, or every slot for the next 90 days is taken, it is refused by name and nothing is scheduled. | |
| videoUrl | No | a Hermoso render URL (a /generated path, or what upload_file returned), a data: URI, or a public https URL — required for youtube, and for tiktok unless you pass an imageUrl (TikTok takes a photo post too). Same origin rule as imageUrl: everything except Facebook/Instagram/Threads REFUSES a non-Hermoso URL, so pass external video through upload_file first. | |
| imageUrls | No | CAROUSEL — an ORDERED list of image URLs to publish as ONE swipeable post on every channel that supports it (Instagram 2–10, Threads 2–20, Facebook, LinkedIn company Pages 2–20, Pinterest 2–5, TikTok up to 35 as a photo post). Use this whenever the creative is a multi-slide deck: a scheduled post carrying only slide 1 of a “1/6 · SWIPE” set is a broken ad that nobody is watching when it fires. THE ORDER IS THE PRODUCT. A channel on this schedule that cannot do carousels — X, YouTube, Google Business Profile — is REFUSED NOW, with the reason, so you can drop it or give it its own single image; it is never quietly downgraded hours later. | |
| slideText | No | PINTEREST CAROUSEL ONLY — per-slide title / description / link, aligned to slide order. Every other platform takes ONE caption for the whole carousel. | |
| topicType | No | GOOGLE BUSINESS — the KIND of Post. STANDARD is the default; EVENT and OFFER both REQUIRE `event` (title + start date), and OFFER also takes `offer`. | |
| trialReel | No | INSTAGRAM TRIAL REEL — publish this Reel to NON-FOLLOWERS ONLY at first, so a hook can be tested on a cold audience without spending it on the people who already follow the brand; Instagram shows it to followers only if it graduates. MANUAL = the creator graduates it by hand in the Instagram app; SS_PERFORMANCE = Instagram graduates it automatically if it performs. REELS ONLY and INSTAGRAM ONLY: an image, a carousel, or a Facebook/Threads channel is REFUSED BY NAME rather than quietly published as an ordinary post — a trial that silently goes to every follower is the exact opposite of what was asked for, so Instagram must be one of the `channels` and the item must carry a video. Omit it for a normal Reel. | |
| yourBrand | No | TIKTOK — the OWN-BRAND disclosure (brand_organic_toggle): true when the post promotes the creator’s own business. TikTok asks for at least one of this and brandedContent once a post is commercial. | |
| actionType | No | GOOGLE BUSINESS — the call-to-action button. Every button except CALL needs `link` (CALL dials the number on the listing and takes none). Google IGNORES the button link on an OFFER post — put the destination in offer.redeemOnlineUrl. Omit and a post carrying a link gets LEARN_MORE. | |
| locationId | No | GOOGLE BUSINESS PROFILE — which listing, e.g. 'locations/123' from list_business_locations. Needed when the account manages more than one storefront; it is never chosen for the user. | |
| madeWithAi | No | X — X’s AI-media label on this post. Opt-in: X treats it as the poster’s own claim about their media, so it is never set on the user’s behalf. | |
| visibility | No | how it should be published — DEFAULT 'public' (live). Only pass something else if the user explicitly asked to stage/hide it. Not every channel supports every value; an impossible combination is refused when you schedule it, with the reason. | |
| aiGenerated | No | INSTAGRAM / FACEBOOK REEL — Meta’s is_ai_generated self-disclosure. OMIT IT and Hermoso decides from provenance: a Hermoso render is declared, media that came through upload_file or from an external URL (the user’s own photographs or footage) is NOT — a real photo must never carry Instagram’s “AI info” label. Pass true or false only to override: false strips the label from something Hermoso would otherwise declare, true declares a render the user uploaded themselves. | |
| communityId | No | X — publish into an X COMMUNITY instead of the main timeline: the number in the community’s own URL (x.com/i/communities/<id>). The connected account must be a MEMBER of it; X answers a non-member and a non-existent id with the same refusal and does not separate them. | |
| description | No | YOUTUBE — the video DESCRIPTION, max 5000 characters: the box under the video carrying the links, the CTA and everything YouTube search reads. It is NOT the caption — a scheduled YouTube item’s text becomes its TITLE — so omitting this publishes the video with an empty description. | |
| disableDuet | No | TIKTOK VIDEO ONLY — block Duets. TikTok’s photo-post API has no Duets, so this is refused on a photo/slideshow item rather than silently dropped. | |
| quotePostId | No | THREADS ONLY — the id of the Threads post this one quotes. | |
| countryCodes | No | THREADS ONLY — two-letter country codes to limit who can see the post. Omit to show it everywhere. | |
| optimizeCopy | No | RECOMMENDED when one caption goes to several channels: fit the shared caption to each channel’s own rules at publish time wherever no per-channel caption was written — YouTube gets a keyword title, a structured multi-paragraph description and search tags; Instagram/TikTok hashtags; LinkedIn longer; X/Bluesky short; Pinterest keyword-rich. The angle and every claim stay the author’s; a channel with its own caption is left exactly as written. Off by default so nobody’s words are rewritten unasked. | |
| privacyLevel | No | TIKTOK — WHICH PRIVACY LEVEL the post goes out at, in TikTok’s own vocabulary. TikTok requires the USER to choose this from the levels their own account allows: call tiktok_creator_info, show them the real options, and pass back the one they picked — never a default and never a guess, which TikTok refuses at init. Omit it and the post falls back to the coarse `visibility` (private → SELF_ONLY, otherwise PUBLIC_TO_EVERYONE), which cannot express MUTUAL_FOLLOW_FRIENDS or FOLLOWER_OF_CREATOR at all. It must agree with the TikTok visibility (SELF_ONLY is the private one) and it is refused on a TikTok DRAFT, which carries no post info. | |
| replyControl | No | THREADS ONLY — who may reply. Omit for Threads' own default (everyone). | |
| xQuotePostId | No | X — the numeric id of an X post this one QUOTES: the last part of its URL. X renders that post inside yours and it stands alone on your own timeline, which is what makes a quote different from a reply. NAMED xQuotePostId, NOT quotePostId, because `quotePostId` on this same schedule belongs to THREADS — a schedule going to both channels would otherwise be silently ambiguous. Billed at X’s higher LINK rate, because X appends the quoted post’s t.co URL to yours. | |
| collaborators | No | INSTAGRAM — a COLLAB post: up to 3 Instagram usernames invited to CO-AUTHOR it, so it appears on their profile too once they accept, with both handles in the header and the engagement shared. Handles only ("hermosoai"); a leading @ is fine. Instagram must be one of the `channels` — asking for collaborators on a schedule Instagram is not on is REFUSED now rather than discovered when it fires, and the other channels in a mixed schedule simply publish without co-authors. THE INVITE IS SENT WHEN THE POST FIRES, not when you schedule it, and it is PENDING until the other account accepts in their notifications; check with instagram_collaborators afterwards rather than telling the user it is live on both profiles. | |
| disableStitch | No | TIKTOK VIDEO ONLY — block Stitches. Same photo-post rule as disableDuet. | |
| replySettings | No | X — who may reply. Omit for everyone, which is the right default for a brand post. | |
| brandedContent | No | TIKTOK — the PAID-PARTNERSHIP disclosure (TikTok’s brand_content_toggle): true when this post promotes a THIRD-PARTY business. It is a compliance declaration, not a preference — set it whenever the post is sponsored. TikTok only accepts branded content on a public or friends-only post, so it cannot ride a private/SELF_ONLY or draft TikTok item and the schedule is refused with the reason. | |
| disableComment | No | TIKTOK — turn comments off on this post. | |
| linkAttachment | No | THREADS ONLY — a full http(s) URL rendered as a link card. This is the ONLY way a Threads post carries a destination, and Threads attaches it to TEXT-ONLY posts (a post with media cannot also carry a card). | |
| paidPartnership | No | X — label the post a PAID PARTNERSHIP, the same disclosure Hermoso already ships for TikTok. OPT-IN ONLY: set it when the post is sponsored, gifted or otherwise paid for, and never assume it on the user’s behalf. | |
| coverTimestampMs | No | TIKTOK VIDEO ONLY — which frame TikTok uses as the cover, in milliseconds from the start. Omit and TikTok uses the first frame. | |
| crossreshareToIg | No | THREADS ONLY — when this fires, ALSO share it to the linked Instagram account as a STORY. Refused on a Threads carousel. No confirmation exists that the Story was created, so the result says it was requested. | |
| commercialContent | No | TIKTOK — the COMMERCIAL CONTENT DISCLOSURE toggle: true when the post promotes a brand, product or service at all. TikTok requires at least one of yourBrand / brandedContent alongside it, and a post declaring itself commercial without naming which kind is refused. Setting either disclosure already implies this, so it is only needed to be explicit. | |
| visibilityByChannel | No | override visibility for one channel, e.g. { "tiktok": "draft" } to go live everywhere but stage TikTok for review | |
| crossreshareDarkMode | No | THREADS ONLY — render that Instagram Story in dark mode. Needs crossreshareToIg. | |
| linkedinOrganizationId | No | LINKEDIN — publish as a COMPANY PAGE instead of the connected personal profile. The organization id from list_linkedin_pages. Omit and it posts as the person: an unset id means the profile, never “probably the company”. A Page can also carry VIDEO, which a personal profile cannot. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=false, destructiveHint=false, openWorldHint=true, idempotentHint=false, but the description significantly enriches this: it discloses that channels are attempted independently so one failure never blocks others, that posts go LIVE PUBLICLY by default and are never quietly downgraded, that refusals happen at enqueue rather than hours later, and that Google Business is currently held back with 0 QPM. The description contradicts none of the annotations — the only small gap is that it doesn't explicitly say whether a successfully scheduled post can be canceled/rescheduled (though sibling tools exist for that).
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 extremely long and dense — over 1000 words of almost continuous prose without paragraph breaks. While nearly every sentence carries information, the wall-of-text format forces an agent to parse through everything to find what's relevant to a specific call. The most critical operational constraints (channels going live publicly, needing boardId/pageId/linkedinOrganizationId/locationId, refusing unsupported visibility) are buried mid-paragraph rather than front-loaded. This is content-rich but structurally poor for quick agent consumption; the schema itself already covers 100% of parameter meanings, so much of this text is redundant with the parameter 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?
For a 55-parameter tool with no output schema, the description is remarkably complete: it covers scheduling semantics, per-channel requirements, refusal behavior, visibility rules, ID resolution, compliance disclosures (brandedContent, commercialContent, paidPartnership, yourBrand), media origin rules (Hermoso render vs external URLs), alt-text carrier matrix, trial reel behavior, and the queue mechanism. There is no obvious scenario an agent would face that the description doesn't anticipate.
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 substantial meaning: it explains the relationship between `at` and `useQueue` as mutually exclusive with refusal rather than silent preference, clarifies that `hook` is the single most valuable field for grouping post_performance data, warns that `imageUrls` on a channel that can't do carousels is refused now, and gives the exact semantics of `title` derivation for Pinterest/YouTube. It also resolves ambiguity between `quotePostId` (Threads) and `xQuotePostId` (X). This goes well beyond the schema's descriptions.
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 opens with a precise verb+resource combination: 'Queue a post to go out at a future time, to one or more connected channels at once' — this clearly differentiates from sibling tools like post_to_meta, post_to_x, post_to_tiktok, and reschedule_post. It explicitly names the TEN live channels plus the held-back google_business, making the scope unmistakable.
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 explicitly tells when to use this vs alternatives: 'This is how you run a content calendar', names the alternative sources for required IDs (list_pinterest_boards, list_linkedin_pages, list_meta_pages, list_business_locations, list_telegram_chats), and gives the direct contrast with single-channel posting tools. It also states exactly when to pass useQueue vs at, and warns when the call would be refused.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
score_adScore adARead-onlyInspect
Virality/performance prediction for a finished ad (image or video URL): overall score, per-dimension breakdown (scroll-stop, hook, clarity, brand/product, CTA, retention, goal fit), strengths, and the single biggest fix. Use BEFORE spending on distribution, or to rank variants.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | the ad asset URL (a /generated/ path or public URL) | |
| kind | No | 'image' (default) or 'video' | |
| intent | No | what the ad is trying to achieve, for goal-fit scoring |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already convey read-only and non-destructive behavior, so the description doesn't need to restate that. It adds context on what the prediction covers (e.g., goal fit, retention) but doesn't disclose limitations like URL accessibility or auth requirements. This is adequate but not rich beyond 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?
Two sentences with zero fluff. The first sentence front-loads the core function and output, the second gives usage guidance. Every clause earns its place, making it easy for an agent to parse quickly.
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 prediction tool with fully documented parameters and read-only annotations, the description covers the essential output (score, dimensions, strengths, fix) and usage timing. It doesn't discuss error handling or performance caveats, but these are minor given the tool's simplicity and annotation coverage.
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 descriptions cover all three parameters (url, kind, intent) at 100% coverage, so the baseline is 3. The description adds minimal extra meaning—only implicitly linking intent to goal-fit scoring via the per-dimension list. It doesn't provide syntax or format details beyond 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?
The description states a specific verb ('prediction') and resource ('ad'), and details the output: overall score, per-dimension breakdown, strengths, and biggest fix. This clearly distinguishes it from sibling tools like plan_ad or render_ad, which focus on creation rather than evaluation.
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 'Use BEFORE spending on distribution, or to rank variants', giving clear context on when to invoke. While it doesn't name alternatives or provide exclusions, the timing guidance is actionable and sufficient for an agent to select this tool appropriately.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_google_adsSearch Google adsARead-onlyInspect
Structured Google Ads Transparency pull for ONE advertiser (by domain or advertiserId) — use when you know the brand; use research_ads for open-ended research. Deliberately fetches the cheap BASIC listing (get_ad_details=false, ~1 credit — the detailed variant with per-ad headlines costs 25 credits/call and is not exposed here). Returns compact JSON {advertiser, format, adUrl, image, firstShown, lastShown} per ad.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | max ads returned (1–25, default 8) | |
| domain | No | the advertiser's domain, e.g. nike.com | |
| region | No | 2-letter region, default US | |
| advertiserId | No | Google advertiser id (AR…) when the domain is ambiguous |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and destructiveHint, so the safety profile is covered. The description adds valuable behavioral detail: it deliberately fetches the low-credit BASIC variant and explains the detailed variant is not exposed, plus the exact return JSON shape. This goes beyond annotations without 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?
Two dense sentences with zero waste. Every clause adds new information: purpose, usage, credit cost, return format, and an alternative. The key differentiator (known brand vs open-ended) is front-loaded, and the cost/return specifics are packed efficiently.
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 lookup with optional parameters and no output schema, the description is complete: it states the return format, the intended use case, the alternative for open-ended research, and the cost trade-off. With annotations covering security, nothing an agent needs to invoke 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% — every parameter has a description, so the schema does the heavy lifting. The description does not add new meaning beyond echoing domain vs advertiserId, so the baseline of 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 clearly states it is a 'Structured Google Ads Transparency pull for ONE advertiser' with specific identifiers, and explicitly contrasts with research_ads. This differentiates it from sibling ad-search tools and tells the agent exactly what resource it acts on and the scope.
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 'use when you know the brand; use research_ads for open-ended research.' Also explains it fetches the cheap BASIC listing, implying when cost matters. This is unambiguous when-to-use guidance with a named alternative.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_instagramSearch InstagramARead-onlyInspect
Organic Instagram REELS keyword search (/v2/instagram/reels/search — our only IG keyword surface; profile/hashtag pulls go through fetch_social_data with a handle). Returns compact JSON {desc, author, handle, plays, likes, link, cover} per reel, ranked by plays. Spends about a credit.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | max reels returned (1–25, default 8) | |
| query | Yes | keyword to search reels for |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint=true and destructiveHint=false, so the safety profile is clear. The description adds behavioral context beyond annotations: it specifies the endpoint, notes the 'organic' nature, indicates a credit cost, and describes the compact JSON return format and ranking by plays. This extra transparency about cost and return format is valuable.
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 sentences with zero redundancy. The primary purpose and unique surface are stated first, followed by the output format and cost. Every sentence earns its place, and the description is well-structured and easily scannable.
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 the tool's low complexity (2 parameters, no output schema), the description is complete: it explains the endpoint, differentiates from siblings, details the return fields, notes the ranking criterion, and mentions the credit cost. No essential information is missing for an agent 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 description coverage is 100%, with both 'query' and 'limit' documented ('keyword to search reels for' and 'max reels returned (1–25, default 8)'). The description does not add additional meaning to the parameters themselves beyond the schema; it only mentions output format and cost. Hence, the baseline of 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 states a specific verb ('search'), resource ('Instagram REELS'), and scope ('keyword search'), names the exact endpoint, and explicitly distinguishes it from other IG surfaces ('our only IG keyword surface; profile/hashtag pulls go through fetch_social_data'). It also describes the output structure and ranking, making the purpose unmistakable.
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 explicitly tells when to use this tool vs alternatives by noting it is the only keyword surface and that profile/hashtag pulls go through fetch_social_data. It also mentions the credit cost, which helps in decision-making. No other usage guidance is needed for a simple search tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_linkedin_adsSearch LinkedIn adsARead-onlyInspect
Structured LinkedIn Ad Library search by company name, keyword, or companyId — use for a targeted B2B pull; use research_ads for open-ended research. Returns compact JSON {advertiser, headline, description, cta, link, media, dates, impressions} per ad — LinkedIn is the one library exposing real impression counts. Spends about a credit.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | max ads returned (1–25, default 8) | |
| company | No | advertiser company name | |
| keyword | No | keyword across all advertisers | |
| companyId | No | LinkedIn company id (numeric) when the name is ambiguous | |
| countries | No | CSV of 2-letter codes like 'US,CA'; omit or 'ALL' = worldwide |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover readOnlyHint=true and destructiveHint=false, so the safety profile is known. The description adds valuable context: the return format (compact JSON with specific fields), the unique advantage (LinkedIn exposes real impression counts), and a cost warning ('Spends about a credit'). This goes beyond what annotations provide without 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 two sentences with zero filler. The core purpose is front-loaded, followed by the usage distinction, then the return format and unique value proposition. Every sentence earns its place and the structure is optimal for quick agent parsing.
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 the tool has annotations covering safety, a fully documented schema, and a brief description of the output format (compact JSON with fields), the description covers the essentials. It does not mention pagination or default ordering, but these are not critical for a search tool and the schema covers the limit parameter. It is sufficiently complete for an agent to invoke 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?
The input schema has 100% coverage with descriptions for all 5 parameters (limit, company, keyword, companyId, countries), so the baseline is 3. The description only mentions three of the parameters (company name, keyword, companyId) and adds no additional syntax or format details beyond what the schema already documents, so it does not elevate above the baseline.
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 the exact action (structured LinkedIn Ad Library search) and the searchable fields (company name, keyword, or companyId). It also explicitly differentiates itself from the sibling tool research_ads by framing this as 'targeted B2B pull' versus 'open-ended research', so an agent can easily decide which to use.
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 direct when-to-use instruction ('use for a targeted B2B pull') and explicitly names the alternative tool ('use research_ads for open-ended research'). This leaves no ambiguity about the context for this tool versus its sibling.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_meta_adsSearch Meta adsARead-onlyInspect
Structured Meta (Facebook/Instagram) Ad Library pull — use when you know exactly WHAT to fetch: a keyword (query) OR one advertiser (companyName / pageId). Returns compact JSON {page_name, body, cta, link, dates, media} per ad. For open-ended research that needs judgment across platforms, use research_ads instead. Spends a credit or two.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | max ads returned (1–25, default 8) | |
| query | No | keyword search across ALL advertisers (use INSTEAD of companyName/pageId) | |
| pageId | No | one advertiser’s ads by Facebook page id (most precise) | |
| status | No | ACTIVE = currently running; default ALL (includes proven past winners) | |
| country | No | 2-letter code or 'ALL' (default ALL) | |
| mediaType | No | filter by creative type (default ALL) | |
| companyName | No | one advertiser’s ads by brand name |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, so the description doesn't need to repeat safety. It adds behavioral details beyond annotations: cost ('Spends a credit or two') and return format ('Returns compact JSON {page_name, body, cta, link, dates, media} per ad'). It doesn't reveal pagination or empty-result behavior, but the annotations cover the core safety profile, making this a solid 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?
The description is four sentences with zero fluff. The core purpose and usage guidance are front-loaded, cost is mentioned concisely, and the return format is succinctly defined. Every sentence 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?
With no output schema, the description provides the return structure explicitly. It covers cost, usage context, and names the alternative tool. It lacks pagination details or limits beyond the 'limit' parameter, but for a 7-parameter tool with full schema coverage and clear annotations, it is complete enough for an agent to call 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 100% with detailed parameter descriptions, so the baseline is 3. The description adds value by clarifying the mutual exclusivity rule: 'a keyword (query) OR one advertiser (companyName / pageId)'. This is not present in the schema and helps an agent choose between parameters correctly, raising the score to 4.
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 ('Structured Meta (Facebook/Instagram) Ad Library pull') and the resource, and explicitly names the sibling tool it is not ('For open-ended research... use research_ads instead'). It clearly distinguishes itself from other search tools like search_google_ads by framing it as a precise pull when you know exactly what to fetch.
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 explicit usage conditions ('use when you know exactly WHAT to fetch') and names the alternative for open-ended research ('use research_ads instead'). It also adds practical cost guidance ('Spends a credit or two'), which is valuable for an agent deciding when to call this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_redditSearch RedditARead-onlyInspect
Reddit keyword search (/v1/reddit/search, top-ranked) — a goldmine for the customer's OWN words (pain points, objections, language) to mine into ad hooks and copy. Returns compact JSON {desc (title+selftext), subreddit, upvotes, comments, link} per post. Spends about a credit.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | max posts returned (1–25, default 8) | |
| query | Yes | what to search Reddit for |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, so the description's job is to add extra behavioral context. It does so by disclosing the credit cost ('Spends about a credit.') and the exact return shape (compact JSON with fields), which are not covered by annotations. This adds meaningful behavioral detail without contradicting 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 description is two concise sentences, front-loaded with the primary purpose and endpoint, then covering return format and cost. Every sentence earns its place with no fluff or redundancy.
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 search tool with no output schema and fully documented parameters, the description covers the essential points: purpose, return payload structure, and cost. It omits details like rate limits or pagination, but these are minor for a simple search tool and the description is sufficiently complete 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?
Schema description coverage is 100%, so both parameters (query, limit) are already documented. The description does not add new parameter-specific semantics beyond the schema; it only reiterates the general use case. Given the high schema coverage, 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 states a specific verb and resource: 'Reddit keyword search' with the endpoint, and clarifies its purpose as mining customer language for ad hooks. It is clearly distinct from other sibling search tools by platform, and the 'top-ranked' note signals its preferred status.
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 use case (mining customer words for ad hooks and copy) but does not explicitly state when to choose Reddit over sibling search tools like search_tiktok or search_youtube. It lacks explicit when-not-to-use guidance or exclusions, relying on the user to infer platform relevance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_threadsSearch ThreadsARead-onlyInspect
Organic Threads keyword search (/v1/threads/search) — short-form text/social posts for trend + voice research. Returns compact JSON {desc, author, handle, likes, link, cover} per post. Spends about a credit.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | max posts returned (1–25, default 8) | |
| query | Yes | keyword to search Threads for |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, openWorldHint=true, and destructiveHint=false, covering the safety profile. The description adds value by disclosing the cost ('Spends about a credit') and the exact return format (compact JSON fields per post), which is useful behavioral context not present in 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?
Two tight sentences front-load the purpose and endpoint, then deliver return format and cost. There is no filler or redundancy; every sentence 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?
The description compensates for the lack of an output schema by specifying the per-post JSON fields. It also covers cost and use case, which is sufficient for a low-complexity read-only tool. Minor gaps like rate limits and pagination details remain, but they are not critical given the schema already documents limit defaults.
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%: both parameters (`query` and `limit`) have descriptions in the schema. The description does not add parameter-specific meaning beyond what the schema already provides, so the baseline score of 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 clearly states a specific verb ('search'), a resource ('Organic Threads keyword search'), and an endpoint, with an explicit use case ('trend + voice research'). However, it does not explicitly differentiate from the sibling tool 'search_threads_keyword', which appears to serve a nearly identical purpose, so it misses full sibling distinction.
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 the intended context ('short-form text/social posts for trend + voice research') but does not mention when to avoid using it or name any alternatives. There is no explicit guidance about choosing this over search_threads_keyword, search_instagram_hashtag, or other search tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_tiktokSearch TikTokARead-onlyInspect
Organic TikTok keyword search (there is NO TikTok ad library) — top-performing videos to mine for hooks/trends/remixable creative. Returns compact JSON {desc, author, handle, plays, likes, link, cover} per video, ranked by plays. Use research_ads for open-ended research. Spends about a credit.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | max videos returned (1–25, default 8) | |
| query | Yes | keyword or hashtag (no # needed) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, openWorldHint=true, and destructiveHint=false, so the safety profile is covered. The description adds valuable behavior beyond that: credit spend ('Spends about a credit'), output format (compact JSON with specific fields), ranking by plays, and the notice that there is no ad library. This is genuinely additive.
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 three sentences: the first establishes what it does, the second details the return format, and the third names the alternative and cost. Every sentence earns its place, the content is front-loaded with the core purpose, and there is zero fluff.
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 tool with two simple parameters and no output schema, the description covers the essentials: purpose, output structure, ranking, credit cost, and the alternative for open-ended research. Nothing an agent needs to invoke it correctly is missing, and the annotations already handle safety.
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% — both query and limit are fully described in the schema. The description does not add any parameter-specific meaning (e.g., no elaboration on query syntax or limit behavior) beyond what the schema provides. Baseline 3 is appropriate since the schema carries the load.
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 opens with 'Organic TikTok keyword search' — a specific verb and resource — and immediately clarifies it's organic (not an ad library). It states the use case (mine hooks/trends/remixable creative) and names the sibling tool it is not. This is fully differentiated from other search tools like search_instagram or search_youtube.
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 'Use research_ads for open-ended research', giving a clear alternative and the condition that selects it. The description also implies this is for keyword-driven, top-performing content, which sets expectations for when to invoke this tool versus alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_youtubeSearch YouTubeARead-onlyInspect
Organic YouTube keyword search (/v1/youtube/search) — videos to mine for hooks/angles/long-form structure. Returns compact JSON {desc (title), author, handle, plays, link, cover} per video, ranked by views. Spends about a credit.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | max videos returned (1–25, default 8) | |
| query | Yes | keyword to search videos for |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is covered. The description adds value beyond that by disclosing credit cost, 'Organic' (non-paid) nature of results, and ranking behavior ('ranked by views'). No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two efficient sentences with zero waste. Purpose is front-loaded, the return format is compactly specified as a JSON key list, and the cost warning earns its place. Nothing redundant.
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?
Complete for a simple 2-param search tool. Annotations cover safety, schema covers the parameters, and the description explains the return format (compact JSON fields), ranking, purpose, and cost. No output schema exists, but the description explicitly enumerates response fields, so nothing an agent needs 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 100%, so both query and limit are already documented with descriptions. Out of curiosity, the description adds the 'ranked by views' context that clarifies how limit interacts with result ordering, but it doesn't add meaningful syntax or format details beyond the schema. 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 (search), resource (YouTube), and endpoint (/v1/youtube/search), plus the intent ('videos to mine for hooks/angles/long-form structure'). It clearly distinguishes itself from sibling search tools like search_tiktok and search_instagram, and from the many youtube_* management tools (post_to_youtube, update_youtube_video, etc.).
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 context for use — organic keyword search for mining hooks/angles/long-form structure — which tells an agent when this is the right research tool. It also discloses the cost ('Spends about a credit'). However, it doesn't explicitly name alternatives or state when-not-to-use, so an agent must infer that other search tools (search_tiktok, search_threads) are the choice for other platforms.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_auto_reloadSet auto-reloadAIdempotentInspect
Turn automatic credit reloads on or off (admin only): when the balance drops below a threshold, the card on file is charged for a top-up pack — SERVER-SIDE, even with no app open. Requires a saved card, added once in the app at first checkout/top-up; if there's none the tool tells you exactly where to add it. After that one-time card setup, agents can manage auto-reload, top-ups and plan links fully. Members (read-only billing) get an 'ask an admin' message.
| Name | Required | Description | Default |
|---|---|---|---|
| enabled | Yes | true to turn auto-reload on, false to turn it off | |
| reloadCredits | No | how many credits to add each reload — must match a credit pack size (see buy_credits) | |
| thresholdCredits | No | reload when the balance drops below this many credits |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds behavioral context beyond the annotations: it explains the operation runs server-side even without the app open, requires a saved card, and that members are blocked with a specific message. It also mentions the tool will guide the user if no card is present. Annotations already indicate idempotent and non-destructive, and the description aligns without contradicting. These extra details help the agent anticipate side effects and prerequisites.
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 moderately long but front-loaded with the primary action and then elaborates on prerequisites and access control. Each sentence adds meaningful information: the server-side behavior, the card requirement, the member restriction. It is not overly verbose and the structure is logical, though it could be tightened slightly without losing value.
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 tool with no output schema and three parameters, the description covers the key conditions: admin-only access, prerequisite of a saved card, server-side execution, and member handling. It also references buy_credits for pack-size details. It does not explicitly state the return value or error handling, but given the tool's simplicity and lack of output schema, this is adequate. The description is sufficiently complete for an agent 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?
The input schema provides 100% description coverage for all three parameters, so the baseline is 3. The description does not add additional parameter-specific semantics beyond what the schema already states. It does frame the threshold and top-up concept in the narrative, but that is more contextual than parameter-explanatory. No extra meaning is provided for the parameters themselves.
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 the action ('Turn automatic credit reloads on or off') with a specific resource (credit reloads) and scope (admin only). It provides context about the mechanism (threshold, top-up pack, server-side). However, it does not explicitly distinguish itself from sibling tools like buy_credits or billing_status, so it lacks direct differentiation but still conveys a precise purpose.
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 some usage guidance: it mentions the tool is admin-only and that members (read-only billing) receive an 'ask an admin' message, which indicates who should not use it. It also states the prerequisite of a saved card and notes that without one the tool guides the user. However, it does not explicitly compare with alternatives or state when to use this tool versus manual top-ups or buying credits, so the guidance is partial.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_competitor_watchSet the competitor watchAIdempotentInspect
Set (or STOP) this workspace's standing COMPETITOR WATCH — the weekly job that re-checks each named brand's ad libraries and reports what is NEW since last time. The same watch the web app's Ad Spy ▸ Watching tab manages, and the same one the weekly digest email is sent from (turn that email on/off with update_settings({watchEmail})). This REPLACES the whole watched list, it does not add to it — pass every brand you want watched, every time. Max 5 brands (the server trims past that). Pass an EMPTY list to stop the watch entirely, which also clears the findings. Give a domain wherever you know one: Google Ads Transparency is looked up BY DOMAIN and is skipped for a brand without one, and the domain is what resolves the right Meta page for a brand with an ambiguous name. The run itself spends credits against the ad libraries (roughly 3 per brand on Meta, 1 each on Google and LinkedIn) and is hard-capped per run server-side, so an oversized watch is trimmed rather than allowed to run away. Setting the list is free; only a run spends. runNow:true runs it once IMMEDIATELY (a background job — it spends now) and then keeps the weekly cadence; leave it off and the first check is a week out. The country and the platform mix are NOT settable here — a re-set inherits whatever the pending run already carried (US / Meta for a watch that has never been configured otherwise). Read the findings back with list_watch_findings.
| Name | Required | Description | Default |
|---|---|---|---|
| runNow | No | true to run one check immediately (spends credits now) instead of waiting a week for the first one | |
| competitors | Yes | the brands to watch — the COMPLETE list, replacing whatever was set before. Empty array = stop watching. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations indicate readOnlyHint=false, idempotentHint=true, and destructiveHint=false. The description goes well beyond this by detailing that empty list stops the watch and clears findings, that setting is free but running spends credits, that the server trims past 5 brands, that runNow triggers an immediate background run, and that country/platform are inherited. This is rich behavioral context with no contradiction.
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 long but every sentence carries essential information: purpose, replacement semantics, credit costs, trimming, runNow behavior, inheritance, and a pointer to the related read tool. It is front-loaded with the core purpose and then details, with no fluff.
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 tool with no output schema and two parameters, the description covers all necessary aspects: what it does, when to use, side effects (credit spending, clearing findings), constraints (max 5, domain requirement), and how to read results. Nothing essential is missing for an agent 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 already describes both parameters, but the description adds substantial meaning: competitors is the complete list (replacing old), empty array stops the watch, max 5 trimmed, domain is needed for Google and disambiguates Meta; runNow spends credits now and runs immediately. This goes well beyond the schema's field descriptions.
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 the tool sets or stops a standing competitor watch — a weekly job that re-checks brands' ad libraries and reports new findings. It distinguishes this from sibling tools like list_watch_findings (for reading back) and find_competitors (one-time discovery) by emphasizing the recurring, standing nature.
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 explains when to use it (to set or stop the watch) and provides context about the weekly cadence, credit spending, and that it replaces the whole list. It points to list_watch_findings for reading results, but it does not explicitly state when to prefer a different tool (e.g., find_competitors for one-off searches) — the context is clear but exclusions are only implicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_connector_accountsChoose which accounts a brand may useAIdempotentInspect
Set WHICH of a connector's accounts this brand is allowed to post to and spend from — Facebook Pages / Instagram / Meta ad accounts, Google Ads customers, LinkedIn company Pages (and the personal profile), Pinterest or Microsoft Advertising ad accounts. Pass ids from list_connector_accounts. This REPLACES the current selection: anything you leave out is un-shared, and an EMPTY list shares nothing (publishing then refuses — it fails closed by design, and the server re-verifies every id against the live connection, so an id the account cannot actually reach is rejected rather than saved). Ask the user which accounts they mean; posting as the wrong Page is a public mistake. Providers: tiktok, x, youtube, threads, bluesky, telegram, reddit, pinterest, instagram, meta, google_ads, linkedin, pinterest_ads, linkedin_ads, reddit_ads, apple_ads, microsoft_ads, google_business, google_analytics, snapchat_ads, x_ads, tiktok_ads, google_tag_manager, google_search_console, bing_webmaster. Free.
| Name | Required | Description | Default |
|---|---|---|---|
| provider | Yes | which connector to scope | |
| accountIds | Yes | the ids (from list_connector_accounts) this brand may use — an empty array shares nothing |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare idempotentHint=true and destructiveHint=false, but the description goes much further: it discloses that the operation REPLACES the current selection, anything omitted is un-shared, empty list shares nothing, failing closed by design, and the server re-verifies each id against the live connection and rejects unreachable ids. This is rich behavioral context 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 core behavioral semantics are front-loaded in the first two sentences, followed by user guidance and provider list. It is somewhat long with the provider list, but the provider list is not repeated in the schema? Actually schema has enums; the list is redundant with the enum, making it slightly longer than necessary. Still well-organized and every sentence carries meaningful guidance.
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 2-param tool with complete schema coverage and no output schema, the description covers what the tool does, how ids are sourced, failure behavior, and user guidance. It does not specify a return value, but no output schema exists and the behavior is sufficiently clear. Slight deduction for not stating what happens on success in terms of response, but this is minor.
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 the schema already documents both parameters. The description adds contextual meaning by clarifying accountIds are ids from list_connector_accounts and that an empty array shares nothing, which mirrors but slightly enriches the schema. 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?
Description clearly states the verb 'Set' and resource: which connector accounts a brand may post to and spend from. It enumerates specific account types (Facebook Pages, Instagram, Google Ads customers, LinkedIn Pages, etc.) and how ids are passed. Distinguishes itself from list_connector_accounts.
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 to pass ids from list_connector_accounts, which is the sibling that produces the input. Describes the replace semantics and empty-list behavior, and instructs the agent to ask the user which accounts they mean because posting as the wrong Page is a public mistake. That is clear when-to-use guidance and what-not-to-do.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_post_refillConfigure the posting refillAIdempotentInspect
Turn the automatic posting refill on or off and set how it behaves. PASS ONLY WHAT CHANGES. enabled:false is the PAUSE — it removes the recurring job outright, and posts already queued are left alone (cancel those with cancel_scheduled if you want them gone). It starts in dryRun, which plans and previews without queueing; set dryRun:false only once a human has read a preview from run_post_refill. THE CADENCE IS THE BRAND’S POSTING TIMES, not a number here: three posting times means three posts a day. Raising maxImagesPerDay / maxVideosPerDay / maxCreditsPerDay above 0 lets it SPEND on new creative — at 0 (the default) it only reuses renders already in the Library and costs nothing.
| Name | Required | Description | Default |
|---|---|---|---|
| chatId | No | TELEGRAM — which chat, group or channel posts go to (@username or numeric id). Without one, telegram is skipped: there is no default chat and posting to the wrong one is a public mistake. | |
| dryRun | No | true (the default) = plan and preview only, queue nothing. Set false ONLY after a human has read a preview. | |
| pageId | No | FACEBOOK / INSTAGRAM / THREADS — which connected Page to publish from (list_meta_pages). Omit for the brand’s only Page. | |
| boardId | No | PINTEREST — which board Pins go on (list_pinterest_boards). Without one, Pinterest is skipped: a Pin on the wrong board is a public mistake, so it is never guessed. | |
| enabled | No | on/off. false PAUSES it: the recurring job is deleted and nothing new is queued. Already-queued posts are untouched. | |
| channels | No | restrict it to these channels. Omit (or send an empty list) to use every connected channel that can carry each post. | |
| daysAhead | No | how far ahead to keep the queue full, 1–30 (default 7) | |
| postsPerDay | No | cap the posts per day BELOW the number of posting times. 0 (default) = use every posting time, which is where "3 a day" comes from. To post MORE per day, add posting times instead. | |
| maxImagesPerDay | No | how many NEW images a day it may render when the Library runs dry. 0 (default) = none, spend nothing. | |
| maxVideosPerDay | No | how many NEW videos a day it may render. 0 (default) = none. Video is the expensive one — hundreds of credits each. | |
| maxCreditsPerDay | No | a hard credit ceiling per day, checked BEFORE any render starts. It binds independently of the counts above. | |
| assetCooldownDays | No | how long before a Library render may be posted again (default 30). It never repeats one inside this window — it queues fewer posts and says so. | |
| linkedinOrganizationId | No | LINKEDIN — which company Page to post as (list_linkedin_pages). A single shared Page is used automatically; a Page that is not shared with this brand is ignored rather than failing the whole post. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses key behaviors beyond annotations: enabled:false removes the recurring job outright, dryRun defaults to planning-only, and spending behavior is gated by max counts/credits. It also explains that at 0 it only reuses Library renders and costs nothing, which is non-obvious. Annotations only state readOnly=false, destructive=false, idempotent=true, so the description adds substantial behavioral context without contradiction.
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 action and uses ALL CAPS for emphasis on critical rules. It is a bit long but every sentence carries information (pause behavior, dryRun, cadence, spending). Slight verbosity from the capitalization style, 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 complex tool with 13 parameters and no output schema, the description covers the most critical operational nuances: Pause vs. disable, dryRun preview flow, and cost control. It references the relevant sibling tools for preview and cancellation, and the schema handles per-parameter details. Nothing essential is missing for an agent to call this 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 100% so each parameter is already described. The description adds global semantics not in the schema: 'PASS ONLY WHAT CHANGES,' the relationship between posting times and postsPerDay, and the spending logic tied to maxImagesPerDay etc. This goes beyond a 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?
The description opens with a clear verb and resource: 'Turn the automatic posting refill on or off and set how it behaves.' It distinguishes itself from siblings like run_post_refill (preview) and cancel_scheduled (cancel queued posts) by explicitly referencing them, making it unambiguous what this tool does versus its alternatives.
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 provides explicit when-to-use and alternative guidance: use cancel_scheduled to remove already-queued posts, read a preview from run_post_refill before disabling dryRun, and notes the cadence comes from brand posting times rather than a numeric parameter. It also instructs 'PASS ONLY WHAT CHANGES,' which clarifies partial-update usage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_product_imageSet product photoAIdempotentInspect
Lock an image as the ad's real PRODUCT photo and SAVE it as this brand's default product, so every later plan_ad / render_ad / generate_image grounds on the true packaging without being told again. Pass imageUrl = a product shot's URL — an image from a prior research result (an organic Instagram/TikTok post, a scraped page image), a workspace / list_product_photos url, or any public product photo. The server downloads it and runs a product+safety check: a lifestyle/scene shot with no clear product, or an off-category / unsafe image, is REJECTED and NOTHING is locked or saved (the summary says why). On PASS it persists the photo to a DURABLE url, writes it to the brand's product library as the DEFAULT, and READS THE BRAND BACK to confirm — savedToBrand and the summary report what the brand ACTUALLY holds now, never what was asked for, so if it did not become the default you are told instead of finding out from a paid render. Bills one vision check. Reads YOUR saved brand for the category match (pass brandId to target a specific brand — switches this key's active brand like use_brand).
| Name | Required | Description | Default |
|---|---|---|---|
| brandId | No | a brand id/name from list_brands to lock the product for; omit to use the active brand | |
| imageUrl | Yes | the image URL to lock as the product (from a research result, a workspace / list_product_photos url, or any public product photo) | |
| source_note | No | a short note on where it came from, e.g. "from their IG post" |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds substantial context well beyond the annotations: the server downloads and validates, bills one vision check, persists to a durable URL, reads the brand back to confirm, and reports what the brand ACTUALLY holds rather than what was requested. This far exceeds the bare readOnlyHint=false / idempotentHint=true / openWorldHint=true annotations and gives the agent accurate expectations for a mutating, costly operation.
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?
Long, but dense and justified for the tool's complexity — it covers purpose, failure semantics, confirmation behavior, cost, and cross-tool effects. Core purpose is front-loaded in the first sentence. It reads as verbose rather than bloated, though it could trim the redundant phrasing around 'never what was asked for.'
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, so the description carries the return-value burden — and it does, referencing `savedToBrand` and a summary that reports actual brand state. Combined with side-effect and cost disclosure, an agent has nearly everything needed. Minor gaps: exact response shape and failure-status codes are not specified, but the summary semantics largely compensate.
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 baseline is 3, but the description adds real value: it specifies imageUrl is a product shot (excluding lifestyle shots), explains the consequence of the validation (rejection means nothing is locked/saved), and clarifies that brandId switches the active brand. This goes beyond the schema's terse field notes.
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 ('Lock an image as the ad's real PRODUCT photo and SAVE it as this brand's default product') and immediately distinguishes itself by explaining the downstream effect on plan_ad / render_ad / generate_image. The agent knows exactly what this does and how it differs from the many adjacent ad/asset 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?
Explicitly enumerates acceptable image sources (prior research results, workspace / list_product_photos URLs, any public photo), names the affected downstream tools, and explains the brandId behavior via the use_brand analogy. It also states rejection conditions (lifestyle/scene shot, off-category, unsafe), telling the agent both when to use it and what will fail.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_roleChange a teammate’s roleAIdempotentInspect
Change a workspace member’s role — admin (full access incl. billing) or member (read-only on billing). A privilege change: confirm the exact person + new role with the user, then call with confirm:true.
| Name | Required | Description | Default |
|---|---|---|---|
| role | Yes | the new role | |
| Yes | the member’s email | ||
| confirm | No | REQUIRED true |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description states that confirm:true must be passed, but the schema does not list confirm as required, creating a conflict that could mislead an agent into omitting it. This is a behavioral hazard. The description does add context about roles (admin has billing access, member is read-only on billing) beyond the annotations, but the confirm discrepancy undermines transparency. No other behavioral traits (e.g., error handling, idempotency implications) are disclosed.
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 concise, two sentences, and front-loaded with the action. The first sentence states the action and role distinctions; the second adds the confirmation instruction. It's efficient without excess, though the confirmation instruction could be clearer about it being a mandate rather than optional.
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 role-change tool, the description covers the essentials: what changes, role meanings, and the need for confirmation. However, it omits expected behaviors like validation (e.g., what if email doesn't exist) or the response/return value. Since there is no output schema, the agent has no idea what the tool returns. The confirm conflict also affects completeness. Overall, adequate but with 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?
The description adds meaningful value to the parameters: it defines what 'admin' and 'member' mean (full access incl. billing vs read-only on billing), and reiterates that confirm must be true. The schema already describes all three parameters with 100% coverage, but the description enriches the enum semantics and the confirmation requirement, going beyond the schema's basic descriptions.
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 the action ('Change a workspace member’s role') and specifies the resource (workspace member) and the two role options (admin vs member) with access details. It distinguishes itself from sibling tools like invite_member or remove_member by focusing on role modification. No ambiguity about what the tool does.
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 explains when to use it: a privilege change that requires confirmation with the user. It implies that the agent should confirm the person and new role before invoking. However, it does not explicitly mention alternatives or when not to use it, though the context of 'privilege change' is a clear indicator. The guidance is present but not exhaustive.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
stitch_videoStitch multi-scene videoAInspect
Render a multi-scene STITCHED video (≥2 scenes) — ONLY for spots LONGER than ONE clip of the chosen model. A multi-beat ad that FITS one clip renders better and cheaper as ONE single-pass generate_video/render_ad (a single generation carries the whole hook→demo→payoff arc) — never stitch those. What fits is the model’s own maximum from hermoso_capabilities, not a fixed number: 15s on most models, 30s on the longest-clip one, so a 30s spot need not be stitched at all if you name that model. Blocks until done. Spends credits.
| Name | Required | Description | Default |
|---|---|---|---|
| model | No | video model id from hermoso_capabilities — omit to let the router pick | |
| voice | No | voiceover voice name, e.g. Rachel / George | |
| scenes | Yes | array of scene objects (visual + optional voiceover/seconds) | |
| voiceover | No | full voiceover script spoken across the scenes | |
| resolution | No | 1080p (default), or 480p/720p for a cheaper draft | |
| aspectRatio | No | output aspect ratio, e.g. 9:16 (default) / 1:1 / 16:9 | |
| durationSeconds | No | total spot length in seconds (defaults to the sum of the scenes’ seconds) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare false hints; the description adds meaningful behavior: 'Blocks until done' and 'Spends credits'. It also implies a render/creation operation, consistent with readOnlyHint=false. This gives the agent awareness of cost and synchronous behavior beyond the structured fields.
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 longer than average but every sentence is purposeful: purpose, usage conditions, model dependency, and behavior. It front-loads the core function and spends no words on fluff. Slightly verbose but well-structured and efficient.
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?
Covers the essential decision framework (when to stitch vs not), model limits from hermoso_capabilities, and behavior (blocking, credits). The scene object structure is only lightly described in the schema ('visual + optional voiceover/seconds'), but the description does not elaborate; however, the schema already provides that hint. Without an output schema, some return details are missing, but overall it's sufficiently complete for an agent to call correctly in most scenarios.
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 each parameter described (model, voice, scenes, etc.). The description adds context about model max and duration defaults indirectly but does not go beyond the schema. Since the schema already documents parameters, a 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?
The description opens with a clear verb and resource: 'Render a multi-scene STITCHED video (≥2 scenes)'. It immediately differentiates itself from single-pass generation tools like generate_video/render_ad by stating the condition (spots longer than one clip). This precisely identifies the tool's unique role among many video-related siblings.
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 states when to use ('ONLY for spots LONGER than ONE clip of the chosen model') and when not to ('never stitch those'), and names the alternatives (generate_video/render_ad). It also references hermoso_capabilities for model-specific limits, giving concrete decision criteria. This is textbook usage guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
store_getRead a workspace storeARead-onlyInspect
Read one of this workspace’s data stores by key, for visibility into what the app holds — playbooks, swipefile, saved locations, avatars, creations, chats, brand, memory, skills. Read-only, free. Allowed keys: heist.memory.v1, heist.skills.v1, heist.playbooks.v1, heist.avatars.v1, heist.locations.v1, heist.chats.v1, heist.creations.v1, heist.assets.v1, heist.brand.v1, adInspo.swipefile.v1. (The typed tools — list_memory / list_skills / get_brand — are friendlier for those; use store_get for the rest.)
| Name | Required | Description | Default |
|---|---|---|---|
| key | Yes | the store key to read (one of the allowlisted keys) | |
| limit | No | max array items to return (default 50) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, covering the safety profile. The description adds behavioral context by specifying the exact allowed keys (the allowlist) and reiterating that the operation is read-only and free. This exceeds a baseline but does not detail response formats or error handling, which are minor for a simple read 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?
The description is information-dense without fluff. It front-loads the core action, lists stores and allowed keys, and then guides the user to alternatives—all in a logical, scannable structure. Each sentence earns its place, and the parenthetical note is neatly appended.
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, read-only tool with a single required parameter, the description is complete. It provides the full allowlist, distinguishes from siblings, and notes the read-only/free nature. Nothing an agent needs to invoke it correctly is missing, and the lack of an output schema is acceptable given the tool's simplicity.
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 covers 100% of parameters (key and limit) with descriptions, but the description adds crucial value by enumerating the exact allowed key values (e.g., heist.memory.v1, adInspo.swipefile.v1) that are not in the schema as an enum. This is essential for correct invocation, going beyond what the schema provides.
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 the tool's action ('Read one of this workspace’s data stores by key') and the resource it operates on, listing specific store types. It also explicitly differentiates from the typed sibling tools (list_memory, list_skills, get_brand), making it unambiguous which tool to choose.
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 explicit usage guidance: it names the typed alternatives (list_memory, list_skills, get_brand) as 'friendlier' for certain keys and instructs to 'use store_get for the rest.' It also states the read-only, free nature, leaving no ambiguity about when this tool is appropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
subscribe_linkedin_leadsTurn on real-time LinkedIn lead deliveryAIdempotentInspect
Have LinkedIn push every new lead to Hermoso the moment it is submitted, and optionally relay each event on to the user’s own CRM. THE WEBHOOK LINKEDIN VALIDATES IS ALWAYS HERMOSO’S OWN: LinkedIn challenges it with our app secret (and re-challenges every ~2 hours), which no CRM, Zapier or Make endpoint can answer — so never promise a customer URL as the LinkedIn webhook. Pass forwardTo (public HTTPS) to have Hermoso relay each lead event there; leave it off to keep events in Hermoso only (list_linkedin_lead_events). The reply is read back from LinkedIn, not from the 201. Leads stay readable with list_linkedin_leads either way. Free.
| Name | Required | Description | Default |
|---|---|---|---|
| pageId | No | the company Page that owns the form — from list_linkedin_pages; omit when one Page is shared | |
| leadType | No | defaults by owner: SPONSORED for an ad account, COMPANY for a Page | |
| forwardTo | No | optional public HTTPS URL Hermoso relays each lead event to (a CRM, Zapier, Make) | |
| adAccountId | No | read forms owned by an AD ACCOUNT instead of a Page |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond what annotations state, it discloses the webhook validation mechanism: LinkedIn challenges Hermoso's own webhook with the app secret every ~2 hours, which no CRM/Zapier/Make endpoint can answer — the key reason a customer URL must never be promised. It also discloses reply semantics ('The reply is read back from LinkedIn, not from the 201') and post-conditions (events stay in Hermoso when forwardTo is omitted; leads remain readable either way). None of this contradicts the annotations; idempotentHint=true and destructiveHint=false are consistent with a non-destructive subscription action.
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 core purpose is front-loaded, and the critical webhook constraint is CAPS-flagged so an agent cannot miss it. Each subsequent sentence covers one distinct fact: forwardTo behavior, reply semantics, persistence of leads, and cost. It is dense — the webhook sentence packs substantial information — but no sentence 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?
With no output schema, the description compensates by covering the call's effect, the hard webhook constraint, forwardTo behavior, reply semantics, and post-conditions. Minor gaps: it does not point to list_linkedin_lead_subscriptions or delete_linkedin_lead_subscription for managing the subscription afterward, nor does it describe failure/validation scenarios.
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 the baseline is 3; the description adds meaning by explaining forwardTo's behavioral consequence — 'leave it off to keep events in Hermoso only' — and clarifying that forwardTo is a relay target, not the LinkedIn webhook. pageId, leadType, and adAccountId gain no new semantics beyond their schema descriptions, which already document defaults and source ownership.
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 action and resource: 'Have LinkedIn push every new lead to Hermoso the moment it is submitted' — a clear verb+resource+trigger semantics. The title 'Turn on real-time LinkedIn lead delivery' matches, and the description distinguishes this creation action from siblings like list_linkedin_lead_events and list_linkedin_lead_subscriptions, which read or manage events/subscriptions rather than create the push.
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 concrete context: forwardTo on/off selects relay-to-CRM versus Hermoso-only, and it cross-references list_linkedin_lead_events for the Hermoso-only case and list_linkedin_leads as the persistent read path 'either way.' It also contains an explicit when-not ('never promise a customer URL as the LinkedIn webhook'). It stops short of fully enumerating sibling selection — e.g., when to use list_linkedin_lead_subscriptions or delete_linkedin_lead_subscription to manage an existing subscription.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tidy_memoryTidy the Memory listADestructiveIdempotentInspect
Clean up and consolidate the workspace Memory: drops entries that are about how Hermoso, a tool, a connector or a platform API behaves (product behaviour, not the brand), drops phone numbers and emails, and merges near-duplicate facts into one sentence each. Call with no argument to get the PROPOSAL (what would be removed and merged, with reasons) — nothing changes. Call again with confirm:true to apply it through the same typed writers the app uses (deletes carry tombstones so they stay deleted on every device). One small model call; a few credits.
| Name | Required | Description | Default |
|---|---|---|---|
| confirm | No | true to APPLY the proposal; omit to only see it |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes well beyond the annotations by explaining exactly what gets removed, that the no-arg call makes no changes, that confirm:true applies via the app's typed writers, and that deletes carry tombstones to stay deleted across devices. It even discloses the small model call and credit cost.
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 information-dense but not bloated; every clause contributes something. It front-loads the core purpose and then explains the preview/apply flow and consequences. The first sentence is long with many serial clauses, but all are relevant and the structure remains readable.
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, multi-step tool with no output schema, the description covers what an agent needs: what is cleaned, how to preview safely, how to apply, the deletion semantics, and the cost/resource implications. Nothing critical is missing 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 single boolean parameter confirm is already fully documented in the schema, and schema coverage is 100%. The description reinforces the meaning by tying 'no argument' to the proposal-only mode and 'confirm:true' to applying the changes, adding practical context beyond the raw 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 opens with a specific verb and resource ('Clean up and consolidate the workspace Memory') and details exactly what that means: dropping product-behavior entries, phone numbers, emails, and merging near-duplicate facts. It is easily distinguished from sibling tools like list_memory, remember, and forget.
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 explicit call patterns: call with no argument to preview the proposal, then call again with confirm:true to apply. It clearly explains the safe preview-first workflow, though it does not explicitly mention when not to use this tool or point to alternatives such as forget for targeted deletion.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_brandUpdate brand fieldsAInspect
Patch SPECIFIC fields of the workspace brand profile (name, domain, sells, summary, category, audience, positioning, voice, style, goal) WITHOUT overwriting the rest — a read-modify-write on the saved brand. Use for “change our voice to playful”, “we sell to dentists now”. To onboard a brand from scratch, use draft_brand. Only pass the fields you’re changing.
| Name | Required | Description | Default |
|---|---|---|---|
| goal | No | current marketing goal | |
| name | No | ||
| sells | No | what the brand sells | |
| style | No | visual style — palette, typography, aesthetic | |
| voice | No | brand voice/tone | |
| domain | No | website domain | |
| summary | No | one-line description | |
| audience | No | ||
| category | No | ||
| positioning | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Since all annotations are false, the description carries the full burden of behavioral disclosure. It explicitly says 'Patch SPECIFIC fields ... WITHOUT overwriting the rest — a read-modify-write on the saved brand', which clearly reveals the partial-update behavior. This is strong transparency, though it does not disclose idempotency or error handling.
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 concise and well-structured: a main action sentence, two usage examples, and a pointer to an alternative tool. It is front-loaded with the critical behavior (patch without overwrite) and contains no redundant 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?
The description explains the patching behavior and provides usage examples, but it does not specify which brand is being updated (implicitly the current workspace brand, given sibling tools like list_brands and use_brand). It also does not mention any return value or error behavior, and there is no output schema. These gaps leave the invocation context 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?
The description lists all 10 patchable fields, which helps the agent know what can be updated, and adds the practical instruction 'Only pass the fields you're changing'. However, with only 60% schema coverage, it does not compensate for the four undocumented parameters (name, audience, category, positioning) by providing semantic explanations; it merely names them.
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 the tool patches specific fields of the workspace brand profile without overwriting the rest, and lists the fields in parentheses. However, it does not differentiate itself from the sibling 'change_voice', which could be a more specialized tool for voice changes, leaving some ambiguity for the agent to decide between them.
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 explicit usage examples ('change our voice to playful', 'we sell to dentists now') and points to 'draft_brand' for full onboarding, which is a clear alternative. It also instructs to pass only changed fields. It does not, however, mention other alternatives like 'change_voice', so the guidance is not fully comprehensive.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_docEdit a Google Doc in placeADestructiveIdempotentInspect
EDIT a Google Doc — the correction append_to_doc cannot make, which until now meant a doc could only ever grow and a wrong line stayed in it forever. Two shapes: replacements:[{find, replace}] rewrites specific text wherever it appears (call read_doc first and match the text EXACTLY; matchCase:false ignores case), or rewrite:"…" replaces the ENTIRE body (rewrite:"" empties it). Find/replace runs immediately and REPORTS how many occurrences changed — zero matches is reported as a FAILURE to match, never as a quiet success, because a text edit that silently does nothing is worse than one that visibly fails. A whole-body rewrite is destructive: call it without confirm first to get the character count, then confirm:true + confirmCells. Both are index-free by design — an agent cannot reliably compute Google’s character offsets, and a wrong offset deletes the wrong sentence.
| Name | Required | Description | Default |
|---|---|---|---|
| docUrl | No | a Google Docs URL — the id is extracted from it | |
| confirm | No | ||
| rewrite | No | replace the WHOLE body with this text ("" empties the doc) | |
| documentId | No | the document id (from create_doc, or list_drive_files for one the user picked) | |
| confirmCells | No | echo back the character count the unconfirmed call reported (rewrite only) | |
| replacements | No | find/replace pairs, applied in order |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark destructiveHint=true, but the description adds essential context beyond that: it explicitly warns that rewrite is destructive, explains the confirm flow, and reveals the failure reporting behavior (zero matches reported as failure, never silent success). It also justifies the index-free design, which helps agents understand constraints. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but each sentence carries meaningful operational detail. It front-loads the core purpose and then systematically explains both modes and their warnings. While not maximally terse, the density of useful information justifies the length; a minor deduction for being more verbose than strictly necessary.
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 six parameters, two operation modes, and a destructive rewrite path, the description covers all essential usage guidance: prerequisites (read_doc first), confirmation workflow, error behavior, and the rationale behind index-free edits. Since there is no output schema, the description appropriately focuses on invocation and side effects, making it complete for an agent to call 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 description coverage is 83%, but the description substantially enhances parameter meaning: it explains the two distinct call shapes (replacements array vs rewrite string), clarifies that rewrite:"" empties the document, gives the role of confirm and confirmCells, and notes matchCase:false ignores case. This goes well beyond the bare schema and aids correct invocation.
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 opens with 'EDIT a Google Doc' and explicitly characterizes it as 'the correction append_to_doc cannot make', naming the sibling it differs from. It further distinguishes two concrete modes (replacements and rewrite), so an agent can immediately grasp the verb, resource, and scope without ambiguity.
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?
Provides explicit step-by-step usage: for replacements it instructs to call read_doc first and match text exactly, including matchCase:false semantics; for rewrite it dictates the two-phase confirm flow (call without confirm to get character count, then confirm:true + confirmCells). It also names the alternative append_to_doc and clarifies when each mode applies.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_drive_fileRename / move / trash a Drive fileAIdempotentInspect
Update a Drive file: rename (name), move it into a folder (moveToFolderId, optionally removeFromFolderId to move OUT of the old one), or trash / untrash it (trash:true|false). Pass fileId (from list_drive_files). To delete permanently, use delete_drive_file.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | new name | |
| trash | No | true → move to Trash; false → restore from Trash | |
| fileId | Yes | the Drive file id | |
| moveToFolderId | No | folder id to move the file into (from create_drive_folder / list_drive_files) | |
| removeFromFolderId | No | the old parent folder id to remove (when moving) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, destructiveHint=false, and idempotentHint=true. The description adds operational details: trash is reversible (untrash with trash:false), moving can remove a file from an old folder via removeFromFolderId, and permanent deletion is excluded. This goes beyond the binary annotation flags and clarifies 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?
The main description is a single, information-dense sentence that front-loads the tool's purpose and lists all operations with their parameters. A second sentence handles the cross-reference to delete_drive_file. No filler or repetition of schema details, making it highly efficient.
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 mutation tool with no output schema, the description covers the required input (fileId), all operation types, the source of values, and the key alternative for permanent deletion. It does not mention the success/return format, but that is a minor gap given the simplicity of operations. It also doesn't explicitly state that multiple operations can be combined, which is implied by the parameter list.
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 input schema describes each parameter individually with 100% coverage, but the description adds crucial relational context: it explains that moveToFolderId and removeFromFolderId work together to move a file out of an old folder, and it names the source of fileId (list_drive_files). This adds meaning beyond the schema's isolated property descriptions.
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 opens with 'Update a Drive file' and immediately enumerates the three distinct operations: rename (name), move (moveToFolderId and removeFromFolderId), and trash/untrash (trash:true|false). It names specific parameters and explicitly contrasts with delete_drive_file for permanent deletion. This is a precise verb+resource definition that clearly differentiates from siblings.
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 an explicit alternative: 'To delete permanently, use delete_drive_file.' It also directs the user to obtain fileId from list_drive_files, establishing a prerequisite. It does not explicitly state when not to use this tool for creating files, but the title and operations make that obvious. Slightly shy of a 5 because it doesn't spell out scenarios like 'use save_to_drive for new files'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_onedrive_fileRename / move a OneDrive fileAIdempotentInspect
Update a OneDrive item: rename (name) and/or move it into a folder (moveToFolderId). Pass fileId (from list_onedrive_files). To remove an item, use delete_onedrive_file.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | new name | |
| fileId | Yes | the OneDrive item id | |
| moveToFolderId | No | folder id to move the item into (from create_onedrive_folder / list_onedrive_files) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description is consistent with the annotations (readOnlyHint=false implies a mutation; destructiveHint=false and idempotentHint=true align with rename/move being non-destructive and repeatable). No contradiction. However, it adds little beyond what the operation name and annotations already imply—it doesn't disclose outcome behavior for partial success, reversibility, or what happens if both rename and move are combined, though the 'and/or' phrasing implies these are possible.
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 tightly written sentences, front-loaded with the operation, then id sourcing, then the sibling alternative for deletion. Zero filler words; every clause 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 3-parameter tool with full schema coverage, present annotations, and no output schema, the description adequately covers the operation, parameter sourcing, and the route to the removal sibling. An agent can call it correctly with what's provided. Minor gap: it doesn't explicitly confirm that rename and move can be combined in one call.
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 already documents fileId, name, and moveToFolderId with descriptions. The description reinforces the rename/move mapping and clarifies the id source ('from list_onedrive_files'), which is mildly additive. With full schema coverage, the baseline of 3 applies since the description doesn't need to compensate for missing param docs.
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 operation ('Update a OneDrive item: rename (name) and/or move it into a folder (moveToFolderId)') with clear verbs and resources. It also names the sibling to use for the inverse operation (delete_onedrive_file), which helps distinguish it. It doesn't contrast with other related siblings like get_onedrive_file or convert_onedrive_file, but the core purpose is 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?
Provides an explicit exclusion ('To remove an item, use delete_onedrive_file') and a sourcing hint ('Pass fileId (from list_onedrive_files)'). This routes the agent away from the wrong sibling for deletion and tells it where to obtain the required id. It stops short of enumerating the full set of siblings or stating exact conditions for move vs rename, but the guidance present is useful.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_saved_creatorUpdate a saved creator (outreach status, note)AIdempotentInspect
Set the OUTREACH STATUS and/or a NOTE on a creator already saved in the swipefile (find_creators → save_to_swipefile, or the ♥ on a creator card). Status is one of new | contacted | replied | booked | passed. The note is free text (deal terms, rate, what was sent). Reads back the updated row. Use list_swipefile to find the key. Free.
| Name | Required | Description | Default |
|---|---|---|---|
| key | Yes | the saved row's key from list_swipefile, e.g. tiktok:handle | |
| note | No | replaces the existing note; pass "" to clear it | |
| status | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond annotations (readOnly=false, idempotent=true, destructive=false), the description adds that the operation is a targeted update ('and/or'), that the note is free text with examples, and that the tool 'reads back the updated row' — clarifying the return behavior despite the lack of an output schema. It also states the prerequisite that the creator must already be saved, which helps avoid misuse. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences: the first states action and scope, the second defines the two fields with their value domains, and the third covers return behavior, key lookup, and cost. Every sentence adds value, and the most critical scoping ('already saved') 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 simple 3-parameter update with idempotentHint and destructiveHint already set, the description covers the workflow prerequisite, the accepted statuses, how to resolve the key, and the return behavior. It does not explicitly note that status and note are both optional in the schema (only key required), but 'and/or' implies at least one should be provided, which is sufficient for an agent. No output schema exists, so mentioning 'reads back the updated row' is the right amount of return-value detail.
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 already documents key and note (67% coverage); the description reinforces status as 'outreach status' and lists its enum values, though this duplicates the enum. The note examples ('deal terms, rate, what was sent') add modest semantic color beyond the schema's clear/replace semantics, but the description does not substantially illuminate parameter formats or constraints not already in 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 the exact operation ('Set'), the target resource ('a creator already saved in the swipefile'), and the precise fields affected (outreach status, note). This clearly differentiates it from siblings like save_to_swipefile (creation) and delete_creator (removal) without ambiguity.
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 embeds the workflow context ('find_creators → save_to_swipefile' or the heart icon), and instructs 'Use list_swipefile to find the key' — telling the agent how to obtain the required key and signalling this operates on existing swipefile rows. It does not explicitly name save_to_swipefile or delete_creator as alternatives for add/remove, so the exclusion is implied rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_settingsChange app settingsAIdempotentInspect
Change this account's app settings. language = the language EVERY ad, script, plan and answer is written in from now on (say the language in plain English, e.g. "German", "Japanese", "Brazilian Portuguese") — it applies to renders made over MCP as well as in the app. theme = the app's appearance, "dark" or "light". watchEmail = the weekly competitor-watch email on/off. Only pass what you are changing. Account-wide (every brand), and it takes effect on the next call.
| Name | Required | Description | Default |
|---|---|---|---|
| theme | No | app appearance | |
| language | No | language for generated ads, copy and answers — e.g. "English", "German", "Japanese" | |
| watchEmail | No | weekly competitor-watch email on/off |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare idempotentHint and non-read-only, but the description adds critical behavioral context: changes are account-wide, affect all brands, apply to MCP renders as well as in-app, and take effect on the next call. It also clarifies language must be plain English. These are meaningful traits beyond what annotations 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?
The description is slightly long but every sentence contributes: purpose, per-parameter detail, partial-update hint, scope, and timing. It is front-loaded with the purpose and uses clear structure. It could be trimmed slightly but is not verbose.
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 settings tool with no output schema, the description covers what an agent needs: scope, effect timing, partial updates, and parameter syntax. It does not mention error handling or validation, but those are not essential for this simple tool. Overall, it is adequately 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?
The input schema already describes each parameter (100% coverage), but the description adds depth—for language, it details that it affects all generated content and specifies the plain-English format; for theme and watchEmail, it confirms the allowed values. This exceeds the schema's brief descriptions.
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 opens with the precise verb+resource: 'Change this account's app settings.' It then names each settable parameter and its meaning, making the tool's function unambiguous. It is clearly distinct from sibling tools like get_settings (read-only) or enable_tools (tool toggling).
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 explicit usage guidance: 'Only pass what you are changing' (partial updates) and 'Account-wide (every brand)', which clarifies scope. It also notes that changes take effect on the next call. Even though it does not explicitly contrast with siblings, the context is clear enough for an agent to know when to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_sheetWrite to a range in a Google SheetADestructiveIdempotentInspect
CORRECT cells in a Google Sheet — write values to an exact range, overwriting whatever is there. This is the fix append_to_sheet cannot make: appending only ever adds rows at the bottom, so without this a wrong number stays wrong forever and the only "correction" is a second row contradicting the first. Pass range (e.g. "B2:C5", or "Q3 Report!B2" to name a tab — list_sheet_tabs gives the names) and values as an array of row arrays; an anchor cell like "B2" is fine and the block is written down and right from it. Writing into EMPTY cells goes straight through. Writing OVER cells that already hold values is REFUSED first, naming exactly how many filled cells would be overwritten — show the user that, get a yes, then call again with confirm:true. The result is READ BACK from the sheet, so what you report is what the sheet now holds rather than what Google accepted.
| Name | Required | Description | Default |
|---|---|---|---|
| range | No | A1 range or anchor cell, e.g. "B2:C5", "B2", or "Q3 Report!B2" (default A1) | |
| values | No | array of row arrays to write | |
| confirm | No | required only when the target range already holds values | |
| updates | No | write SEVERAL disjoint ranges in one call, instead of range+values | |
| sheetUrl | No | ||
| spreadsheetId | No | ||
| valueInputOption | No | USER_ENTERED (default) parses formulas, dates and numbers the way typing them would; RAW stores every value as literal text |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint, idempotentHint, and openWorldHint, but the description adds critical behavioral details beyond those: writing over filled cells is refused first (naming the count), a confirm:true flag is required to proceed, and the result is read back from the sheet so the agent reports actual sheet state. These specifics materially modify expected behavior and are not derivable from 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 description is long but highly informative, and each sentence adds value. The purpose is front-loaded, the alternative is named, and edge cases (refusal, confirmation, read-back) are covered. While slightly wordy, it is not bloated or repetitive; the structure flows from purpose to mechanics to safety verification.
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 7 parameters, no output schema, and rich annotations, the description covers the critical aspects: what the tool does, when to use it, the confirmation gate, and the read-back guarantee. It does not explicitly explain the difference between sheetUrl and spreadsheetId, but those are conventional and likely self-evident. Overall, an agent has enough to call this correctly without external documentation.
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 71%, and the description significantly enriches the main parameters: it gives concrete range examples ('B2:C5', 'Q3 Report!B2'), explains the anchor-cell behavior, clarifies that values must be an array of row arrays, and explains confirm is required only when overwriting. It also details the updates parameter for multiple disjoint ranges. The only parameters left untouched are sheetUrl and spreadsheetId, which are standard identifiers; the description compensates well for the schema gaps.
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 verb ('CORRECT cells'), the resource ('a Google Sheet'), and the precise operation ('write values to an exact range, overwriting whatever is there'). It explicitly contrasts with append_to_sheet, naming the sibling and the exact limitation it overcomes, so an agent can distinguish this tool without ambiguity.
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 explicit when-to-use guidance: 'This is the fix append_to_sheet cannot make' and explains the failure mode appending would cause. It also specifies the confirmation workflow for overwriting non-empty cells ('show the user that, get a yes, then call again with confirm:true'), leaving no ambiguity about prerequisites or safe invocation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
upgrade_planUpgrade planAInspect
Change this account's SUBSCRIPTION plan (admin only). Call with no argument to list the plans (id · monthly price · monthly credits); call again with plan set to a plan id. A NEW subscriber gets a ready-to-pay Stripe Checkout URL to hand your human — THEY pay on Stripe (agents never spend money directly). If the account already has a paid plan, or you're DOWNGRADING, the change is made by a person in the app (Settings → Billing) and the tool returns exactly what to do. Members (read-only billing) get an honest 'ask an admin' message. Nothing is charged until your human pays.
| Name | Required | Description | Default |
|---|---|---|---|
| plan | No | the plan id to move to (e.g. pro) — omit to list the available plans first | |
| period | No | billing cadence — monthly (default) or yearly (2 months free) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already indicate non-readonly, non-destructive, but the description adds critical financial behavior: agents never pay directly, returns a Stripe Checkout URL for the human, and 'Nothing is charged until your human pays.' This beyond-annotation transparency is essential to prevent an agent from taking harmful action. No contradiction.
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 but information-dense, front-loaded with the main purpose, then the usage pattern, then edge cases. Every sentence adds value: admin-only restriction, listing flow, Stripe payment, downgrade handling, and member message. No fluff or repetition.
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 fully covers the three possible return scenarios (new subscriber → Stripe URL, existing paid/downgrade → instructions, member → message), plus permission handling. An agent has all information needed to call correctly without ambiguity.
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%: both 'plan' and 'period' are well documented, including the default and the 2-months-free bonus. The description reinforces the omit-to-list behavior already present in the schema, adding no new parameter semantics. Baseline 3 is appropriate since schema carries the full weight.
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 ('Change this account's SUBSCRIPTION plan'), notes 'admin only', and clearly distinguishes from siblings like billing_status or buy_credits by describing the flow: list plans with no argument, then set a plan. The purpose is 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?
Explicitly instructs the two-step call pattern ('Call with no argument to list the plans... call again with `plan` set'), and specifies the fallback for paid/downgrade cases (returns instructions) and for members ('ask an admin' message). This fully clarifies when to use the tool and what to do in each scenario.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
upload_fileUpload a local file → durable public URLAInspect
Persist an ARBITRARY user file (image, video, audio, PDF or document, up to 150MB) into Hermoso and get back a durable public URL that EVERY publish, schedule and ad-build tool accepts — post_to_meta / post_to_linkedin / post_to_linkedin_page / post_to_youtube / post_to_tiktok / post_to_pinterest / post_to_x / post_to_google_business / schedule_post / upload_meta_asset / upload_google_ads_asset / create_meta_ad / create_linkedin_ads_creative / set_youtube_thumbnail / save_to_drive / save_to_onedrive. THIS IS THE BRING-YOUR-OWN-CREATIVE PATH: it is for files that have NOTHING to do with a Hermoso render (media on the user's desktop, an agency's finished ad, a photo they shot), and it means you can publish, schedule and run ads through Hermoso without generating anything here. Provide exactly ONE source — passing two is an error, never a silent preference: url (ANY public http(s) link — Hermoso fetches it server-side, so nothing crosses this connection and there is no practical size limit; THIS IS THE ONE THAT ALWAYS WORKS, including on the hosted connector), path (a local file — ONLY when Hermoso runs on the user's own machine over stdio/CLI; the hosted connector cannot see their disk), or dataUri (a base64 data: URI — keep it under ~15MB, since the bytes travel over this connection). If the file is already at a public https URL, the Meta, Reddit and ChatGPT-Ads tools take it directly and re-host it safely — but LinkedIn (posts and ad creatives), Pinterest, the YouTube thumbnail and upload_google_ads_asset upload the BYTES themselves and therefore refuse an external host, so run it through here first and pass the URL this returns. When in doubt, use this: its URL works everywhere. (Calling the underlying HTTP route directly? POST /api/upload takes the file's RAW BYTES as the request body with its own content-type — NOT multipart/form-data — or ?url= with no body.) Returns {url, kind, bytes}.
| Name | Required | Description | Default |
|---|---|---|---|
| url | No | a PUBLIC http(s) URL Hermoso fetches server-side (private/internal addresses are refused, and every redirect hop is re-checked). Works on every surface including the hosted connector, and the bytes never cross this connection — prefer this whenever the file is reachable on the web. | |
| name | No | original file name — helps pick the right extension | |
| path | No | local filesystem path (stdio/CLI only — refused on the hosted connector) | |
| dataUri | No | base64 data: URI of the file bytes (data:<mime>;base64,<…>) — bytes travel over this connection, so keep it small |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations are thin (read-only/idempotent/destructive hints), so the description carries the full burden. It discloses server-side fetching, private-address refusal, redirect checks, the 'exactly one source or error' rule, size constraints, hosting-surface differences, and the raw HTTP route behavior. It even states the return shape {url, kind, bytes} despite no output schema.
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 content is front-loaded and dense, with the core purpose in the first sentence and almost no filler. However, the long list of accepting tools and the direct-HTTP aside make it longer than strictly necessary, even though that detail is useful.
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 complex tool with no output schema, the description is unusually complete: it covers all four parameters, failure conditions, size limits, environment restrictions, downstream compatibility, and return values. An agent has everything needed to select the right source and invoke the tool 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 100%, but description adds critical semantics beyond the schema: mutual exclusivity, error behavior, when each source is valid, and platform-specific re-host requirements. This turns bare properties into actionable decision rules.
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 names a specific verb ('Persist'), resource ('arbitrary user file'), and outcome ('durable public URL'). It clearly distinguishes itself from Hermoso render/generation tools by labeling this the bring-your-own-creative path and enumerating which downstream tools accept its URL.
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 explicit when-to-use guidance for each source: url for any public link with no practical size limit, path only for stdio/CLI, dataUri for small payloads. It also tells which downstream platforms require re-hosting through this tool and which can accept external URLs directly, and closes with 'when in doubt, use this.'
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
upscale_videoUpscale videoAInspect
Upscale a video to higher resolution (2x) for final delivery. Paid render; returns the served URL.
| Name | Required | Description | Default |
|---|---|---|---|
| video | Yes | the source video URL |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations indicate readOnlyHint=false and destructiveHint=false, which are consistent with a tool that creates a new output. The description adds critical behavioral context: 'Paid render' informs the agent that this operation incurs cost, and 'returns the served URL' clarifies the return format. This goes beyond the annotations by disclosing financial impact and output type. It doesn't mention any potential delays or failure modes, but for a one-parameter tool, the added context is valuable.
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 a single, dense sentence that conveys the action, resolution factor, usage context (final delivery), cost (paid), and the output (served URL). Every word adds value, and the most important aspects (action and purpose) are front-loaded. No wasted text.
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 tool with one parameter and no output schema, the description covers the essential aspects: what it does, that it's paid, and what the return is. It doesn't mention whether the operation is synchronous or asynchronous, or any constraints on the input video (e.g., maximum resolution, format). However, given the simplicity, this is nearly complete and sufficient for an agent to decide when to invoke it. Minor gaps keep it from a 5.
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 input schema covers the sole parameter 'video' with a description 'the source video URL' (100% coverage). The tool description does not add any parameter-specific details beyond what the schema provides, such as accepted formats, size limits, or how the URL should be hosted. Since schema coverage is high, the description meets the baseline but doesn't enrich parameter understanding beyond 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?
The description states exactly what the tool does: 'Upscale a video to higher resolution (2x)' with a clear resource (video) and purpose ('for final delivery'). It distinguishes itself from siblings like clip_video, stitch_video, or edit_video by focusing specifically on resolution upscaling. This is a specific verb+resource pairing with no ambiguity.
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 phrase 'for final delivery' gives clear contextual guidance on when to use this tool (when preparing a video for final output). It also notes 'Paid render,' implying it should be used when the user is willing to pay for higher quality. However, it does not explicitly mention alternatives or when NOT to use it, such as if the video is already at the target resolution or if a cheaper preview is sufficient. This is slightly above average but lacks explicit exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
use_brandSwitch brandAIdempotentInspect
Pin which brand this connection acts on (multi-brand accounts). Pass the brand id or exact name from list_brands. Works for a brand on your own account AND for a workspace another account SHARED with you — for a shared one pass its name or the profile id list_brands prints, and access is verified against your real membership before it is pinned. Persists for this API key until changed, on every surface (hosted connector included — no environment variables, no restart).
| Name | Required | Description | Default |
|---|---|---|---|
| brand | Yes | brand id (e.g. default / p_xxx), its exact name from list_brands, or the profile id of a workspace shared with you |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already note idempotentHint=true and destructiveHint=false. The description adds meaningful behavioral details beyond that: persistence across surfaces (hosted connector, no env vars/restart) and membership verification for shared workspaces. It enriches the agent's understanding of state and side effects without contradicting 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 description is somewhat long (four sentences) but each sentence adds essential context: purpose, accepted inputs, shared-workspace nuance, and persistence. It is logically organized and front-loads the core action before diving into edge cases. No wasted 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?
For a single-parameter tool with no output schema, the description covers the essential scenarios: own brand, shared brand, input formats, persistence, and access verification. It does not explain the return value, but that is not expected without an output schema. The definition is complete 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?
Schema coverage is 100% and the schema already describes the 'brand' parameter thoroughly (id, name, profile id). The description reinforces these options but adds only incremental nuance about shared workspace verification. Since the schema carries the main meaning, this is a 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?
The description clearly states the tool's purpose: "Pin which brand this connection acts on" for multi-brand accounts. It distinguishes itself from siblings like list_brands (which lists) and create_brand/delete_brand (which manage) by focusing on the active selection. The wording is specific and avoids tautology.
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 clear context for when to use it (multi-brand accounts, own or shared) and explicitly references list_brands as the source of valid inputs. It doesn't explicitly say 'use this when you need to switch the active brand' but the function is evident. It lacks explicit exclusion of alternatives, but the context is sufficient.
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. Dates show when Glama detected each change.
18 tool updates
v0.1.209- Added
call_tool - Changed
change_voice1 field changed- changed
Input schema / properties / voice / descriptionPrevious value: -"target narrator voice preset name, e.g. 'Aria', 'George', 'Rachel', 'Sarah', 'Brian', 'Charlotte' (defaults to a warm female read)"New value: +"target narrator voice preset name, e.g. 'Aria', 'George', 'Rachel', 'Sarah', 'Brian', 'Charlotte' (defaults to a warm female read). A saved VOICE CLONE of the user's own voice counts as a preset here — name it the way it is saved on their cast"
- Added
delete_linkedin_lead_subscription - Added
find_creators - Added
find_tools - Added
get_linkedin_lead - Added
list_linkedin_lead_events - Added
list_linkedin_lead_forms - Added
list_linkedin_lead_subscriptions - Added
list_linkedin_leads - Changed
post_to_meta2 fields changed- added
Input schema / properties / aiGeneratedAdded value: +{ + "description": "INSTAGRAM / FACEBOOK REEL — Meta’s is_ai_generated self-disclosure. OMIT IT and Hermoso decides from provenance: a Hermoso render is declared, media that came through upload_file or from an external URL (the user’s own photographs or footage) is NOT — a real photo must never carry Instagram’s “AI info” label. Pass true or false only to override: false strips the label from something Hermoso would otherwise declare, true declares a render the user uploaded themselves.", + "type": "boolean" +} - changed
Input schema / properties / altText / descriptionPrevious value: -"ACCESSIBILITY — the description screen readers announce, and what the platform otherwise auto-generates badly or not at all. Describe what is actually IN the picture, never the caption. ONE STRING describes the picture; on a CAROUSEL it describes EVERY slide. Pass an ARRAY of strings instead to describe each slide separately, aligned to the slide order — that is strictly better on a multi-slide post, because one sentence read out over six different pictures is wrong for five of them. More descriptions than pictures is refused rather than dropped. WHERE IT LANDS, per Meta’s own docs: INSTAGRAM image posts and the IMAGE slides of an Instagram carousel (up to 1000 characters; dropped rather than sent on a Reel or a video slide, which Meta do not support); FACEBOOK Page photos including every photo of an album, via alt_text_custom (Meta publish no length for it, so nothing is truncated); THREADS on a single-image or single-video post ONLY — Meta document no way to attach alt text to a Threads CAROUSEL slide, so a Threads carousel publishes undescribed and the reply says so rather than risking the whole post on a guess. (AI disclosure is separate and automatic — every Instagram post Hermoso publishes is flagged is_ai_generated, which is not a caller setting.)"New value: +"ACCESSIBILITY — the description screen readers announce, and what the platform otherwise auto-generates badly or not at all. Describe what is actually IN the picture, never the caption. ONE STRING describes the picture; on a CAROUSEL it describes EVERY slide. Pass an ARRAY of strings instead to describe each slide separately, aligned to the slide order — that is strictly better on a multi-slide post, because one sentence read out over six different pictures is wrong for five of them. More descriptions than pictures is refused rather than dropped. WHERE IT LANDS, per Meta’s own docs: INSTAGRAM image posts and the IMAGE slides of an Instagram carousel (up to 1000 characters; dropped rather than sent on a Reel or a video slide, which Meta do not support); FACEBOOK Page photos including every photo of an album, via alt_text_custom (Meta publish no length for it, so nothing is truncated); THREADS on a single-image or single-video post ONLY — Meta document no way to attach alt text to a Threads CAROUSEL slide, so a Threads carousel publishes undescribed and the reply says so rather than risking the whole post on a guess. (Meta’s AI disclosure defaults from PROVENANCE: a Hermoso render is declared is_ai_generated; media that came through upload_file or an external URL, i.e. the user’s own photos or footage, is NOT. Pass `aiGenerated` to force it either way.)"
- Removed
post_to_reddit - Changed
post_to_tiktok1 field changed- added
Input schema / properties / aiGeneratedAdded value: +{ + "description": "TikTok’s is_aigc AI-generated-content label (video posts). OMIT IT and Hermoso decides from provenance: a Hermoso render is declared, a video that came through upload_file or an external URL (the user’s own footage) is NOT. true/false overrides.", + "type": "boolean" +}
- Changed
post_to_youtube3 fields changed- added
Input schema / properties / aiGeneratedAdded value: +{ + "description": "YouTube’s “altered or synthetic content” declaration (containsSyntheticMedia). OMIT IT and Hermoso decides from provenance: a Hermoso render is declared, a video the user uploaded through upload_file or from an external URL is NOT — real footage must not carry the label. true/false overrides.", + "type": "boolean" +} - changed
Input schema / properties / description / descriptionPrevious value: -"video description (≤5000 chars)"New value: +"REQUIRED in practice — what the video shows, a line about the brand, a link and a few #hashtags (≤5000 chars); YouTube search, suggested videos and the Shorts feed rank on it, so an upload with no description (and no caption) is refused" - changed
Input schema / properties / title / descriptionPrevious value: -"video title (≤100 chars)"New value: +"REQUIRED in practice — the headline every search result and the Shorts feed shows (≤100 chars); an upload with no title is refused"
- Changed
reschedule_post1 field changed- added
Input schema / properties / aiGeneratedAdded value: +{ + "description": "INSTAGRAM / FACEBOOK REEL — Meta’s is_ai_generated self-disclosure. OMIT IT and Hermoso decides from provenance: a Hermoso render is declared, media that came through upload_file or from an external URL (the user’s own photographs or footage) is NOT — a real photo must never carry Instagram’s “AI info” label. Pass true or false only to override: false strips the label from something Hermoso would otherwise declare, true declares a render the user uploaded themselves.", + "type": "boolean" +}
- Changed
schedule_post2 fields changed- added
Input schema / properties / aiGeneratedAdded value: +{ + "description": "INSTAGRAM / FACEBOOK REEL — Meta’s is_ai_generated self-disclosure. OMIT IT and Hermoso decides from provenance: a Hermoso render is declared, media that came through upload_file or from an external URL (the user’s own photographs or footage) is NOT — a real photo must never carry Instagram’s “AI info” label. Pass true or false only to override: false strips the label from something Hermoso would otherwise declare, true declares a render the user uploaded themselves.", + "type": "boolean" +} - added
Input schema / properties / optimizeCopyAdded value: +{ + "description": "RECOMMENDED when one caption goes to several channels: fit the shared caption to each channel’s own rules at publish time wherever no per-channel caption was written — YouTube gets a keyword title, a structured multi-paragraph description and search tags; Instagram/TikTok hashtags; LinkedIn longer; X/Bluesky short; Pinterest keyword-rich. The angle and every claim stay the author’s; a channel with its own caption is left exactly as written. Off by default so nobody’s words are rewritten unasked.", + "type": "boolean" +}
- Added
subscribe_linkedin_leads - Added
update_saved_creator
1 tool update
v0.1.193- Added
tidy_memory
164 tool updates
v0.1.189- Removed
answer_google_business_question - Removed
bluesky_post_metrics - Removed
comment_on_meta_post - Removed
comment_on_tiktok_video - Removed
create_meta_catalog - Removed
create_pinterest_board - Removed
create_whatsapp_template - Removed
delete_bluesky_post - Removed
delete_google_business_post - Removed
delete_meta_catalog - Removed
delete_pinterest_board - Removed
delete_pinterest_pin - Removed
delete_reddit_post - Removed
delete_telegram_message - Removed
delete_thread - Removed
delete_tiktok_post_ad_authorization - Removed
delete_whatsapp_template - Removed
delete_x_post - Removed
delete_youtube_report_job - Removed
delete_youtube_video - Changed
disconnect_connector1 field changed- added
Input schema / properties / accountAdded value: +{ + "description": "on a channel with several connected accounts (TikTok, X, YouTube, Threads, Bluesky, Telegram, Reddit, Pinterest): remove ONLY this account (@handle or id from list_connector_accounts) and keep the others", + "type": "string" +}
- Removed
edit_reddit_post - Removed
edit_x_post - Removed
extend_tiktok_post_ad_authorization - Removed
get_business_location - Removed
get_tiktok_mention - Removed
get_tiktok_post_ad_authorization - Removed
google_business_account - Removed
google_business_insights - Removed
google_business_search_keywords - Removed
hide_thread_reply - Removed
instagram_collaborators - Removed
instagram_insights - Removed
instagram_profile - Removed
linkedin_page_analytics - Removed
list_bluesky_convos - Removed
list_bluesky_posts - Changed
list_connector_accounts1 field changed- changed
Input schema / properties / provider / enumPrevious value: -[ - "meta", - "google_ads", - "linkedin", - "pinterest_ads", - "linkedin_ads", - "reddit_ads", - "apple_ads", - "microsoft_ads", - "google_business", - "google_analytics", - "snapchat_ads", - "x_ads", - "tiktok_ads", - "google_tag_manager", - "google_search_console", - "bing_webmaster" -]New value: +[ + "tiktok", + "x", + "youtube", + "threads", + "bluesky", + "telegram", + "reddit", + "pinterest", + "instagram", + "meta", + "google_ads", + "linkedin", + "pinterest_ads", + "linkedin_ads", + "reddit_ads", + "apple_ads", + "microsoft_ads", + "google_business", + "google_analytics", + "snapchat_ads", + "x_ads", + "tiktok_ads", + "google_tag_manager", + "google_search_console", + "bing_webmaster" +]
- Removed
list_google_business_posts - Removed
list_google_business_questions - Removed
list_google_business_reviews - Removed
list_inbox - Removed
list_instagram_media - Removed
list_instagram_shopping_catalogs - Removed
list_meta_catalog_products - Removed
list_meta_catalogs - Removed
list_meta_comments - Removed
list_meta_conversations - Removed
list_meta_partnership_creators - Changed
list_meta_posts1 field changed- added
Input schema / properties / accountAdded value: +{ + "description": "which Instagram account — an @handle or id from list_connector_accounts(\"instagram\"). Needed when several are linked, and the way an Instagram Login (standalone) account is reached; omit for the one Page-linked account.", + "type": "string" +}
- Removed
list_meta_product_sets - Removed
list_meta_webhook_events - Removed
list_pinterest_pins - Removed
list_reddit_comments - Removed
list_reddit_posts - Removed
list_shopify_products - Removed
list_telegram_dms - Removed
list_threads_mentions - Removed
list_threads_posts - Removed
list_threads_profile_posts - Removed
list_threads_replies - Removed
list_tiktok_brand_hashtag_posts - Removed
list_tiktok_brand_hashtags - Removed
list_tiktok_comment_replies - Removed
list_tiktok_comments - Removed
list_tiktok_mention_comments - Removed
list_tiktok_mentions - Removed
list_tiktok_videos - Removed
list_whatsapp_templates - Removed
list_x_dms - Removed
list_youtube_captions - Removed
list_youtube_categories - Removed
list_youtube_comments - Removed
list_youtube_playlists - Removed
list_youtube_report_jobs - Removed
list_youtube_video_stats - Removed
list_youtube_videos - Removed
manage_bluesky_convo - Removed
manage_instagram_product_tags - Removed
manage_linkedin_post - Removed
manage_meta_partnership_creator - Removed
manage_meta_post - Removed
manage_tiktok_brand_hashtags - Removed
manage_youtube_caption - Removed
manage_youtube_channel_section - Removed
manage_youtube_playlist - Removed
manage_youtube_playlist_image - Removed
manage_youtube_playlist_items - Removed
mark_bluesky_convo_read - Removed
meta_catalog_blast_radius - Removed
meta_page_insights - Removed
meta_post_insights - Removed
meta_webhook_status - Removed
moderate_meta_comment - Removed
moderate_tiktok_comment - Removed
moderate_youtube_comment - Added
multiply_ad - Removed
pinterest_ads_async_report - Removed
pinterest_analytics - Removed
pinterest_audience_insights - Removed
pinterest_targeting_analytics - Changed
post_to_bluesky1 field changed- added
Input schema / properties / accountAdded value: +{ + "description": "WHICH connected account of this channel to post as — its @handle or id from list_connector_accounts. Needed only when the brand has more than one bluesky account connected (several and none named is refused by name, never guessed); omit when there is one.", + "type": "string" +}
- Changed
post_to_meta1 field changed- added
Input schema / properties / accountAdded value: +{ + "description": "WHICH Instagram account when target is instagram and the brand has several — Page-linked and Instagram Login accounts alike; an @username or id from list_connector_accounts(\"instagram\"). Several and none named is refused by name; omit when there is one.", + "type": "string" +}
- Changed
post_to_pinterest1 field changed- added
Input schema / properties / accountAdded value: +{ + "description": "WHICH connected account of this channel to post as — its @handle or id from list_connector_accounts. Needed only when the brand has more than one pinterest account connected (several and none named is refused by name, never guessed); omit when there is one.", + "type": "string" +}
- Changed
post_to_reddit1 field changed- added
Input schema / properties / accountAdded value: +{ + "description": "WHICH connected account of this channel to post as — its @handle or id from list_connector_accounts. Needed only when the brand has more than one reddit account connected (several and none named is refused by name, never guessed); omit when there is one.", + "type": "string" +}
- Changed
post_to_telegram1 field changed- added
Input schema / properties / accountAdded value: +{ + "description": "WHICH connected account of this channel to post as — its @handle or id from list_connector_accounts. Needed only when the brand has more than one telegram account connected (several and none named is refused by name, never guessed); omit when there is one.", + "type": "string" +}
- Changed
post_to_tiktok1 field changed- added
Input schema / properties / accountAdded value: +{ + "description": "WHICH connected account of this channel to post as — its @handle or id from list_connector_accounts. Needed only when the brand has more than one tiktok account connected (several and none named is refused by name, never guessed); omit when there is one.", + "type": "string" +}
- Changed
post_to_x1 field changed- added
Input schema / properties / accountAdded value: +{ + "description": "WHICH connected account of this channel to post as — its @handle or id from list_connector_accounts. Needed only when the brand has more than one x account connected (several and none named is refused by name, never guessed); omit when there is one.", + "type": "string" +}
- Changed
post_to_youtube1 field changed- added
Input schema / properties / accountAdded value: +{ + "description": "WHICH connected account of this channel to post as — its @handle or id from list_connector_accounts. Needed only when the brand has more than one youtube account connected (several and none named is refused by name, never guessed); omit when there is one.", + "type": "string" +}
- Removed
react_to_bluesky_dm - Removed
read_bluesky_dm - Removed
read_meta_conversation - Removed
reddit_post_stats - Changed
render_ad1 field changed- changed
Input schema / properties / captions / descriptionPrevious value: -"composited caption pills on/off (default: the recipe decides)"New value: +"burn the plan's per-scene on-screen words as caption pills. DEFAULT FALSE — leave it off unless the user asks for on-screen text (no captions, or true subtitles of what is said; never scene or emphasis labels); a recipe whose format IS on-screen text keeps its text either way"
- Removed
reply_to_google_business_review - Removed
reply_to_inbox_item - Removed
reply_to_meta_comment - Removed
reply_to_meta_message - Removed
reply_to_reddit_comment - Removed
reply_to_thread - Removed
reply_to_tiktok_comment - Removed
reply_to_youtube_comment - Removed
repost_thread - Removed
save_pinterest_pin - Changed
schedule_post1 field changed- added
Input schema / properties / accountsAdded value: +{ + "additionalProperties": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "const": "all", + "type": "string" + } + ] + }, + "description": "WHICH accounts of a multi-account channel to post to, e.g. { \"tiktok\": [\"@a\", \"@b\"] } or { \"tiktok\": \"all\" } — one row per account at fire time, each with its own result. Omit for channels with one account (several and none named is refused by name).", + "propertyNames": { + "type": "string" + }, + "type": "object" +}
- Removed
search_instagram_hashtag - Removed
search_instagram_shopping_products - Removed
search_pinterest_ads_targeting - Removed
search_threads_keyword - Removed
search_threads_locations - Removed
send_bluesky_dm - Removed
send_whatsapp_broadcast - Removed
send_whatsapp_message - Removed
send_x_dm - Changed
set_connector_accounts1 field changed- changed
Input schema / properties / provider / enumPrevious value: -[ - "meta", - "google_ads", - "linkedin", - "pinterest_ads", - "linkedin_ads", - "reddit_ads", - "apple_ads", - "microsoft_ads", - "google_business", - "google_analytics", - "snapchat_ads", - "x_ads", - "tiktok_ads", - "google_tag_manager", - "google_search_console", - "bing_webmaster" -]New value: +[ + "tiktok", + "x", + "youtube", + "threads", + "bluesky", + "telegram", + "reddit", + "pinterest", + "instagram", + "meta", + "google_ads", + "linkedin", + "pinterest_ads", + "linkedin_ads", + "reddit_ads", + "apple_ads", + "microsoft_ads", + "google_business", + "google_analytics", + "snapchat_ads", + "x_ads", + "tiktok_ads", + "google_tag_manager", + "google_search_console", + "bing_webmaster" +]
- Removed
set_tiktok_post_ad_authorization - Removed
set_youtube_thumbnail - Removed
set_youtube_watermark - Removed
subscribe_meta_webhooks - Removed
threads_insights - Removed
threads_profile - Removed
threads_publishing_limit - Removed
tiktok_account - Removed
tiktok_account_insights - Removed
tiktok_account_status - Removed
tiktok_category_benchmark - Removed
tiktok_creator_info - Removed
tiktok_mention_top_terms - Removed
unsubscribe_meta_webhooks - Removed
update_business_location - Removed
update_meta_catalog - Removed
update_pinterest_board - Removed
update_pinterest_pin - Removed
update_youtube_channel - Removed
update_youtube_video - Removed
upload_tiktok_comment_image - Removed
x_mentions - Removed
x_post_insights - Removed
x_post_insights_historical - Removed
x_post_metrics - Removed
youtube_bulk_report - Removed
youtube_channel - Removed
youtube_channel_report - Removed
youtube_video_insights
4 tool updates
v0.1.162- Added
fetch_social_data - Changed
list_hooks1 field changed- changed
Input schema / properties / category / descriptionPrevious value: -"the product category (e.g. 'skincare serum', 'protein powder', 'sunglasses') — returns the setting Higgsfield's Location x Tier matrix puts that category in, with the reason"New value: +"the product category (e.g. 'skincare serum', 'protein powder', 'sunglasses') — returns the setting our Location x Tier matrix puts that category in, with the reason"
- Changed
make_explainer1 field changed- changed
Input schema / properties / frameDensity / descriptionPrevious value: -"how many pictures per second of narration, and therefore what it costs. 'standard' (default) is a frame about every 1.5s — the density Higgsfield's own stills pipeline enforces; 'lean' is one about every 2.5s (the longest hold that still reads as a film, ~40% of the frames and ~40% of the cost); 'minimal' is ONE picture per narration section, which is cheapest and is frankly a slideshow. Only drop below the default if the user asked for something cheaper."New value: +"how many pictures per second of narration, and therefore what it costs. 'standard' (default) is a frame about every 1.5s — the density a stills film needs to read as a film rather than a slideshow; 'lean' is one about every 2.5s (the longest hold that still reads as a film, ~40% of the frames and ~40% of the cost); 'minimal' is ONE picture per narration section, which is cheapest and is frankly a slideshow. Only drop below the default if the user asked for something cheaper."
- Removed
scrapecreators_fetch
314 tool updates
v0.1.161- Changed
analyze_video1 field changed- changed
Output schema / (root)Previous value: -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "durationSeconds": { - "description": "the video length in seconds", - "type": "number" - }, - "frameTimes": { - "description": "timestamps (seconds) of the sampled frames", - "items": { - "type": "number" - }, - "type": "array" - }, - "transcript": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "verbatim voiceover + on-screen text with a beat list (null when silent/unreachable)" - } - }, - "type": "object" -}New value: +null
- Added
answer_google_business_question - Added
append_to_doc - Added
append_to_sheet - Added
backfill_posts - Changed
billing_status1 field changed- changed
Output schema / (root)Previous value: -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "autoReload": { - "description": "auto-reload config ({enabled, thresholdCredits, reloadCredits, available})" - }, - "balanceCredits": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "description": "the current credit balance" - }, - "card": { - "description": "the saved card ({brand, last4}) when present" - }, - "isAdmin": { - "description": "whether this key can change billing", - "type": "boolean" - }, - "paymentMethodOnFile": { - "description": "whether a card is saved for one-click charges", - "type": "boolean" - }, - "plan": { - "description": "the current plan ({id, label, monthlyUsd})" - }, - "role": { - "description": "this key’s billing role (admin/member)", - "type": "string" - } - }, - "type": "object" -}New value: +null
- Added
bluesky_post_metrics - Changed
buy_credits1 field changed- changed
Output schema / (root)Previous value: -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "amountUsd": { - "description": "USD amount of the checkout link", - "type": "number" - }, - "credits": { - "description": "credits added by a completed top-up (or bought by the checkout link)", - "type": "number" - }, - "ok": { - "description": "true when a one-click top-up charge succeeded", - "type": "boolean" - }, - "packId": { - "description": "the pack id the checkout link buys", - "type": "string" - }, - "packs": { - "description": "available credit packs ({id, credits, priceUsd}) when listing", - "items": {}, - "type": "array" - }, - "quote": { - "description": "the one-click charge quote ({packId, credits, priceUsd, card}) awaiting confirm:true" - }, - "url": { - "description": "Stripe checkout URL for a first purchase (no saved card yet)", - "type": "string" - } - }, - "type": "object" -}New value: +null
- Added
cancel_scheduled - Changed
change_voice1 field changed- changed
Output schema / (root)Previous value: -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "jobId": { - "description": "the render job id — poll get_job with this id to resume or inspect", - "type": "string" - }, - "model": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "the product-facing label of the model that rendered it" - }, - "raw": { - "description": "the raw job result payload (e.g. images[] for carousel template ads)" - }, - "stillRendering": { - "description": "true when the render is still in progress — keep polling get_job with jobId", - "type": "boolean" - }, - "url": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "the served URL of the finished media (absent/null while still rendering)" - } - }, - "type": "object" -}New value: +null
- Changed
check_ad_policy1 field changed- changed
Output schema / (root)Previous value: -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "anchors": { - "description": "the Meta policy pages consulted ({url, …})", - "items": {}, - "type": "array" - }, - "findings": { - "description": "flagged issues ({severity, issue, policy_quote, fix_suggestion, where_in_ad})", - "items": {}, - "type": "array" - }, - "summary": { - "description": "one-line verdict summary", - "type": "string" - }, - "verdict": { - "description": "pass / fix / block", - "type": "string" - } - }, - "type": "object" -}New value: +null
- Added
clear_sheet_range - Added
clip_video - Added
collect_post_metrics - Added
comment_on_meta_post - Added
comment_on_tiktok_video - Changed
competitor_teardown1 field changed- changed
Output schema / (root)Previous value: -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "adCount": { - "description": "how many ads were analyzed", - "type": "number" - }, - "teardown": { - "description": "the playbook — hook_taxonomy, campaigns, white_space, counter_plays, not_saying" - } - }, - "type": "object" -}New value: +null
- Added
convert_onedrive_file - Added
create_brand - Added
create_doc - Changed
create_drive_folder1 field changed- changed
Output schema / (root)Previous value: -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "id": { - "type": "string" - }, - "name": { - "type": "string" - }, - "webViewLink": { - "type": "string" - } - }, - "type": "object" -}New value: +null
- Removed
create_meta_ad - Removed
create_meta_campaign - Added
create_meta_catalog - Added
create_onedrive_folder - Added
create_pinterest_board - Added
create_sheet - Added
create_whatsapp_template - Added
delete_bluesky_post - Added
delete_brand - Added
delete_creator - Changed
delete_drive_file1 field changed- changed
Output schema / (root)Previous value: -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "deleted": { - "type": "string" - }, - "fileId": { - "type": "string" - }, - "ok": { - "type": "boolean" - } - }, - "type": "object" -}New value: +null
- Added
delete_google_business_post - Added
delete_meta_catalog - Removed
delete_meta_object - Added
delete_onedrive_file - Added
delete_pinterest_board - Added
delete_pinterest_pin - Added
delete_playbook - Added
delete_reddit_post - Added
delete_skill - Added
delete_telegram_message - Added
delete_thread - Added
delete_tiktok_post_ad_authorization - Added
delete_whatsapp_template - Added
delete_x_post - Added
delete_youtube_report_job - Added
delete_youtube_video - Added
diagnose_posts - Added
disconnect_connector - Changed
draft_brand1 field changed- changed
Output schema / (root)Previous value: -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "category": { - "description": "the detected category", - "type": "string" - }, - "domain": { - "description": "the brand website domain (empty for non-website drafts)", - "type": "string" - }, - "logo": { - "description": "the detected logo URL", - "type": "string" - }, - "name": { - "description": "the drafted brand name — VERIFY it matches the brand the user meant", - "type": "string" - }, - "palette": { - "description": "the brand colors", - "items": {}, - "type": "array" - }, - "productImages": { - "description": "product photo URLs", - "items": {}, - "type": "array" - }, - "products": { - "description": "the detected products" - }, - "sells": { - "description": "what the brand sells" - }, - "summary": { - "description": "a short positioning summary", - "type": "string" - } - }, - "type": "object" -}New value: +null
- Changed
dub_video3 fields changed- changed
Input schema / properties / script / descriptionPrevious value: -"the original spoken script if known — improves translation fidelity"New value: +"OPTIONAL override for the original spoken words. Leave this out — the source video is transcribed automatically. Only pass it when you already know the exact script and the auto-transcript got it wrong." - added
Input schema / properties / voiceAdded value: +{ + "description": "optional target voice preset, e.g. 'Aria' (warm female) or 'George' (confident male). Defaults to a voice matching the source speaker's register.", + "type": "string" +} - changed
Output schema / (root)Previous value: -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "jobId": { - "description": "the render job id — poll get_job with this id to resume or inspect", - "type": "string" - }, - "model": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "the product-facing label of the model that rendered it" - }, - "raw": { - "description": "the raw job result payload (e.g. images[] for carousel template ads)" - }, - "stillRendering": { - "description": "true when the render is still in progress — keep polling get_job with jobId", - "type": "boolean" - }, - "url": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "the served URL of the finished media (absent/null while still rendering)" - } - }, - "type": "object" -}New value: +null
- Added
duplicate_scheduled - Added
edit_reddit_post - Added
edit_video - Added
edit_x_post - Added
enable_tools - Added
error_detail - Added
export_swipefile_deck - Added
extend_tiktok_post_ad_authorization - Added
fetch_app_screens - Changed
fetch_asset1 field changed- changed
Output schema / (root)Previous value: -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "downloadUrl": { - "description": "a direct download URL for the asset", - "type": "string" - }, - "url": { - "description": "the clickable absolute asset URL", - "type": "string" - } - }, - "type": "object" -}New value: +null
- Changed
find_competitors2 fields changed- changed
Input schema / properties / domain / descriptionPrevious value: -"the brand domain, e.g. yourbrand.com"New value: +"the brand domain, e.g. flourish.com" - changed
Output schema / (root)Previous value: -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "candidates": { - "description": "discovered brands ({name, domain, kind, reason})", - "items": {}, - "type": "array" - }, - "diagnostics": { - "description": "discovery diagnostics (LLM tokens, web grounding)" - } - }, - "type": "object" -}New value: +null
- Changed
finish_video1 field changed- changed
Output schema / (root)Previous value: -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "jobId": { - "description": "the render job id — poll get_job with this id to resume or inspect", - "type": "string" - }, - "model": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "the product-facing label of the model that rendered it" - }, - "raw": { - "description": "the raw job result payload (e.g. images[] for carousel template ads)" - }, - "stillRendering": { - "description": "true when the render is still in progress — keep polling get_job with jobId", - "type": "boolean" - }, - "url": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "the served URL of the finished media (absent/null while still rendering)" - } - }, - "type": "object" -}New value: +null
- Changed
fix_beat1 field changed- changed
Output schema / (root)Previous value: -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "jobId": { - "description": "the render job id — poll get_job with this id to resume or inspect", - "type": "string" - }, - "model": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "the product-facing label of the model that rendered it" - }, - "raw": { - "description": "the raw job result payload (e.g. images[] for carousel template ads)" - }, - "stillRendering": { - "description": "true when the render is still in progress — keep polling get_job with jobId", - "type": "boolean" - }, - "url": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "the served URL of the finished media (absent/null while still rendering)" - } - }, - "type": "object" -}New value: +null
- Added
forget - Added
format_sheet - Changed
generate_avatar2 fields changed- changed
Input schema / properties / resolution / descriptionPrevious value: -"'720p' (default) or '480p' draft"New value: +"'1080p' (default) or '480p'/'720p' draft" - changed
Output schema / (root)Previous value: -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "jobId": { - "description": "the render job id — poll get_job with this id to resume or inspect", - "type": "string" - }, - "model": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "the product-facing label of the model that rendered it" - }, - "raw": { - "description": "the raw job result payload (e.g. images[] for carousel template ads)" - }, - "stillRendering": { - "description": "true when the render is still in progress — keep polling get_job with jobId", - "type": "boolean" - }, - "url": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "the served URL of the finished media (absent/null while still rendering)" - } - }, - "type": "object" -}New value: +null
- Changed
generate_image2 fields changed- added
Input schema / properties / rawAdded value: +{ + "description": "RAW MODEL ACCESS: run the caller’s prompt on the named model with no Hermoso adjustments at all — the prompt reaches the provider byte-identical (no hex-to-colour-name rewrite, no prepended fidelity preamble) and NO saved-brand product photos are attached, so the model you name is the model that renders. Use it to drive the raw catalog; leave it off for an on-brand ad. Billing, the durable Library landing and per-model validation are unchanged.", + "type": "boolean" +} - changed
Output schema / (root)Previous value: -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "image": { - "description": "the served absolute URL of the finished image", - "type": "string" - }, - "model": { - "description": "the product-facing label of the model that rendered it", - "type": "string" - } - }, - "type": "object" -}New value: +null
- Changed
generate_text2 fields changed- added
Input schema / properties / rawAdded value: +{ + "description": "RAW MODEL ACCESS: send the prompt with NO Hermoso system prompt — the model answers as itself rather than as an ad copywriter. Use it whenever the ask is not marketing copy (analysis, code, extraction, a plain question). Default false: the copywriter framing is applied.", + "type": "boolean" +} - changed
Output schema / (root)Previous value: -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "creditsUsed": { - "description": "credits billed for this generation", - "type": "number" - }, - "model": { - "description": "the writing model label", - "type": "string" - }, - "text": { - "description": "the generated text", - "type": "string" - } - }, - "type": "object" -}New value: +null
- Changed
generate_video6 fields changed- added
Input schema / properties / audioAdded value: +{ + "description": "default true. false = render SILENT: no native model audio, no music bed, and no bed charge held or billed. This is the ONLY way to decline the automatic bed (see musicMood) — leave it alone for anything that should have sound, and do not combine it with ttsScript.", + "type": "boolean" +} - changed
Input schema / properties / durationSeconds / descriptionPrevious value: -"clip length in seconds"New value: +"length of THIS ONE clip in seconds — pick one of the CHOSEN model’s listed durations from hermoso_capabilities (never a generic guess: the lists differ per model, from 4–8s on the short models up to 30s on the longest-clip one). This is a single continuous generation, so it CANNOT exceed that model’s longest clip: a longer ask is REFUSED with nothing rendered and nothing charged (it is never quietly truncated). Past ~15s only the long-clip models qualify, and an unnamed render is routed by the narrower auto-pool — so NAME the model in `model` when you are asking for a long single take. For a spot longer than any one clip, use plan_ad with durationSeconds then render_ad, which stitches acts of at most one model clip each (on a 15s-clip model, 40s = 15+15+10)." - changed
Input schema / properties / musicMood / descriptionPrevious value: -"licensed music-bed mood (e.g. upbeat / cinematic) — omit for no music bed"New value: +"WHICH mood the music bed is composed in (upbeat / calm / warm / epic / tense / playful / elegant / hype / chill / dramatic). It does NOT decide WHETHER there is one: a clip that comes back with no audio track — every model hermoso_capabilities lists as \"silent\", plus any audio model that returned mute — gets a bed composed and CHARGED automatically, at the flat per-track fee hermoso_capabilities reports as explainerMusicCredits, and omitting this field only means the mood defaults to \"warm\". Pass audio:false for a genuinely silent clip with no bed and no bed charge." - added
Input schema / properties / rawAdded value: +{ + "description": "RAW MODEL ACCESS: dispatch this prompt to the model BYTE-IDENTICAL — no appended packaging/label guidance, no negative prompt, no reference-binding lines, no hex-to-colour-name rewrite. Use it when you want the model itself rather than Hermoso's render craft. Two provider-mandated corrections still apply, because the vendor hard-fails without them: an @ImageN token that outnumbers the references actually shipped is dropped, and a prompt past the endpoint's published character cap is trimmed at a sentence boundary. Billing, durable delivery and per-model validation are unchanged.", + "type": "boolean" +} - changed
Input schema / properties / resolution / descriptionPrevious value: -"'720p' default; '480p' = cheap fast draft pass, '1080p'/'4k' = premium final delivery (more credits)"New value: +"'1080p' default (what we ship and bill for); '480p'/'720p' = cheaper draft passes, '4k' = premium final delivery (more credits). NOT EVERY MODEL OFFERS EVERY TIER — this enum is what the tool accepts, and each model's OWN `resolutions` list in hermoso_capabilities is what it can actually render (the longest-clip 30s model, for one, tops out at 720p). Ask for a tier the chosen model does not list and it is rendered at that model's best available tier instead, with nothing in the reply saying so — so check `resolutions` before promising anyone 1080p or 4k." - changed
Output schema / (root)Previous value: -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "jobId": { - "description": "the render job id — poll get_job with this id to resume or inspect", - "type": "string" - }, - "model": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "the product-facing label of the model that rendered it" - }, - "raw": { - "description": "the raw job result payload (e.g. images[] for carousel template ads)" - }, - "stillRendering": { - "description": "true when the render is still in progress — keep polling get_job with jobId", - "type": "boolean" - }, - "url": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "the served URL of the finished media (absent/null while still rendering)" - } - }, - "type": "object" -}New value: +null
- Changed
generate_voice1 field changed- changed
Output schema / (root)Previous value: -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "audio": { - "description": "the served absolute URL of the MP3 voice clip", - "type": "string" - }, - "creditsUsed": { - "description": "credits billed for this clip", - "type": "number" - }, - "model": { - "description": "the voice engine label", - "type": "string" - }, - "voice": { - "description": "the voice preset used", - "type": "string" - } - }, - "type": "object" -}New value: +null
- Changed
get_brand1 field changed- changed
Output schema / (root)Previous value: -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "brand": { - "description": "the saved brand profile (name, domain, category, products, palette, …) or null" - }, - "hasBrand": { - "description": "whether a brand is saved for this workspace", - "type": "boolean" - }, - "memoryCount": { - "description": "how many learned memory notes the workspace holds", - "type": "number" - } - }, - "type": "object" -}New value: +null
- Added
get_business_location - Changed
get_drive_file1 field changed- changed
Output schema / (root)Previous value: -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "id": { - "type": "string" - }, - "name": { - "type": "string" - }, - "webContentLink": { - "type": "string" - }, - "webViewLink": { - "type": "string" - } - }, - "type": "object" -}New value: +null
- Changed
get_job1 field changed- changed
Output schema / (root)Previous value: -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "error": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "the failure message when status is error" - }, - "id": { - "description": "the job id", - "type": "string" - }, - "progress": { - "description": "0–1 progress when reported", - "type": "number" - }, - "result": { - "description": "the raw job result payload" - }, - "status": { - "description": "queued | running | done | error", - "type": "string" - }, - "type": { - "description": "the job type (video / stitch / avatar / …)", - "type": "string" - }, - "url": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "the served media URL once done" - } - }, - "type": "object" -}New value: +null
- Added
get_onedrive_file - Added
get_post_refill - Added
get_settings - Changed
get_skill1 field changed- changed
Output schema / (root)Previous value: -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "name": { - "description": "the loaded skill bundle name", - "type": "string" - } - }, - "type": "object" -}New value: +null
- Added
get_tiktok_mention - Added
get_tiktok_post_ad_authorization - Added
google_business_account - Added
google_business_insights - Added
google_business_search_keywords - Added
hermoso_capabilities - Changed
hermoso_credits1 field changed- changed
Output schema / (root)Previous value: -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "accountBalance": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "description": "the account’s Hermoso credit balance (authoritative when authed)" - }, - "balance": { - "description": "raw vendor meter balance (operator/local-dev surface)", - "type": "number" - }, - "recentCalls": { - "description": "recent priced calls with their credit deltas", - "items": {}, - "type": "array" - }, - "sessionStart": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "description": "vendor balance at session start (operator surface)" - }, - "sessionUsed": { - "description": "credits used this session", - "type": "number" - } - }, - "type": "object" -}New value: +null
- Added
hide_thread_reply - Added
instagram_collaborators - Added
instagram_insights - Added
instagram_profile - Added
invite_member - Added
leave_connector - Added
linkedin_page_analytics - Added
list_bluesky_convos - Added
list_bluesky_posts - Changed
list_brands1 field changed- changed
Output schema / (root)Previous value: -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "brands": { - "description": "every brand on the account ({id, name, active})", - "items": {}, - "type": "array" - } - }, - "type": "object" -}New value: +null
- Added
list_business_locations - Added
list_connector_accounts - Added
list_connectors - Added
list_creators - Changed
list_drive_files1 field changed- changed
Output schema / (root)Previous value: -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cursor": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "files": { - "items": {}, - "type": "array" - } - }, - "type": "object" -}New value: +null
- Added
list_errors - Added
list_google_business_posts - Added
list_google_business_questions - Added
list_google_business_reviews - Added
list_hooks - Added
list_inbox - Added
list_instagram_media - Added
list_instagram_shopping_catalogs - Changed
list_jobs1 field changed- changed
Output schema / (root)Previous value: -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "jobs": { - "description": "recent jobs ({id, type, status, …}), newest first", - "items": {}, - "type": "array" - }, - "running": { - "description": "how many jobs are currently running", - "type": "number" - } - }, - "type": "object" -}New value: +null
- Changed
list_library1 field changed- changed
Output schema / (root)Previous value: -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "assets": { - "items": { - "additionalProperties": false, - "properties": { - "ageHours": { - "type": "number" - }, - "kind": { - "type": "string" - }, - "model": { - "type": "string" - }, - "url": { - "type": "string" - } - }, - "required": [ - "url" - ], - "type": "object" - }, - "type": "array" - } - }, - "type": "object" -}New value: +null
- Added
list_linkedin_pages - Added
list_memory - Removed
list_meta_ads - Added
list_meta_catalog_products - Added
list_meta_catalogs - Added
list_meta_comments - Added
list_meta_conversations - Changed
list_meta_pages1 field changed- changed
Output schema / (root)Previous value: -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "adAccounts": { - "items": {}, - "type": "array" - }, - "pages": { - "items": {}, - "type": "array" - } - }, - "type": "object" -}New value: +null
- Added
list_meta_partnership_creators - Added
list_meta_posts - Added
list_meta_product_sets - Added
list_meta_webhook_events - Added
list_onedrive_files - Added
list_pinterest_boards - Added
list_pinterest_pins - Added
list_playbooks - Changed
list_product_photos1 field changed- changed
Output schema / (root)Previous value: -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "photos": { - "description": "the saved photos ({url, label, …})", - "items": {}, - "type": "array" - }, - "summary": { - "description": "a readable rundown of the saved product photos", - "type": "string" - } - }, - "type": "object" -}New value: +null
- Added
list_published_posts - Added
list_reddit_comments - Added
list_reddit_posts - Added
list_scheduled - Added
list_sheet_tabs - Added
list_shopify_products - Changed
list_skills1 field changed- changed
Output schema / (root)Previous value: -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "bundles": { - "description": "bundled skills ({name, description}) loadable via get_skill", - "items": {}, - "type": "array" - }, - "inApp": { - "description": "in-app strategy skills + creative recipes ({id, kind/group})", - "items": {}, - "type": "array" - } - }, - "type": "object" -}New value: +null
- Added
list_swipefile - Added
list_team - Added
list_telegram_chats - Added
list_telegram_dms - Added
list_threads_mentions - Added
list_threads_posts - Added
list_threads_profile_posts - Added
list_threads_replies - Added
list_tiktok_brand_hashtag_posts - Added
list_tiktok_brand_hashtags - Added
list_tiktok_comment_replies - Added
list_tiktok_comments - Added
list_tiktok_mention_comments - Added
list_tiktok_mentions - Added
list_tiktok_videos - Added
list_watch_findings - Added
list_whatsapp_accounts - Added
list_whatsapp_templates - Added
list_x_dms - Added
list_youtube_captions - Added
list_youtube_categories - Added
list_youtube_comments - Added
list_youtube_playlists - Added
list_youtube_report_jobs - Added
list_youtube_video_stats - Added
list_youtube_videos - Added
make_explainer - Changed
make_template_ad1 field changed- changed
Output schema / (root)Previous value: -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "jobId": { - "description": "the render job id — poll get_job with this id to resume or inspect", - "type": "string" - }, - "model": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "the product-facing label of the model that rendered it" - }, - "raw": { - "description": "the raw job result payload (e.g. images[] for carousel template ads)" - }, - "stillRendering": { - "description": "true when the render is still in progress — keep polling get_job with jobId", - "type": "boolean" - }, - "url": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "the served URL of the finished media (absent/null while still rendering)" - } - }, - "type": "object" -}New value: +null
- Added
make_thumbnail - Added
manage_bluesky_convo - Added
manage_instagram_product_tags - Added
manage_linkedin_post - Added
manage_meta_partnership_creator - Changed
manage_meta_post5 fields changed- added
Input schema / properties / confirmChildrenAdded value: +{ + "description": "Instagram only: how many carousel cards the delete also destroys, as the unconfirmed call reported", + "type": "number" +} - added
Input schema / properties / confirmNameAdded value: +{ + "description": "Instagram only: the post’s exact caption line, exactly as the unconfirmed call reported it — required once the post has any likes or comments", + "type": "string" +} - added
Input schema / properties / pageIdAdded value: +{ + "description": "which Page to use — needed when the post id has no page prefix, or when the brand has several Pages and you are deleting an Instagram post", + "type": "string" +} - changed
Input schema / properties / postId / descriptionPrevious value: -"the post id returned by post_to_meta"New value: +"the post id returned by post_to_meta — for Instagram, the media id from list_instagram_media" - changed
Output schema / (root)Previous value: -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "action": { - "type": "string" - }, - "ok": { - "type": "boolean" - }, - "postId": { - "type": "string" - }, - "target": { - "type": "string" - } - }, - "type": "object" -}New value: +null
- Added
manage_sheet_tabs - Added
manage_tiktok_brand_hashtags - Added
manage_youtube_caption - Added
manage_youtube_channel_section - Added
manage_youtube_playlist - Added
manage_youtube_playlist_image - Added
manage_youtube_playlist_items - Added
mark_bluesky_convo_read - Added
meta_catalog_blast_radius - Removed
meta_insights - Added
meta_page_insights - Added
meta_post_insights - Added
meta_webhook_status - Changed
mine_angles1 field changed- changed
Output schema / (root)Previous value: -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "angles": { - "description": "the ranked angle bank ({category, angle, score, hook_draft, proof_quotes})", - "items": {}, - "type": "array" - }, - "note": { - "description": "why no angles were returned, when the bank is empty", - "type": "string" - }, - "sourceCount": { - "description": "how many customer sources were mined", - "type": "number" - } - }, - "type": "object" -}New value: +null
- Added
moderate_meta_comment - Added
moderate_tiktok_comment - Added
moderate_youtube_comment - Added
pinterest_ads_async_report - Added
pinterest_analytics - Added
pinterest_audience_insights - Added
pinterest_targeting_analytics - Changed
plan_ad4 fields changed- added
Input schema / properties / durationSecondsAdded value: +{ + "description": "VIDEO ONLY — the total spot length the user explicitly asked for, in seconds, copied verbatim (30 for \"a 30 second ad\"). The planner authors the storyboard TO it: the scenes’ seconds sum to it and the script is word-budgeted for it. Supported range 4–180; anything outside is CLAMPED to it (the reply says so). A length that fits ONE clip of the render model renders as a single continuous pass; anything longer is STITCHED from acts filled to that model’s clip maximum with the remainder last (on a 15s-clip model, 40 → 15+15+10 and 17 → 13+4) — never time-compressed. The maximum is the model’s own: 15s on most, 30s on the longest-clip model, so a 30s ad can be one unbroken take rather than two acts. Omit when the user named no length; do NOT pass a guess, an omitted value keeps the recipe-aware default.", + "type": "number" +} - added
Input schema / properties / hookAdded value: +{ + "description": "force the VISUAL scroll-stop mechanic the opening beat is built on — a hook id from list_hooks (e.g. \"direct_callout\", \"mid_problem\", \"macro_asmr\"). Omit to let the planner pick. A hook that cannot be delivered in this brief is DROPPED with the reason rather than rendered wrongly — an on-screen-text hook on an authentic/UGC ad is the one that bites, because that register carries zero on-screen text.", + "type": "string" +} - added
Input schema / properties / settingAdded value: +{ + "description": "force the WHERE — a setting id from list_hooks (e.g. \"kitchen\", \"gym\", or a surreal one like \"volcano_rim\" / \"airplane_wing\", which are played 100% straight and never acknowledged). Omit for a neutral setting.", + "type": "string" +} - changed
Output schema / (root)Previous value: -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "brand": { - "description": "the brand grounding embedded in the creative (name, logo, palette, productImages)" - }, - "concept": { - "description": "the one-line creative concept", - "type": "string" - }, - "copy": { - "description": "copy variants ({headline, primary, cta})", - "items": {}, - "type": "array" - }, - "format": { - "description": "the resolved creative format — 'image' or 'video'", - "type": "string" - }, - "image_concept": { - "description": "the render-ready image concept (prompt etc.) when format is image" - }, - "imodel": { - "description": "the image model id to render with", - "type": "string" - }, - "recipe": { - "description": "the resolved recipe id", - "type": "string" - }, - "recipe_label": { - "description": "the resolved recipe display name", - "type": "string" - }, - "render_plan": { - "description": "the routing plan (structure/duration) render_ad honors" - }, - "video_storyboard": { - "description": "the timed storyboard (scenes, cta, music) when format is video" - }, - "vmodel": { - "description": "the video model id to render with", - "type": "string" - } - }, - "type": "object" -}New value: +null
- Changed
plan_variations1 field changed- changed
Output schema / (root)Previous value: -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "angles": { - "description": "alternate key the planner may return the variants under", - "items": {}, - "type": "array" - }, - "variants": { - "description": "the distinct ad angles ({name, hook, headline, visual brief})", - "items": {}, - "type": "array" - } - }, - "type": "object" -}New value: +null
- Changed
post_edit1 field changed- changed
Output schema / (root)Previous value: -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "jobId": { - "description": "the render job id — poll get_job with this id to resume or inspect", - "type": "string" - }, - "model": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "the product-facing label of the model that rendered it" - }, - "raw": { - "description": "the raw job result payload (e.g. images[] for carousel template ads)" - }, - "stillRendering": { - "description": "true when the render is still in progress — keep polling get_job with jobId", - "type": "boolean" - }, - "url": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "the served URL of the finished media (absent/null while still rendering)" - } - }, - "type": "object" -}New value: +null
- Added
post_performance - Added
post_to_bluesky - Added
post_to_google_business - Added
post_to_linkedin - Added
post_to_linkedin_page - Changed
post_to_meta20 fields changed- added
Input schema / properties / allowDuplicateAdded value: +{ + "description": "post it even though an identical post was just made or attempted. Only pass this when the user genuinely wants the same thing posted twice, or when you have LOOKED at the account and confirmed a timed-out attempt did not land.", + "type": "boolean" +} - added
Input schema / properties / altTextAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } + ], + "description": "ACCESSIBILITY — the description screen readers announce, and what the platform otherwise auto-generates badly or not at all. Describe what is actually IN the picture, never the caption. ONE STRING describes the picture; on a CAROUSEL it describes EVERY slide. Pass an ARRAY of strings instead to describe each slide separately, aligned to the slide order — that is strictly better on a multi-slide post, because one sentence read out over six different pictures is wrong for five of them. More descriptions than pictures is refused rather than dropped. WHERE IT LANDS, per Meta’s own docs: INSTAGRAM image posts and the IMAGE slides of an Instagram carousel (up to 1000 characters; dropped rather than sent on a Reel or a video slide, which Meta do not support); FACEBOOK Page photos including every photo of an album, via alt_text_custom (Meta publish no length for it, so nothing is truncated); THREADS on a single-image or single-video post ONLY — Meta document no way to attach alt text to a Threads CAROUSEL slide, so a Threads carousel publishes undescribed and the reply says so rather than risking the whole post on a guess. (AI disclosure is separate and automatic — every Instagram post Hermoso publishes is flagged is_ai_generated, which is not a caller setting.)" +} - added
Input schema / properties / asyncAdded value: +{ + "description": "publish in the BACKGROUND and return a job id to poll with get_job, instead of waiting. USE THIS FOR VIDEO: a Facebook or Instagram video publish routinely outlives an agent transport, and a timeout on the synchronous path leaves you unable to tell whether the post is live. With async:true nothing can time out — the job reports the post id and url when it lands.", + "type": "boolean" +} - added
Input schema / properties / collaboratorsAdded value: +{ + "description": "INSTAGRAM COLLAB — up to 3 Instagram usernames invited to CO-AUTHOR this post. Once one accepts, the post appears on THEIR profile too, with both handles in the header and the likes and comments shared — it is how a brand reaches a creator’s audience without paying for placement, and it is the single most-asked thing a scheduler normally cannot do. Pass handles only (\"hermosoai\"), not profile links; a leading @ is fine. INSTAGRAM ONLY — Facebook and Threads have no collab post at all and are refused BY NAME rather than silently dropping the co-authors — and never on a Story. AN INVITE IS NOT A CO-POST: publishing SENDS a request the other account must accept in their Instagram notifications, and until they do the post is on this brand’s profile ALONE; they may also decline, and Instagram sends no notification either way. So never report the post as live on both accounts — read the invite status back out of the reply, and use instagram_collaborators later to find out whether they accepted.", + "items": { + "type": "string" + }, + "type": "array" +} - added
Input schema / properties / countryCodesAdded value: +{ + "description": "THREADS ONLY — restrict the post to these ISO 3166-1 alpha-2 countries. ⚠ This is an ALLOWLIST, so the post becomes INVISIBLE in every country not named — it narrows reach, it does not target.", + "items": { + "type": "string" + }, + "type": "array" +} - added
Input schema / properties / crossreshareDarkModeAdded value: +{ + "description": "THREADS ONLY — render that Instagram Story in dark mode. Only meaningful alongside crossreshareToIg; on its own it is refused rather than silently ignored, because a parameter that never reaches the wire must not look accepted.", + "type": "boolean" +} - added
Input schema / properties / crossreshareToIgAdded value: +{ + "description": "THREADS ONLY — ALSO share this Threads post to the linked Instagram account AS A STORY (not a feed post), in the same publish. NOT available on a Threads CAROUSEL, which is refused by name rather than silently dropped. THERE IS NO CONFIRMATION: Threads returns no field saying whether the Story was created, so report it as REQUESTED and tell the user to check their Instagram Stories — never that it is live.", + "type": "boolean" +} - added
Input schema / properties / hookAdded value: +{ + "description": "WHAT ANGLE THIS POST IS BUILT ON — the single most valuable field here, and the only moment it can ever be recorded. post_performance groups on it to answer \"which hooks work\", and it needs 5 posts sharing ONE hook before it will call anything a winner, so REUSE THE SAME WORDING across a campaign instead of rephrasing it every time. Best of all, pass a hook id from list_hooks (e.g. \"direct_callout\", \"mid_problem\", \"before_after\") — those fold onto a stable key however they are spelled, so a whole brand accumulates evidence on one row. Your own wording is fine too; it just only groups when you repeat it exactly. Omitting it means this post can never vote on which hook works.", + "type": "string" +} - added
Input schema / properties / idempotencyKeyAdded value: +{ + "description": "SAFE RETRIES. Publishing can take minutes (a video upload, a carousel of ten slides) and a transport can time out while the post SUCCEEDS — retrying blind is how the same thing gets posted twice. Pass any stable string here and a repeat of the SAME publish returns the ORIGINAL post id instead of posting again (24h). You do not have to: an identical publish is auto-recognised for 10 minutes anyway. If a call times out or errors ambiguously, CALL AGAIN WITH THE SAME KEY — that is the safe move, and it will either report the original post or publish it for the first time. It never posts twice.", + "type": "string" +} - added
Input schema / properties / imageUrlsAdded value: +{ + "description": "CAROUSEL — an ORDERED list of image (and, where the channel allows, video) URLs published as ONE post the viewer swipes through. THIS IS NOT “post several” — it is a single post with several slides, which is what a multi-slide creative (a listicle, a “1/6 · SWIPE” deck) actually needs; publishing only its first slide tells the viewer to swipe at something that cannot. The ORDER is the product. Limits per channel: Instagram 2–10 (images, videos or a mix), Threads 2–20 (mix allowed), Facebook 2+ (Meta publishes no documented maximum; Hermoso caps the upload fan-out at 30 and says so), LinkedIn company Pages 2–20 (images only), Pinterest 2–5 (images only), TikTok up to 35. One url here is simply an ordinary single post. Anything a channel cannot do is REFUSED with the real reason — nothing is ever quietly downgraded to one slide.", + "items": { + "type": "string" + }, + "type": "array" +} - added
Input schema / properties / linkAttachmentAdded value: +{ + "description": "THREADS TEXT POSTS ONLY — a full http(s) URL rendered as a clickable link card. This is how a Threads post carries a destination at all; without it a link is just text. Meta allows at most 5 links per post and refuses a link attachment on a post that also carries an image or video, so Hermoso refuses that combination up front rather than letting Meta silently drop it.", + "type": "string" +} - added
Input schema / properties / locationIdAdded value: +{ + "description": "Threads only — a place id from search_threads_locations, to geotag the post to a physical location (restaurant, storefront)", + "type": "string" +} - added
Input schema / properties / productTagsAdded value: +{ + "description": "INSTAGRAM SHOPPING — make the post SHOPPABLE by tagging products from the brand’s own catalog; tapping a tag opens the product’s price sheet inside Instagram. Instagram only. ON A PHOTO each tag is {product_id, x, y}, where x and y are FRACTIONS of the image from 0.0 (left/top) to 1.0 (right/bottom) — 0.5,0.5 is the middle — and BOTH are required, max 20. ON A REEL it is {product_id} ALONE with no coordinates, max 30. ON A CAROUSEL it is an array PER SLIDE ([[{…}], [], [{…}]]) because Instagram tags each slide’s own container, max 5 per slide and 20 across the post. Ids come from search_instagram_shopping_products; call list_instagram_shopping_catalogs FIRST, because tagging needs an APPROVED Instagram Shop and without one this fails after the media is already uploaded. A tag whose product is not “approved” is stored and shown to nobody.", + "items": {}, + "type": "array" +} - added
Input schema / properties / quotePostIdAdded value: +{ + "description": "THREADS ONLY — the id of a post to QUOTE. A quote post is a distinct post type, not a formatting option.", + "type": "string" +} - added
Input schema / properties / replyControlAdded value: +{ + "description": "THREADS ONLY — who may reply. Default is everyone.", + "enum": [ + "everyone", + "accounts_you_follow", + "mentioned_only", + "parent_post_author_only", + "followers_only" + ], + "type": "string" +} - added
Input schema / properties / scheduleAtAdded value: +{ + "description": "FACEBOOK ONLY — schedule instead of posting now. ISO timestamp (2026-08-01T09:00:00Z) or unix seconds; must be 10 minutes to 30 days ahead. Facebook holds the post and publishes it at that time, so nothing has to stay running on our side. Instagram and Threads have NO scheduling in Meta’s API — passing this for them is refused rather than silently posted immediately.", + "type": "string" +} - added
Input schema / properties / subjectAdded value: +{ + "description": "WHAT THIS POST IS ABOUT — the product, feature, offer or theme (e.g. \"winter coat\", \"free trial\", \"founder story\"). The second grouping axis in post_performance. Same rule as hook: reuse the exact wording so posts about one subject land in one group.", + "type": "string" +} - added
Input schema / properties / topicTagAdded value: +{ + "description": "THREADS ONLY — one topic tag for discovery, 1–50 characters. A leading # is stripped for you; Threads refuses \".\" and \"&\".", + "type": "string" +} - added
Input schema / properties / trialReelAdded value: +{ + "description": "INSTAGRAM TRIAL REEL — publish this Reel to NON-FOLLOWERS ONLY at first, so a hook can be tested on a cold audience without spending it on the people who already follow the brand. Instagram then shows it to followers only if it graduates. MANUAL = the creator graduates it by hand in the Instagram app; SS_PERFORMANCE = Instagram graduates it automatically if it performs well. REELS ONLY and INSTAGRAM ONLY: an image, a carousel, a Facebook post or a Threads post is REFUSED BY NAME rather than quietly published as an ordinary post — a trial that silently goes to every follower is the exact opposite of what was asked for. Omit it for a normal Reel.", + "enum": [ + "MANUAL", + "SS_PERFORMANCE" + ], + "type": "string" +} - changed
Output schema / (root)Previous value: -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "account": { - "type": "string" - }, - "ok": { - "type": "boolean" - }, - "page": { - "type": "string" - }, - "postId": { - "type": "string" - }, - "target": { - "type": "string" - }, - "url": { - "type": "string" - } - }, - "type": "object" -}New value: +null
- Added
post_to_pinterest - Added
post_to_reddit - Added
post_to_telegram - Added
post_to_tiktok - Added
post_to_x - Added
post_to_youtube - Added
post_x_article - Added
product_sizzle - Added
publish_to_shopify_product - Changed
pull_competitor_ads2 fields changed- removed
Input schema / properties / platformsRemoved value: -{ - "description": "default ['facebook']; add 'google','linkedin'", - "items": { - "type": "string" - }, - "type": "array" -} - changed
Output schema / (root)Previous value: -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "facebook": { - "description": "Meta results ({ads[], matched} or {error}; null when not requested)" - }, - "google": { - "description": "Google results ({ads[], cursor} or {error}; null when not requested)" - }, - "linkedin": { - "description": "LinkedIn results ({ads[], cursor} or {error}; null when not requested)" - } - }, - "type": "object" -}New value: +null
- Added
react_to_bluesky_dm - Added
read_bluesky_dm - Added
read_doc - Added
read_meta_conversation - Added
read_sheet - Changed
recast_motion1 field changed- changed
Output schema / (root)Previous value: -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "jobId": { - "description": "the render job id — poll get_job with this id to resume or inspect", - "type": "string" - }, - "model": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "the product-facing label of the model that rendered it" - }, - "raw": { - "description": "the raw job result payload (e.g. images[] for carousel template ads)" - }, - "stillRendering": { - "description": "true when the render is still in progress — keep polling get_job with jobId", - "type": "boolean" - }, - "url": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "the served URL of the finished media (absent/null while still rendering)" - } - }, - "type": "object" -}New value: +null
- Added
reddit_post_stats - Changed
reframe_video1 field changed- changed
Output schema / (root)Previous value: -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "jobId": { - "description": "the render job id — poll get_job with this id to resume or inspect", - "type": "string" - }, - "model": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "the product-facing label of the model that rendered it" - }, - "raw": { - "description": "the raw job result payload (e.g. images[] for carousel template ads)" - }, - "stillRendering": { - "description": "true when the render is still in progress — keep polling get_job with jobId", - "type": "boolean" - }, - "url": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "the served URL of the finished media (absent/null while still rendering)" - } - }, - "type": "object" -}New value: +null
- Added
remember - Changed
remix_static1 field changed- changed
Output schema / (root)Previous value: -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "image": { - "description": "the served absolute URL of the remixed ad image", - "type": "string" - }, - "model": { - "description": "the model label that rendered it", - "type": "string" - }, - "residual": { - "description": "source-branding sweep result ({clean, note})" - }, - "slots": { - "description": "the filled slot map (layout elements swapped to your brand)" - } - }, - "type": "object" -}New value: +null
- Added
remove_member - Changed
render_ad5 fields changed- added
Input schema / properties / allowGenericProductAdded value: +{ + "description": "proceed even though this brand has NO product photo on file and the ad features a product — the packaging will be INVENTED. Only pass true after telling the user that and hearing they are fine with a generic stand-in", + "type": "boolean" +} - added
Input schema / properties / creatorAdded value: +{ + "description": "CAST A SAVED CREATOR in this ad — their id from list_creators, or the name you know them by (“Sarah”). Their saved portrait becomes the on-camera identity for the whole spot, so the same face carries across every act and across every ad you render for this brand — and because we already have their picture, the character portrait this pipeline would otherwise generate is skipped, so casting somebody costs LESS than not casting them. Omit to let the ad cast a fresh person. Refused for free, with nothing rendered, if the name matches nobody or more than one creator, if the plan has nobody on camera, or if they are a REAL person with no likeness consent on file.", + "type": "string" +} - changed
Input schema / properties / durationSeconds / descriptionPrevious value: -"total ad length in seconds — omit to honor the plan’s own duration"New value: +"total ad length in seconds (supported range 4–180; outside that it is clamped). Omit to honor the plan’s own duration — that is almost always right. This only RE-TIMES an already-authored board (its scenes are scaled to fit), it does NOT re-write it, so to change the length of the ad the user asked for, re-run plan_ad with durationSeconds instead. A length that fits ONE clip of the render model renders as one continuous pass; longer is stitched from acts filled to that model’s clip maximum with the remainder last — the maximum is 15s on most models and 30s on the longest-clip one, so use dryRun:true to see the exact act split for free before spending." - changed
Input schema / properties / resolution / descriptionPrevious value: -"'720p' default; '480p' = cheap fast draft pass, '1080p'/'4k' = premium final delivery (more credits)"New value: +"'1080p' default (what we ship and bill for); '480p'/'720p' = cheaper draft passes, '4k' = premium final delivery (more credits). NOT EVERY MODEL OFFERS EVERY TIER — this enum is what the tool accepts, and each model's OWN `resolutions` list in hermoso_capabilities is what it can actually render (the longest-clip 30s model, for one, tops out at 720p). Ask for a tier the chosen model does not list and it is rendered at that model's best available tier instead, with nothing in the reply saying so — so check `resolutions` before promising anyone 1080p or 4k." - changed
Output schema / (root)Previous value: -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "dryRun": { - "description": "true when this was a dry run (no job submitted, nothing charged)", - "type": "boolean" - }, - "input": { - "description": "the assembled render input (dry run only — resolved model, duration, scenes)" - }, - "jobId": { - "description": "the render job id — poll get_job with this id to resume or inspect", - "type": "string" - }, - "jobType": { - "description": "the routing decision — 'video' (single pass) or 'stitch' (acts)", - "type": "string" - }, - "model": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "the product-facing label of the model that rendered it" - }, - "raw": { - "description": "the raw job result payload (e.g. images[] for carousel template ads)" - }, - "stillRendering": { - "description": "true when the render is still in progress — keep polling get_job with jobId", - "type": "boolean" - }, - "url": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "the served URL of the finished media (absent/null while still rendering)" - } - }, - "type": "object" -}New value: +null
- Added
reply_to_google_business_review - Added
reply_to_inbox_item - Added
reply_to_meta_comment - Added
reply_to_meta_message - Added
reply_to_reddit_comment - Added
reply_to_thread - Added
reply_to_tiktok_comment - Added
reply_to_youtube_comment - Added
report_bug - Added
repost_thread - Added
request_feature - Added
reschedule_post - Changed
research_ads1 field changed- changed
Output schema / (root)Previous value: -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "actions": { - "description": "follow-up actions the research loop suggested" - }, - "reply": { - "description": "the research summary", - "type": "string" - }, - "results": { - "description": "the found ads/videos (normalized card objects with served URLs)", - "items": {}, - "type": "array" - } - }, - "type": "object" -}New value: +null
- Added
retry_scheduled - Added
run_post_refill - Added
save_creator - Added
save_pinterest_pin - Added
save_playbook - Added
save_skill - Changed
save_to_drive1 field changed- changed
Output schema / (root)Previous value: -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "failed": { - "type": "number" - }, - "files": { - "items": {}, - "type": "array" - }, - "ok": { - "type": "boolean" - } - }, - "type": "object" -}New value: +null
- Added
save_to_onedrive - Added
save_to_swipefile - Added
schedule_post - Changed
score_ad1 field changed- changed
Output schema / (root)Previous value: -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "dimensions": { - "description": "per-dimension breakdown ({name, score})", - "items": {}, - "type": "array" - }, - "overall": { - "description": "the overall score out of 100", - "type": "number" - }, - "strengths": { - "description": "what the ad already does well" - }, - "tier": { - "description": "the qualitative tier", - "type": "string" - }, - "top_fix": { - "description": "the single biggest improvement lever", - "type": "string" - } - }, - "type": "object" -}New value: +null
- Changed
scrapecreators_fetch1 field changed- changed
Output schema / (root)Previous value: -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": {}, - "type": "object" -}New value: +null
- Changed
search_google_ads1 field changed- changed
Output schema / (root)Previous value: -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "ads": { - "description": "the compact ad objects ({advertiser, format, adUrl, image, firstShown, lastShown})", - "items": {}, - "type": "array" - }, - "found": { - "description": "total ads found upstream", - "type": "number" - } - }, - "type": "object" -}New value: +null
- Changed
search_instagram1 field changed- changed
Output schema / (root)Previous value: -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "found": { - "description": "total reels found", - "type": "number" - }, - "reels": { - "description": "the compact reel objects ({desc, author, handle, plays, likes, link, cover}), ranked by plays", - "items": {}, - "type": "array" - } - }, - "type": "object" -}New value: +null
- Added
search_instagram_hashtag - Added
search_instagram_shopping_products - Changed
search_linkedin_ads1 field changed- changed
Output schema / (root)Previous value: -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "ads": { - "description": "the compact ad objects ({advertiser, headline, description, cta, link, media, dates, impressions})", - "items": {}, - "type": "array" - }, - "found": { - "description": "total ads found upstream", - "type": "number" - } - }, - "type": "object" -}New value: +null
- Changed
search_meta_ads1 field changed- changed
Output schema / (root)Previous value: -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "ads": { - "description": "the compact ad objects ({page_name, body, cta, link, dates, media})", - "items": {}, - "type": "array" - }, - "found": { - "description": "total ads found upstream", - "type": "number" - } - }, - "type": "object" -}New value: +null
- Added
search_pinterest_ads_targeting - Changed
search_reddit1 field changed- changed
Output schema / (root)Previous value: -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "found": { - "description": "total posts found", - "type": "number" - }, - "posts": { - "description": "the compact post objects ({desc, subreddit, upvotes, comments, link})", - "items": {}, - "type": "array" - } - }, - "type": "object" -}New value: +null
- Changed
search_threads1 field changed- changed
Output schema / (root)Previous value: -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "found": { - "description": "total posts found", - "type": "number" - }, - "posts": { - "description": "the compact post objects ({desc, author, handle, likes, link, cover})", - "items": {}, - "type": "array" - } - }, - "type": "object" -}New value: +null
- Added
search_threads_keyword - Added
search_threads_locations - Changed
search_tiktok1 field changed- changed
Output schema / (root)Previous value: -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "found": { - "description": "total videos found", - "type": "number" - }, - "videos": { - "description": "the compact video objects ({desc, author, handle, plays, likes, link, cover}), ranked by plays", - "items": {}, - "type": "array" - } - }, - "type": "object" -}New value: +null
- Changed
search_youtube1 field changed- changed
Output schema / (root)Previous value: -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "found": { - "description": "total videos found", - "type": "number" - }, - "videos": { - "description": "the compact video objects ({desc, author, handle, plays, link, cover}), ranked by views", - "items": {}, - "type": "array" - } - }, - "type": "object" -}New value: +null
- Added
send_bluesky_dm - Added
send_whatsapp_broadcast - Added
send_whatsapp_message - Added
send_x_dm - Changed
set_auto_reload1 field changed- changed
Output schema / (root)Previous value: -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "applied": { - "description": "whether the auto-reload config was applied", - "type": "boolean" - }, - "capUsd": { - "description": "monthly auto-reload spend cap in USD, if set" - }, - "enabled": { - "description": "the resulting auto-reload state", - "type": "boolean" - }, - "guidance": { - "description": "instructions when the change must be made in the app", - "type": "string" - }, - "needsCard": { - "description": "true when there is no saved card yet (add one in the app first)", - "type": "boolean" - }, - "reloadCredits": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "description": "credits added per reload" - }, - "reloadPack": { - "description": "the pack charged on each reload" - }, - "status": { - "description": "auto-reload status detail", - "type": "string" - }, - "thresholdCredits": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "description": "reload triggers below this balance" - } - }, - "type": "object" -}New value: +null
- Added
set_competitor_watch - Added
set_connector_accounts - Removed
set_meta_campaign_status - Added
set_post_refill - Changed
set_product_image1 field changed- changed
Output schema / (root)Previous value: -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "attached": { - "description": "true when the image passed the product check and was locked", - "type": "boolean" - }, - "source_note": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "where the photo came from" - }, - "summary": { - "description": "the check verdict — on rejection, why nothing was locked", - "type": "string" - }, - "url": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "the durable served URL of the locked product photo" - } - }, - "type": "object" -}New value: +null
- Added
set_role - Added
set_tiktok_post_ad_authorization - Added
set_youtube_thumbnail - Added
set_youtube_watermark - Changed
stitch_video2 fields changed- changed
Input schema / properties / resolution / descriptionPrevious value: -"720p (default), 480p draft, or 1080p final"New value: +"1080p (default), or 480p/720p for a cheaper draft" - changed
Output schema / (root)Previous value: -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "jobId": { - "description": "the render job id — poll get_job with this id to resume or inspect", - "type": "string" - }, - "model": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "the product-facing label of the model that rendered it" - }, - "raw": { - "description": "the raw job result payload (e.g. images[] for carousel template ads)" - }, - "stillRendering": { - "description": "true when the render is still in progress — keep polling get_job with jobId", - "type": "boolean" - }, - "url": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "the served URL of the finished media (absent/null while still rendering)" - } - }, - "type": "object" -}New value: +null
- Added
store_get - Added
subscribe_meta_webhooks - Added
threads_insights - Added
threads_profile - Added
threads_publishing_limit - Added
tiktok_account - Added
tiktok_account_insights - Added
tiktok_account_status - Added
tiktok_category_benchmark - Added
tiktok_creator_info - Added
tiktok_mention_top_terms - Added
unsubscribe_meta_webhooks - Added
update_brand - Added
update_business_location - Added
update_doc - Changed
update_drive_file1 field changed- changed
Output schema / (root)Previous value: -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "id": { - "type": "string" - }, - "name": { - "type": "string" - }, - "trashed": { - "type": "boolean" - } - }, - "type": "object" -}New value: +null
- Added
update_meta_catalog - Removed
update_meta_object - Added
update_onedrive_file - Added
update_pinterest_board - Added
update_pinterest_pin - Added
update_settings - Added
update_sheet - Added
update_youtube_channel - Added
update_youtube_video - Changed
upgrade_plan1 field changed- changed
Output schema / (root)Previous value: -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "action": { - "description": "the in-app action required ('upgrade' or 'downgrade')", - "type": "string" - }, - "chargeUsd": { - "description": "the actual charge amount (yearly billing charges the annual total)", - "type": "number" - }, - "guidance": { - "description": "exact instructions when the change must be made in the app", - "type": "string" - }, - "mode": { - "description": "'checkout' (a Stripe URL was minted) or 'in_app' (a person makes the change in the app)", - "type": "string" - }, - "monthlyUsd": { - "description": "the plan’s monthly price in USD", - "type": "number" - }, - "period": { - "description": "billing cadence of the link — 'mo' or 'yr'", - "type": "string" - }, - "plan": { - "description": "the target plan id", - "type": "string" - }, - "planLabel": { - "description": "the target plan display name", - "type": "string" - }, - "plans": { - "description": "available paid plans ({id, name, priceUsd, credits}) when listing", - "items": {}, - "type": "array" - }, - "url": { - "description": "the ready-to-pay Stripe Checkout URL (checkout mode)", - "type": "string" - } - }, - "type": "object" -}New value: +null
- Changed
upload_file3 fields changed- changed
Input schema / properties / dataUri / descriptionPrevious value: -"base64 data: URI of the file bytes (data:<mime>;base64,<…>)"New value: +"base64 data: URI of the file bytes (data:<mime>;base64,<…>) — bytes travel over this connection, so keep it small" - added
Input schema / properties / urlAdded value: +{ + "description": "a PUBLIC http(s) URL Hermoso fetches server-side (private/internal addresses are refused, and every redirect hop is re-checked). Works on every surface including the hosted connector, and the bytes never cross this connection — prefer this whenever the file is reachable on the web.", + "type": "string" +} - changed
Output schema / (root)Previous value: -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "bytes": { - "type": "number" - }, - "kind": { - "type": "string" - }, - "url": { - "type": "string" - } - }, - "type": "object" -}New value: +null
- Removed
upload_meta_asset - Added
upload_tiktok_comment_image - Changed
upscale_video1 field changed- changed
Output schema / (root)Previous value: -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "jobId": { - "description": "the render job id — poll get_job with this id to resume or inspect", - "type": "string" - }, - "model": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "the product-facing label of the model that rendered it" - }, - "raw": { - "description": "the raw job result payload (e.g. images[] for carousel template ads)" - }, - "stillRendering": { - "description": "true when the render is still in progress — keep polling get_job with jobId", - "type": "boolean" - }, - "url": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "the served URL of the finished media (absent/null while still rendering)" - } - }, - "type": "object" -}New value: +null
- Changed
use_brand2 fields changed- changed
Input schema / properties / brand / descriptionPrevious value: -"brand id (e.g. default / p_xxx) or its exact name from list_brands"New value: +"brand id (e.g. default / p_xxx), its exact name from list_brands, or the profile id of a workspace shared with you" - changed
Output schema / (root)Previous value: -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "brand": { - "description": "the now-active brand ({id, name})" - }, - "ok": { - "description": "true when the brand switch persisted", - "type": "boolean" - } - }, - "type": "object" -}New value: +null
- Added
x_mentions - Added
x_post_insights - Added
x_post_insights_historical - Added
x_post_metrics - Added
youtube_bulk_report - Added
youtube_channel - Added
youtube_channel_report - Added
youtube_video_insights
32 tool updates
v0.1.15- Changed
billing_status2 fields changed- added
Output schema / properties / balanceCredits / anyOfAdded value: +[ + { + "type": "number" + }, + { + "type": "null" + } +] - removed
Output schema / properties / balanceCredits / typeRemoved value: -"number"
- Changed
buy_credits1 field changed- added
Input schema / properties / quote_tokenAdded value: +{ + "description": "the quoteToken returned by the quote step — REQUIRED (with confirm:true) to charge; it binds the exact pack + price you quoted (10-minute validity) and makes a retried confirm idempotent", + "type": "string" +}
- Added
create_drive_folder - Added
create_meta_ad - Added
create_meta_campaign - Added
delete_drive_file - Added
delete_meta_object - Added
generate_text - Added
generate_video - Added
get_drive_file - Added
get_job - Removed
hermoso_capabilities - Added
hermoso_credits - Added
list_brands - Added
list_drive_files - Added
list_jobs - Added
list_library - Added
list_meta_ads - Added
list_meta_pages - Added
manage_meta_post - Added
meta_insights - Added
plan_ad - Added
post_edit - Added
post_to_meta - Added
save_to_drive - Added
set_auto_reload - Added
set_meta_campaign_status - Added
stitch_video - Added
update_drive_file - Added
update_meta_object - Added
upload_file - Added
upload_meta_asset
24 tool updates
v0.1.0- Added
billing_status - Added
dub_video - Added
fix_beat - Added
get_brand - Removed
get_job - Added
get_skill - Added
hermoso_capabilities - Removed
hermoso_credits - Removed
list_brands - Removed
list_jobs - Added
make_template_ad - Removed
plan_ad - Added
pull_competitor_ads - Added
recast_motion - Added
research_ads - Added
search_linkedin_ads - Added
search_meta_ads - Added
search_reddit - Added
search_youtube - Removed
set_auto_reload - Removed
stitch_video - Added
upgrade_plan - Added
upscale_video - Added
use_brand
33 tool updates
v0.1.0- First observed
analyze_video - First observed
buy_credits - First observed
change_voice - First observed
check_ad_policy - First observed
competitor_teardown - First observed
draft_brand - First observed
fetch_asset - First observed
find_competitors - First observed
finish_video - First observed
generate_avatar - First observed
generate_image - First observed
generate_voice - First observed
get_job - First observed
hermoso_credits - First observed
list_brands - First observed
list_jobs - First observed
list_product_photos - First observed
list_skills - First observed
mine_angles - First observed
plan_ad - First observed
plan_variations - First observed
reframe_video - First observed
remix_static - First observed
render_ad - First observed
score_ad - First observed
scrapecreators_fetch - First observed
search_google_ads - First observed
search_instagram - First observed
search_threads - First observed
search_tiktok - First observed
set_auto_reload - First observed
set_product_image - First observed
stitch_video
TDQS
Each tool has a clearly distinct purpose: billing tools (hermoso_credits, buy_credits, set_auto_reload) are separate from generation tools (generate_image, generate_voice, generate_avatar) and research tools (search_google_ads, search_tiktok, etc.). Even similar tools like plan_ad and plan_variations differ in scope (single concept vs. multiple angles).
Most tools follow a verb_noun pattern (e.g., list_brands, generate_image, search_tiktok), but there are inconsistencies like 'scrapecreators_fetch' (instead of fetch_scrapecreators) and 'hermoso_credits' (no verb). However, the pattern is broadly predictable.
With 33 tools, the server exceeds the 'too many' threshold of 25. While the scope is broad (ad creation, research, billing, etc.), the high number risks bloat and could be streamlined by combining some tools (e.g., merging search tools into one with a platform parameter).
The tool set covers the full ad creation lifecycle: brand onboarding, product image management, research (competitors, social platforms), planning, generation (image, voice, avatar, video), post-processing, analysis, and policy checking. No obvious gaps for the domain.
Maintenance
Related MCP Connectors
Competitive ad intelligence for AI agents: portfolios, ad/content search, analytics, discovery.
AI image, video and audio generation for agents: banners, reveal videos, avatars, voice cloning.
60+ Meta Ads tools for AI agents: audits, campaign management, audiences and CAPI tracking.
Run ads on Google, Meta, LinkedIn, TikTok and more from AI. 460+ tools across 14 platforms.
Related MCP Servers
- AlicenseAqualityDmaintenanceProvides Meta and Google Ads intelligence for AI assistants, enabling users to analyze performance, track competitors, and manage ad campaigns through natural language. It features 17 tools for generating creative concepts, scraping competitor ads, and performing deep account-level analysis.17MIT
- AlicenseNot gradedqualityDmaintenanceGenerate AI UGC video ads from any product URL in 5 minutes. Realistic AI avatars, natural voiceover, proven ad templates. No actors, no editing, no experience required.1441MIT
- FlicenseNot gradedqualityDmaintenanceSearches and analyzes competitor ads and content across Meta, Google, Instagram, TikTok, and YouTube with AI-powered creative analysis and cross-platform brand discovery.1-
- AlicenseNot gradedqualityAmaintenanceManage ad campaigns across Meta, Google, and TikTok, create campaigns, analyze performance, spy on competitors, and generate AI creatives.12MIT
Appeared in Searches
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/hermoso-ai/hermoso'
If you have feedback or need assistance with the MCP directory API, please join our Discord server