Skip to main content
Glama

Server Details

Unified GTM API for AI agents: find leads, enrich to verified emails, verify, detect intent, social listening, provision warmed sending, launch human-approved campaigns and handle replies. One key, prepaid credits.

Ownership verified
Status
Healthy
Uptime
100.0% over 43 days
Last Tested
Transport
Streamable HTTP · MCP 2025-11-25
URL

TDQS

A3.9/5.0

Scored across 22 tools

Disambiguation4/5

Most tools have distinct resource/action targets, and the descriptions explicitly route between similar-sounding tools such as check_companies, find_intent, research_company, and prospect_picture. There is still conceptual overlap among the research, intent, and company-checking tools that could cause occasional misselection.

Naming Consistency4/5

The set is overwhelmingly consistent snake_case, usually with a verb_noun pattern such as find_leads, create_campaign, get_reply, and verify_email. Minor deviations like prospect_picture and reply_to_thread are readable but not perfectly aligned with the dominant convention.

Tool Count4/5

At 22 tools this is heavier than an ideal compact set, but the server spans a broad GTM workflow: discovery, enrichment, intent, research, campaigns, sending, replies, and operations. Each tool maps to a recognizable stage, with no obvious duplicate requiring removal.

Completeness4/5

The surface covers the main outbound lifecycle from company/lead discovery through enrichment, campaign creation, launch, replies, and status tracking. Notable gaps remain around campaign read/listing/update or pause operations and suppression-list management, but core workflows are workable.

Available Tools

22 tools
add_leadsAdd leads to campaignA
DestructiveIdempotent
Inspect

Add recipients to a draft or incomplete campaign through the suppression-safe bulk importer. Returns removed counts for recipients not added and their reasons. Adding to an active campaign pauses it and requires signed-in human confirmation before recipients enter the sequence. The campaign-wide maximum is 5,000 unique recipients. dry_run: true returns an advisory estimate as of evaluated_at, reserves nothing, and may differ from a later execution plan. Pass each person’s location from find_leads or enrich in leads[].location (at most 200 characters). Active area rules leave new people with no location out; removed.no_location is included in removed.do_not_contact, not added again to total.

NameRequiredDescriptionDefault
leadsNo
dry_runNo
campaign_idYes
idempotency_keyYesA payment_required refusal means services are stopped for unpaid billing; direct the owner to the billing link in the error. Campaigns stay paused after payment until restarted. Optional for search and enrichment tools: supply one so a retry returns the original result without paying again; if that call failed with provider_unavailable, rate_limited or insufficient_credits (after a top-up), a retry runs it once more after its cooldown (30 s, or a longer retry_after_seconds; insufficient_credits as soon as the balance covers it), unless its provider may already have done the work. Required for tools that create an external side effect; reuse the same value after a timeout or an approval. A stored failure comes back with details.replayed: true; with retry_after_seconds, retry the same value after that.
confirmation_tokenNo
finalize_incompleteNo

TDQS

A4.3/5.0
Behavior5/5

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

Adds substantial context beyond the annotations: returns removed counts with reasons, pauses active campaigns pending signed-in human confirmation, enforces a 5,000 unique-recipient campaign maximum, and details dry_run's non-reserving semantics. The do_not_contact/removed.no_location accounting behavior is disclosed, which an agent could not infer from destructiveHint=true alone.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

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

Front-loads the core action and keeps every sentence informational — limits, confirmation, dry_run, and location rules each add distinct value. Some sentences are densely packed and require a second read, but there is no filler.

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

Completeness4/5

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

For a destructive, open-world mutation with no output schema, the description covers the return shape (removed counts and reasons), the confirmation gate, and capacity limits. The remaining shortfall is the unexplained confirmation_token/finalize_incomplete parameters, which an agent invoking the approval flow would need.

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

Parameters3/5

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

Schema description coverage is only 17%, and the description compensates for two parameters well: dry_run (advisory estimate as of evaluated_at, reserves nothing, may diverge from a later plan) and leads[].location (sourced from find_leads/enrich, 200-char cap). However confirmation_token, finalize_incomplete, and campaign_id carry no meaning in the description, so the gap is only partly closed.

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

Purpose5/5

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

States a specific verb+resource ('Add recipients to a draft or incomplete campaign') and distinguishes itself from the campaign-creation sibling by scoping to existing draft/incomplete campaigns. The suppression-safe bulk importer framing tells the agent exactly what mechanism is used.

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

Usage Guidelines4/5

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

Gives clear conditional guidance: use dry_run for an advisory estimate, expect a pause plus human confirmation when targeting an active campaign, and source location values from find_leads or enrich. It stops short of an explicit 'use X instead when Y' routing against siblings such as find_leads or launch_campaign.

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

check_companiesCheck companiesA
Destructive
Inspect

Answer one yes/no question about each of up to 10 companies from its own website, e.g. "Do they let their users book appointments inside their product?" or "Do they publish a public API?". For angles, what's changed, how to approach, or why now on one company or person, use research_company (a company) or prospect_picture (a person, their company, or both) instead. Ask about what the company offers or does, as a seller would. Each answer is yes (with the passage from the company's own site that states it, quoted word for word, and its page URL), not_found (every passage of the pages listed in pages_read was checked and none touches it; that is not proof it's absent) or unclear (the pages hint at it but no single passage states it). A yes always comes with a passage that states it on its own. 3.5 credits per company answered yes or not_found; unclear answers and unreadable sites are free. An unreadable company's site blocked our reader; it's free and you can ask again with different words or skip it. A call answers within about a minute; a company it could not reach in that time comes back unclear (free), so send it again. Use it after a broad company search to keep only companies with the need, before paying for people or emails. budget_credits is a spend ceiling, never permission to use a dearer source: above it, the call is refused before anything is reserved, and no company you sent is dropped to fit. dry_run: true returns the plan instead (the most the call can cost, how many sources could answer, and each limit it would trip) with nothing looked up, reserved or charged. Example: {"question":"Do they let their users book appointments inside their product?","company_domains":["acme.com","example.io"]}

NameRequiredDescriptionDefault
dry_runNoReturn this call's plan instead of running it, as of evaluated_at: the most it can cost, how many sources could answer, what budget_credits changes, and every limit the real call would trip. Nothing is looked up, reserved or charged, and a later call may differ. Where previews aren't available to this key yet, a request that sets it is refused with the reason.
questionYesOne yes/no question about each company's own offering, as a seller would ask it (10–300 characters), e.g. "Do they let their users book appointments inside their product?". Answered only from the company's own website.
budget_creditsNoSpend ceiling for this call, in credits. If the most the call can cost is above it, the call is refused before anything is reserved or charged. No company you sent is dropped to fit. It is a ceiling only: it never lets the call use a dearer source. Where spend ceilings aren't available to this key yet, a request that sets it is refused with the reason.
company_domainsYes
idempotency_keyNoA payment_required refusal means services are stopped for unpaid billing; direct the owner to the billing link in the error. Campaigns stay paused after payment until restarted. Optional for search and enrichment tools: supply one so a retry returns the original result without paying again; if that call failed with provider_unavailable, rate_limited or insufficient_credits (after a top-up), a retry runs it once more after its cooldown (30 s, or a longer retry_after_seconds; insufficient_credits as soon as the balance covers it), unless its provider may already have done the work. Required for tools that create an external side effect; reuse the same value after a timeout or an approval. A stored failure comes back with details.replayed: true; with retry_after_seconds, retry the same value after that.

TDQS

A4.5/5.0
Behavior5/5

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

Goes well beyond the annotations: it discloses per-company pricing (3.5 credits for yes/not_found, unclear and unreadable free), the ~1 minute latency and what happens on timeout, retry guidance, budget_credits refusal-before-reservation semantics, and what dry_run returns. The annotations' destructiveHint=true is explained by the spend behavior it does describe, 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.

Conciseness4/5

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

Purpose and the answer-state model are front-loaded in the first sentences, and no sentence is pure filler — pricing, retry and dry_run details each carry decision value. It is still a single dense block of semicolon-chained clauses whose length makes the credit rules harder to scan than they need to be.

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

Completeness4/5

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

For a paid, open-world lookup with no output schema, the description supplies what matters: answer states, cost model, latency, timeout behavior and the dry_run escape hatch. The main remaining gap is the 10-vs-20 batch ceiling, which is exactly the kind of detail an agent needs before composing a call.

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

Parameters3/5

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

Question, budget_credits and dry_run all get meaningful elaboration beyond the schema. However the description caps the batch at 'up to 10 companies' while the schema allows maxItems 20, leaving the agent unsure which limit governs, and idempotency_key is not addressed in the description at all. With 80% schema coverage the baseline is 3, and the batch-size conflict keeps it there rather than higher.

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

Purpose5/5

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

States a specific verb and resource — answer one yes/no question per company from its own website — plus the exact scope (one question, up to 10 domains) and the shape of the answer (yes with quoted passage + URL, not_found, unclear). It explicitly demarcates itself from research_company and prospect_picture by the kind of question asked, so an agent can route 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.

Usage Guidelines5/5

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

Names the alternatives and the condition selecting each ('For angles, what's changed, how to approach, or why now ... use research_company ... or prospect_picture'), and gives a positive placement recommendation ('after a broad company search to keep only companies with the need, before paying for people or emails'). Both when-to-use and when-not-to-use are explicit.

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

create_campaignCreate draft campaignA
DestructiveIdempotent
Inspect

Create a draft email campaign with sequence steps, {{first_name}}-style variables, leads, and an optional sending window. Common sending_window.timezone values: Europe/London, Europe/Dublin, Europe/Paris, Europe/Berlin, America/New_York, America/Denver, America/Phoenix, America/Toronto, Australia/Sydney, Asia/Singapore, America/Chicago, Asia/Kolkata, Asia/Dubai. Returns removed counts for opted-out, do-not-contact, invalid, platform-blocked, or capped recipients. Active person, company and area entries are enforced even when new list creation is disabled. List management requires a signed-in person in the console or client window; there is no list-management MCP tool. Drafts never send; launch is a separate confirmed action. dry_run: true returns an advisory estimate as of evaluated_at, reserves nothing, and may differ from a later execution plan. Pass each person’s location from find_leads or enrich in leads[].location (at most 200 characters). Active area rules leave new people with no location out; removed.no_location is included in removed.do_not_contact, not added again to total.

NameRequiredDescriptionDefault
nameYes
leadsYes
stepsYes
dry_runNo
stop_on_replyNo
sending_windowNo
idempotency_keyYesA payment_required refusal means services are stopped for unpaid billing; direct the owner to the billing link in the error. Campaigns stay paused after payment until restarted. Optional for search and enrichment tools: supply one so a retry returns the original result without paying again; if that call failed with provider_unavailable, rate_limited or insufficient_credits (after a top-up), a retry runs it once more after its cooldown (30 s, or a longer retry_after_seconds; insufficient_credits as soon as the balance covers it), unless its provider may already have done the work. Required for tools that create an external side effect; reuse the same value after a timeout or an approval. A stored failure comes back with details.replayed: true; with retry_after_seconds, retry the same value after that.

TDQS

A4.5/5.0
Behavior5/5

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

Annotations cover safety flags, but the description adds genuinely non-derivable behavior: what `removed` counts mean (opted-out, do-not-contact, invalid, platform-blocked, capped), that active person/company/area entries are enforced even when new list creation is disabled, that drafts never send, and that dry_run reserves nothing and may differ from a later plan. This is rich disclosure 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.

Conciseness4/5

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

Front-loaded with purpose and the create-vs-launch distinction, and every sentence carries operational content. It is dense and interleaves several concerns (billing, list management, area-rule edge cases), with some granularity that borders on padding ('removed.no_location is included in removed.do_not_contact'), but nothing is clearly wasted.

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

Completeness4/5

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

For a 7-param, nested, non-read-only tool with no output schema and low schema coverage, the description supplies the return-side essentials (`removed` accounting), the dry-run contract, and enforcement rules. The main gap is that it doesn't document most nested lead/step fields, which the schema carries only via types and constraints.

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

Parameters4/5

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

Schema coverage is only 14%, so the description has to compensate — and it does for the highest-risk params: sending_window.timezone (names common values), dry_run (advisory/reserves-nothing semantics), and leads[].location (source from find_leads/enrich, 200-char cap). It does not add meaning for name, the other lead fields, or step body/subject/wait_days, so it falls short of full compensation.

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

Purpose5/5

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

The first sentence gives a specific verb+resource (create a draft email campaign) plus the shape of the payload (sequence steps, variables, leads, optional sending window). It also explicitly distinguishes itself from the sibling launch_campaign: 'Drafts never send; launch is a separate confirmed action.' An agent can route between create and launch 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.

Usage Guidelines4/5

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

Gives clear context for use and non-use: drafts never send, launch is a separate confirmed action, and there is no list-management MCP tool (so list management must happen elsewhere). It also explains when to reach for dry_run. It stops short of a full when-to-use/when-not matrix against all siblings, but the boundaries are clear.

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

enrichFind a person's verified emailA
Destructive
Inspect

Find a person's verified work email and profile (title, company, linkedin, location). Accepts email, linkedin_url, or name plus company_domain. Fresh results are cached per workspace; repeats are served from cache. Costs credits on hit only. The address it returns already carries its check: contact.email_verdict, in verify_email's status words (null only when the check couldn't finish). Call verify_email only for an address you got elsewhere, or one whose email_verdict is null. want: ["mobile_phone"] also looks for a mobile number: 17 credits when a separate mobile search finds it, 5 when it comes with the email, nothing when none is found. budget_credits is a spend ceiling, never permission to use a dearer source: the same ceiling as max_credits (send one); above it, the call is refused before anything is reserved. dry_run: true returns the plan instead (the most the call can cost, how many sources could answer, and each limit it would trip) with nothing looked up, reserved or charged. route picks how sources are chosen: balanced (the default), cheapest, broadest or fastest. The price is the same whichever you pick, and the answer's layrcake.route says which route was used and whether it came from the request, this key's default or the default.

NameRequiredDescriptionDefault
wantNoWhat to look up. work_email and profile run the email lookup (5 credits on a hit), which returns a mobile number too when its source has one. mobile_phone also runs a separate mobile search when the email lookup found none: 17 credits when that search finds one, 5 when the mobile came with the email, nothing when no mobile is found; a mobile_phone-only request that finds only an email is free and returns nothing. Where this isn't applied for your key yet, every call runs the same email lookup whatever this lists.
routeNoSource preference for this call: balanced (the default), cheapest (the lowest-cost sources), broadest (the sources expected to find the most) or fastest. The price doesn't change with it. Where route choice isn't available to this key yet, only balanced is accepted.
personYes
dry_runNoReturn this call's plan instead of running it, as of evaluated_at: the most it can cost, how many sources could answer, what budget_credits changes, and every limit the real call would trip. Nothing is looked up, reserved or charged, and a later call may differ. Where previews aren't available to this key yet, a request that sets it is refused with the reason.
max_creditsNoSpend ceiling for this call, in credits. If the most the call can cost is above it, the call is refused before anything is reserved or charged.
budget_creditsNoSpend ceiling for this call, in credits. The same ceiling as max_credits, as a number: send one or the other. If the most the call can cost is above it, the call is refused before anything is reserved or charged. It is a ceiling only: it never lets the call use a dearer source. Where spend ceilings aren't available to this key yet, a request that sets it is refused with the reason.
idempotency_keyNoA payment_required refusal means services are stopped for unpaid billing; direct the owner to the billing link in the error. Campaigns stay paused after payment until restarted. Optional for search and enrichment tools: supply one so a retry returns the original result without paying again; if that call failed with provider_unavailable, rate_limited or insufficient_credits (after a top-up), a retry runs it once more after its cooldown (30 s, or a longer retry_after_seconds; insufficient_credits as soon as the balance covers it), unless its provider may already have done the work. Required for tools that create an external side effect; reuse the same value after a timeout or an approval. A stored failure comes back with details.replayed: true; with retry_after_seconds, retry the same value after that.

TDQS

A4.4/5.0
Behavior4/5

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

Adds a lot beyond the annotations: credit costs per outcome, per-workspace caching of repeats, 'refused before anything is reserved' spend ceilings, dry_run returning a plan with nothing charged, and feature-availability caveats ('where this isn't applied for your key yet'). It does not reconcile the destructiveHint=true annotation with what is actually destroyed (nothing but credits), leaving that trait unexplained.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

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

Purpose is front-loaded, but the remainder is a single dense block that jumps between cost, verification, mobile sourcing, budgets, dry_run and routing with no grouping, and includes a garbled reference ('the answer's layrcake.route'). Most sentences earn their place, but the lack of structure costs readability.

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

Completeness4/5

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

With no output schema, the description usefully names the returned profile fields and the key response field contact.email_verdict, tying it to verify_email's vocabulary. What is missing is a fuller sketch of the response object and the credit/balance requirements that gate a real call.

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

Parameters4/5

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

Schema coverage is already 86%, so the baseline is 3; the description still adds real meaning, notably that budget_credits and max_credits are the same ceiling ('send one') and that budget is not permission to use a dearer source, plus the 17/5/0 credit outcomes for want=['mobile_phone']. Route semantics (price invariant across routes) are also spelled out.

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

Purpose5/5

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

Opens with a specific verb and resource ('Find a person's verified work email and profile') plus the fields returned, and immediately distinguishes itself from the sibling verify_email. An agent can tell this apart from enrich_company and find_leads without reading any schema.

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

Usage Guidelines5/5

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

Explicitly routes between siblings: 'Call verify_email only for an address you got elsewhere, or one whose email_verdict is null.' It also gives per-option usage conditions for want (mobile_phone add-on), route, dry_run and budget_credits, including the exclusion that budget_credits never authorizes a dearer source.

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

enrich_companyEnrich a companyA
Destructive
Inspect

Enrich one company domain with independently statused profile, technologies, funding, or relationships datasets; or request an exclusive fast/deep sourced brief. Structured hits cost 13 credits each; briefs cost 10 fast or 40 deep. Empty and unavailable datasets are free.

NameRequiredDescriptionDefault
wantNo
depthNo
company_domainYesCompany website domain or URL, e.g. acme.com or https://www.acme.com/about
idempotency_keyNoA payment_required refusal means services are stopped for unpaid billing; direct the owner to the billing link in the error. Campaigns stay paused after payment until restarted. Optional for search and enrichment tools: supply one so a retry returns the original result without paying again; if that call failed with provider_unavailable, rate_limited or insufficient_credits (after a top-up), a retry runs it once more after its cooldown (30 s, or a longer retry_after_seconds; insufficient_credits as soon as the balance covers it), unless its provider may already have done the work. Required for tools that create an external side effect; reuse the same value after a timeout or an approval. A stored failure comes back with details.replayed: true; with retry_after_seconds, retry the same value after that.

TDQS

A3.7/5.0
Behavior4/5

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

Annotations already declare destructiveHint=true, readOnlyHint=false and idempotentHint=false, so the safety profile is covered; the description adds genuinely new behavioral facts beyond that — per-dataset credit costs (13), fast/deep brief pricing (10/40), and that empty or unavailable datasets are free. It still omits what the response looks like and the credit-exhaustion failure mode, but the cost model is meaningful added context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

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

Two tightly packed sentences with no filler: the capability list comes first, the cost model second. The pricing clause is dense but each element (per-hit, brief, free cases) carries distinct decision-relevant information.

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

Completeness3/5

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

With no output schema, the description should ideally hint at the shape of the returned datasets or the brief, and it does not. For a cost-incurring, non-idempotent call the pricing coverage is good, but the sibling ambiguity and absent return-value framing leave gaps an agent must guess at.

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

Parameters4/5

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

Schema coverage is 50% (company_domain and idempotency_key are documented in-schema; want and depth are bare enums). The description compensates by explaining that 'want' selects among independently statused datasets and that 'depth' (fast/deep) applies specifically to briefs and changes the price, which is semantics the enum alone does not convey.

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

Purpose4/5

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

States a specific verb and resource ('Enrich one company domain') and enumerates the concrete datasets it can return (profile, technologies, funding, relationships) plus the brief alternative, which is far more than a restatement of the title. However, it never distinguishes itself from close siblings like research_company or enrich, so an agent still has to infer which enrichment tool to pick.

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

Usage Guidelines3/5

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

The single-domain scope ('one company domain') is implied as a usage boundary versus batch tools, and the pricing sentence implicitly warns the agent about cost. But there is no explicit when-to-use, when-not-to-use, or named alternative, so selection against research_company/enrich remains unguided.

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

find_companiesFind companiesA
Destructive
Inspect

Discover companies by hiring activity, technologies in use, similarity to one company domain, or a plain-language query (up to 400 characters, translated server-side into those filters and echoed back in result.interpreted). Industry phrases in a plain-language query are not applied; they appear in result.interpreted.dropped.industries so the result can be disclosed and narrowed with supported filters. Hiring, technology and query requests accept provider-taxonomy industries, ISO alpha-2 country_codes and company_headcount. Sent with a query, they win over what the query says; company_headcount merges bound by bound, so a bound you leave out keeps the query's value unless that would invert the range, in which case your range is used alone. result.interpreted.caller_filters lists them with every reading of the query they replaced or dropped. limit defaults to 25, maximum 100. exclude_domains (up to 500) leaves out companies you have already seen, in every mode: they are never returned or charged, and result.left_out.excluded counts those the search came across. A firmographic search fetches further to fill the limit, so sending the domains you already have is how to get the next companies. Returns unique companies with evidence and company_domains, plus jobs_last_30_days and last funding round facts when the source reports them. Technology matches carry match_confidence; only high-confidence companies are returned and billed unless include_low_confidence is true, which adds a separate unbilled low_confidence_companies list. Technologies take a tool's usual name (for example Customer.io or Pendo); an unknown name is refused with close suggestions. A similar_to request also accepts country_codes and company_headcount: each lookalike then comes back with headcount, industry and country, companies that don't fit are dropped and free (counted in result.filtered_out), and each company kept costs 33 credits. Hiring results cost 11 credits each, unfiltered lookalikes 13 and technology results 16; zero results are free. mode: "firmographic" finds companies by industries (LinkedIn's names, as on find_leads) and ISO alpha-2 country_codes, optionally narrowed by locations (cities or regions, matched against each company's headquarters) and company_headcount; 2 credits a company. mode: "local" finds local businesses by categories (for example "dentist") in locations, each a city with its country (for example "Leeds, United Kingdom"); 3 credits a business, with a website. budget_credits is a spend ceiling, never permission to use a dearer source: when the call could cost more, limit is lowered to the largest that fits and result.budget_applied says so. dry_run: true returns the plan instead (the most the call can cost, how many sources could answer, and each limit it would trip) with nothing looked up, reserved or charged. Example: {"hiring":{"titles":["GTM Engineer","Sales Development Representative"],"posted_within_days":30},"country_codes":["US","GB"],"company_headcount":{"min":50,"max":500},"limit":10} route picks how sources are chosen: balanced (the default), cheapest, broadest or fastest. The price is the same whichever you pick, and the answer's layrcake.route says which route was used and whether it came from the request, this key's default or the default.

NameRequiredDescriptionDefault
modeNofirmographic: companies by industries (LinkedIn's names, as on find_leads), country_codes, and optionally locations and company_headcount. local: local businesses by categories (for example "dentist") in locations. events: companies that had something happen (event, within within_days), each with a verbatim quote, its source and date; runs in the background and needs an Idempotency-Key. Leave it out for hiring, technologies, similar_to or query. Where a mode isn't available to this key yet, a request that sets it is refused with the reason.
eventNoOnly with mode events: what happened to the companies, in plain words, for example "opened a new office in London" or "disclosed a data breach".
limitNoMost companies to return: up to 100, default 25. Mode events: up to 25, default 15.
queryNoPlain-language description of the companies; one with no hiring or technology in it also needs a country (country_codes, or in the words).
routeNoSource preference for this call: balanced (the default), cheapest (the lowest-cost sources), broadest (the sources expected to find the most) or fastest. The price doesn't change with it. Where route choice isn't available to this key yet, only balanced is accepted.
hiringNo
dry_runNoReturn this call's plan instead of running it, as of evaluated_at: the most it can cost, how many sources could answer, what budget_credits changes, and every limit the real call would trip. Nothing is looked up, reserved or charged, and a later call may differ. Where previews aren't available to this key yet, a request that sets it is refused with the reason.
audienceNo
keywordsNoOnly with mode firmographic: 1 to 10 phrases, for example "carbon accounting"; for a non-English-speaking country add its own words too. A company matches when its own description, products or specialties mention any of them, in the language they are written in; with keywords, industries may be left out, and an industry that means the same as a keyword asks for it twice. Each company then comes back with its description. Where keywords aren't available to this key yet, a request that sets them is refused with the reason.
locationsNoPlaces, only with mode. firmographic: optional cities or regions inside country_codes, matched against each company's headquarters. local: required, each a city with its country, for example "Leeds, United Kingdom" or "Austin, TX".
categoriesNoOnly with mode local: the kinds of business, for example "dentist" or "commercial cleaning service".
industriesNoLinkedIn industry names, for example "Software Development" or "Online and Mail Order Retail"; other words go in keywords (firmographic).
min_ratingNoOnly with mode local: the lowest public map rating to keep, 1 to 5 with one decimal, for example 4.5. A business with no rating is left out and not charged. Where it isn't available to this key yet, a request that sets it is refused with the reason.
similar_toNoCompany website domain or URL, e.g. acme.com or https://www.acme.com/about
min_reviewsNoOnly with mode local: the fewest public map reviews to keep, for example 20. A business with no review count is left out and not charged. Where it isn't available to this key yet, a request that sets it is refused with the reason.
within_daysNoOnly with mode events: the event happened in the last this many days (1 to 365, default 90). A company whose event has no date is left out.
technologiesNo
country_codesNo
budget_creditsNoSpend ceiling for this call, in credits. If the most the call can cost is above it, limit is lowered to the largest that fits and result.budget_applied says so; the call is refused, before anything is reserved or charged, only when not even one company fits. It is a ceiling only: it never lets the call use a dearer source. Where spend ceilings aren't available to this key yet, a request that sets it is refused with the reason.
exclude_domainsNoCompany domains to leave out, up to 500: companies you've already seen. They are never returned or charged, and result.left_out.excluded counts those the search came across. In mode firmographic the search fetches further to fill the limit.
idempotency_keyNoA payment_required refusal means services are stopped for unpaid billing; direct the owner to the billing link in the error. Campaigns stay paused after payment until restarted. Optional for search and enrichment tools: supply one so a retry returns the original result without paying again; if that call failed with provider_unavailable, rate_limited or insufficient_credits (after a top-up), a retry runs it once more after its cooldown (30 s, or a longer retry_after_seconds; insufficient_credits as soon as the balance covers it), unless its provider may already have done the work. Required for tools that create an external side effect; reuse the same value after a timeout or an approval. A stored failure comes back with details.replayed: true; with retry_after_seconds, retry the same value after that.
include_handledNoOnly inside an agent run: true includes companies this agent already checked (yes or not_found) in the last 90 days, which the run's searches otherwise leave out. Outside an agent run it changes nothing.
exclude_keywordsNoOnly with mode firmographic: up to 10 phrases, for example "recruitment agency" or "consultancy". Companies whose own description mentions any of them are left out. Each company then comes back with its description. Where exclude_keywords aren't available to this key yet, a request that sets them is refused with the reason.
company_headcountNoEmployee-count range. With no min or max, companies with fewer than 10 employees are left out. Any bound replaces that default: a max without a min searches from 1 employee.
include_low_confidenceNo

TDQS

A4.4/5.0
Behavior5/5

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

Although annotations declare readOnlyHint=false, destructiveHint=true, and openWorldHint=true, the description adds substantial behavioral context beyond them: per-company credit costs, zero-result forgiveness, exclude_domains being never charged, separately unbilled low-confidence results, budget-driven limit reduction, and dry_run making no lookup, reservation, or charge. That is exactly the kind of cost and side-effect disclosure an agent needs for a billed discovery tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

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

The purpose statement is front-loaded and most sentences carry useful information, but the description is an enormous single paragraph with dense nested clauses and even a garbled phrase ('layrcake.route'). For a 25-parameter tool some length is justified, but sections or bullets would make it far easier to parse.

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

Completeness4/5

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

With no output schema and 25 parameters, the description does well to explain the returned shape: interpreted fields, caller_filters, left_out.excluded, filtered_out, match_confidence, low_confidence_companies, and the core company evidence fields. It is not fully complete because it omits the events mode from the main prose and does not cover some parameters and result details, but the overall coverage is strong for a tool this complex.

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

Parameters4/5

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

Schema coverage is already 80%, so the baseline is 3, but the description adds meaningful semantics: query is capped at 400 characters, company_headcount merges bound-by-bound, budget_credits is a ceiling and never a source upgrade, and exclude_domains is intended for previously seen companies. It leaves a few parameters such as audience, include_handled, and include_low_confidence largely to the schema, and there is a minor discrepancy around exclude_domains' 500-item claim versus the schema's 1000 maxItems.

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

Purpose5/5

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

The opening sentence names a specific verb and resource and enumerates the distinct discovery modes: hiring, technologies, similar_to, and plain-language query. It distinguishes the firmographic mode from find_leads by saying industries use LinkedIn names 'as on find_leads,' so an agent can route between the two tools without opening both schemas.

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

Usage Guidelines4/5

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

The description clearly states which modes accept which filters, explains credit costs, and tells the agent that exclude_domains is how to fetch the next batch. It also explains how budget_credits and dry_run behave. It stops short of explicitly saying when not to use this tool versus siblings like check_companies or enrich_company, leaving some routing inference to the agent.

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

find_intentFind buying intentA
Destructive
Inspect

Screen up to 25 company domains for dated buying signals: hiring (live job posts with evidence URLs), funding, news, job_change. For angles, what's changed, how to approach, or why now on one company or person, use research_company (a company) or prospect_picture (a person, their company, or both) instead. Leave signals out unless a family must be checked on every company: by default only hiring is checked, a company that is not hiring costs nothing, and a hiring company's latest funding round comes with it (the others list funding under skipped_signals). A company with a current hiring signal costs 11 credits. Each paid check you ask for explicitly (funding on a company that is not hiring, news, job_change, technology) costs 13 credits whatever it finds; hiring checks that find nothing, and failed checks, are free; result.domain_status[].charge shows what each company cost. Recency: signals observed inside since / within_days (default 180 days) are current; older ones return under result.historical as context. Each news signal carries news_type, the kind of news it is: funding | product | partnership | customers | expansion | leadership | layoffs | acquisition | challenges | recognition | other. roles filters hiring by job title (literal match). technology is DEPRECATED (a present-day vendor detection with no adoption date, not a buying signal; use find_companies technologies). audience is an optional goal: what you sell and to whom. It never changes charges. With a goal, ranking.by says goal when signals were judged for it, otherwise recency (today’s order); why_now requires a date within 60 days, and why_now_basis says judged or date. Unavailable or unsure judgments use the date rule. budget_credits is a spend ceiling, never permission to use a dearer source: above it, the call is refused before anything is reserved, and no company you sent is dropped to fit. dry_run: true returns the plan instead (the most the call can cost, how many sources could answer, and each limit it would trip) with nothing looked up, reserved or charged. Example: {"company_domains":["acme.com","example.io"]}

NameRequiredDescriptionDefault
rolesNoHiring role filter, up to 25 job titles or phrases: a hiring post counts only when it is one of these roles. Put a role in double quotes to match it word for word. Applies to hiring only; job_change events carry no structured role field.
sinceNo
dry_runNoReturn this call's plan instead of running it, as of evaluated_at: the most it can cost, how many sources could answer, what budget_credits changes, and every limit the real call would trip. Nothing is looked up, reserved or charged, and a later call may differ. Where previews aren't available to this key yet, a request that sets it is refused with the reason.
signalsNoSignal families to check. hiring = live job posts with evidence URLs; funding, news, job_change = dated events. Omit it to check hiring first: only hiring is checked, and a hiring company's latest funding round comes with it; list funding explicitly to check every company (a paid check). DEPRECATED: technology — a present-day vendor detection with no adoption date, not a buying signal; use find_companies.technologies instead. Still accepted in v1.
audienceNoOptional goal: what you sell and to whom. Always accepted. Until goal ordering is available, signals keep today’s order with ranking.by recency and date-based why_now flags; no change to charges.
within_daysNo
budget_creditsNoSpend ceiling for this call, in credits. If the most the call can cost is above it, the call is refused before anything is reserved or charged. No company you sent is dropped to fit. It is a ceiling only: it never lets the call use a dearer source. Where spend ceilings aren't available to this key yet, a request that sets it is refused with the reason.
company_domainsYes
idempotency_keyNoA payment_required refusal means services are stopped for unpaid billing; direct the owner to the billing link in the error. Campaigns stay paused after payment until restarted. Optional for search and enrichment tools: supply one so a retry returns the original result without paying again; if that call failed with provider_unavailable, rate_limited or insufficient_credits (after a top-up), a retry runs it once more after its cooldown (30 s, or a longer retry_after_seconds; insufficient_credits as soon as the balance covers it), unless its provider may already have done the work. Required for tools that create an external side effect; reuse the same value after a timeout or an approval. A stored failure comes back with details.replayed: true; with retry_after_seconds, retry the same value after that.

TDQS

A4.7/5.0
Behavior5/5

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

With annotations already flagging destructiveHint=true, the description goes far beyond them: it prices each path (11 credits for a hiring company, 13 per explicit paid check), states which checks are free (hiring misses, failed checks), explains budget_credits refusal-before-reservation semantics, dry_run's no-charge plan, and recency/historical split. This is the kind of cost-and-side-effect disclosure the destructiveHint annotation only hints at.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

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

Front-loaded and every sentence is substantive, but it is delivered as one unbroken ~350-word block interleaving pricing, deprecation, recency, ranking, and refusal rules. There is no structural separation (no lines for cost, defaults, or return fields), so scanning for a specific rule is hard despite low redundancy.

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

Completeness5/5

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

There is no output schema, so the description carries the return burden and does: result.domain_status[].charge, result.historical, skipped_signals, news_type values, ranking.by, and why_now_basis are all explained. For a 9-parameter, credit-spending, open-world tool, an agent has everything needed to call it safely.

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

Parameters4/5

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

Schema coverage is 67%, and the description fills many gaps: signals defaults and the DEPRECATED technology note, roles as literal job-title match, audience as a charge-neutral goal, and how ranking.by / why_now_basis behave with a goal. It does not mention idempotency_key at all, and its 'up to 25 company domains' conflicts with the schema's maxItems of 50, a count an agent could rely on incorrectly.

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

Purpose5/5

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

The opening sentence states a concrete verb and resource — 'Screen up to 25 company domains for dated buying signals' — and enumerates the signal families (hiring, funding, news, job_change). It also names the two siblings it is not (research_company for a company angle, prospect_picture for a person), so an agent can route without opening any schema.

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

Usage Guidelines5/5

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

Explicit when-to-use and when-not-to-use: 'For angles, what's changed, how to approach, or why now... use research_company... or prospect_picture instead.' It also gives a default-behavior rule ('Leave signals out unless a family must be checked on every company') that tells the agent which invocation is the cheap/correct one.

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

find_leadsFind leadsA
Destructive
Inspect

Search 200M+ B2B contacts by structured filters (titles, locations, industries, company_headcount, company_domains). At least one of titles, industries, locations, or company_domains is required. company_domains accepts up to 100 domains or URLs and restricts results to people at those companies. Industry values follow LinkedIn's taxonomy (for example, 'Hospitals and Health Care'). Returned leads have work_email null. If title_filter.withheld is above 0, the sources found people whose titles did not match; widen titles to see them. Costs 0.25 credits per lead returned, with a 3-credit minimum when any lead is returned; zero results are free. To reach people at a kind of company that titles and industries can't pin down, find the companies first with find_companies, then call find_leads with their company_domains. budget_credits is a spend ceiling, never permission to use a dearer source: when the call could cost more, limit is lowered to the largest that fits and result.budget_applied says so. dry_run: true returns the plan instead (the most the call can cost, how many sources could answer, and each limit it would trip) with nothing looked up, reserved or charged. Example: {"audience":"Heads of Sales and VPs of Sales at US software companies with 50 to 500 employees","titles":["Head of Sales","VP Sales"],"industries":["Software Development"],"locations":["United States"],"company_headcount":{"min":50,"max":500},"limit":25} route picks how sources are chosen: balanced (the default), cheapest, broadest or fastest. The price is the same whichever you pick, and the answer's layrcake.route says which route was used and whether it came from the request, this key's default or the default.

NameRequiredDescriptionDefault
limitNo
routeNoSource preference for this call: balanced (the default), cheapest (the lowest-cost sources), broadest (the sources expected to find the most) or fastest. The price doesn't change with it. Where route choice isn't available to this key yet, only balanced is accepted.
titlesNo
dry_runNoReturn this call's plan instead of running it, as of evaluated_at: the most it can cost, how many sources could answer, what budget_credits changes, and every limit the real call would trip. Nothing is looked up, reserved or charged, and a later call may differ. Where previews aren't available to this key yet, a request that sets it is refused with the reason.
premiumNoConsent, for this call only, to a dearer source when the standard sources come back short, as long as the whole call, the premium step included, stays within budget_credits (which it requires). The premium step is charged separately and reported in result.premium_step. Without it, budget_credits is only a ceiling. Where premium offers aren't available to this key yet, a request that sets it is refused with the reason.
audienceYes
locationsNo
industriesNoLinkedIn industry names, for example "Hospitals and Health Care" or "Software Development".
offer_tokenNoAccept a previous answer's offer: send the same call again, unchanged, with its offer.offer_token. Only the premium step runs, as its own charge at the offer's price, up to its max_credits; the token works once, until expires_at, and only when max_credits is within this key's premium allowance. Where premium offers aren't available to this key yet, a request that sets it is refused with the reason.
budget_creditsNoSpend ceiling for this call, in credits. If the most the call can cost is above it, limit is lowered to the largest that fits and result.budget_applied says so; the call is refused, before anything is reserved or charged, only when not even one lead fits. It is a ceiling only: it never lets the call use a dearer source. Where spend ceilings aren't available to this key yet, a request that sets it is refused with the reason.
company_domainsNo
idempotency_keyNoA payment_required refusal means services are stopped for unpaid billing; direct the owner to the billing link in the error. Campaigns stay paused after payment until restarted. Optional for search and enrichment tools: supply one so a retry returns the original result without paying again; if that call failed with provider_unavailable, rate_limited or insufficient_credits (after a top-up), a retry runs it once more after its cooldown (30 s, or a longer retry_after_seconds; insufficient_credits as soon as the balance covers it), unless its provider may already have done the work. Required for tools that create an external side effect; reuse the same value after a timeout or an approval. A stored failure comes back with details.replayed: true; with retry_after_seconds, retry the same value after that.
include_handledNoOnly inside an agent run: true includes people this agent already put in a campaign in the last 90 days, which the run's searches otherwise leave out. Outside an agent run it changes nothing.
company_headcountNo

TDQS

A4.4/5.0
Behavior4/5

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

Adds substantial context beyond the annotations: exact pricing (0.25 credits/lead, 3-credit minimum, zero results free), that leads come back with work_email null, that title_filter.withheld signals non-matching titles, and that dry_run reserves and charges nothing. With destructive/openWorld already declared by annotations, the money-spend disclosure is the missing piece and it is covered well. It does not explain the destructiveHint implication beyond cost, which keeps it off 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.

Conciseness3/5

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

The first third is front-loaded and efficient, but the tail becomes a run-on that repeats what the schema already documents for route and budget_credits ('The price is the same whichever you pick...') and ends with a garbled reference ('the answer's layrcake.route'). Several sentences could be trimmed without losing decision-relevant information.

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

Completeness4/5

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

For a 14-parameter, nested-object, cost-bearing search tool with no output schema, the description covers the essentials an agent needs: the required-filter rule, pricing and minimums, budget lowering behavior, dry-run planning, source routing, and a worked example. The premium/offer_token flow and the return payload shape are left to the schema, which is acceptable but leaves a small gap.

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

Parameters4/5

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

Adds real meaning over the 57%-covered schema: which filters satisfy the required-filter constraint, the LinkedIn taxonomy for industries, and what company_domains does to results ('restricts results to people at those companies'), plus budget_credits and route behavior tied to result fields. One inconsistency: it says company_domains accepts 'up to 100 domains' while the schema sets maxItems to 200, and premium/offer_token/idempotency_key are left entirely to the schema.

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

Purpose5/5

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

Opens with a specific verb and resource plus scale: 'Search 200M+ B2B contacts by structured filters', then enumerates the filter families. It explicitly distinguishes itself from the sibling find_companies by stating when to use that tool first and then come back with company_domains.

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

Usage Guidelines5/5

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

Gives a hard prerequisite ('At least one of titles, industries, locations, or company_domains is required'), a routing rule to the sibling tool for a specific intent ('a kind of company that titles and industries can't pin down'), and guidance on when to use dry_run versus a real call. The budget_credits paragraph also clarifies the ceiling-vs-permission distinction that would otherwise cause misuse.

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

find_postsFind social postsA
Destructive
Inspect

Find public social posts by keyword (people discussing a topic), by a known author's profile URL or handle, or by LinkedIn company domain. For angles, what's changed, how to approach, or why now on one company or person, use research_company (a company) or prospect_picture (a person, their company, or both) instead. intent: pain | question keeps only posts one audience-specific model pass classified as buyer pain or a buying question (each returned post carries its label and reason; unclassifiable candidates are withheld, never returned unlabelled) and adds a separate classification component at llm token pricing, shown in result.cost_breakdown. Supports LinkedIn, X, Reddit and Facebook, and YouTube and TikTok by keyword, when enabled. include: ["author_details"] adds each author's type (person or company page) and whether the post is a repost. A keyword query is matched word for word (literal-v1): a post is kept only when it contains every quoted phrase and at least 70% of the other words exactly as written, rounded up, so 2 or 3 words must all appear. Send 2–3 core words the posts would use, not a sentence, and let intent do the judging. Returns per-platform status, with how many posts came back and how many the word match dropped, and bills only kept posts. Keyword search costs 0.5 credit per returned post and a miss is free; author/company scope adds a 1-credit base even when no post is returned. On Reddit and Facebook a returned post costs 2 credits. For a person known only by name, call enrich with person { full_name, company_domain } first, then pass the linkedin_url it returns as author { type: "profile_url", profile_url }; a name-only author is refused before any charge, with that call in error.details.next. intent also takes hiring_for_it (the author's own company hiring for the work your product does) and competitor_complaint (a user complaining about a tool like yours; it finds most, not all, complaint posts, so an empty answer doesn't mean nobody is complaining). audience is an optional goal: what you sell and to whom. It never changes charges. With a goal, posts are ordered by how worth a reply they are (ranking.by goal; recency when nothing was judged) and each carries why_now with why_now_basis judged or date. leads takes contacts as find_leads or enrich return them and gives each one's best recent reason to reach out (their own post, a comment, a reaction or their company's post) with the evidence, and the person ready for enrich: 3 credits per lead with a signal, a lead with none is free, budget_credits caps it. Up to 10 leads answer inline; up to 1,000 run as an operation: send idempotency_key, then poll get_operation, which returns the leads 25 at a time with next_cursor. engagers_of takes up to 5 post URLs and returns the people who reacted, commented, replied or reposted, each with what they did and ready for enrich: 0.5 credit per person (2 on Reddit), a post with nobody is free, per_post up to 50. author_filter (headline or bio keywords) keeps only matching people, adds 0.4 credit per person read, and skips Reddit and Facebook, whose people show no headline. Choose posts your buyers engage with. A company's own announcements can draw mostly its own staff, so check who engaged, or pass author_filter with title words (for example head of sales, VP sales) to keep only the roles you want. Each post reports read (people read) and, on LinkedIn, engaged_total; more_available true means the sample missed people. To read everyone, send the same posts with read_all: true, budget_credits and idempotency_key: it runs in the background (about 2 minutes per 500 people) at the same price per person kept, plus 0.4 credit per person read with author_filter, and never charges above budget_credits. When the counts are known the sample's full_read quotes that budget and the time: tell the user before running it. Then poll get_operation, which returns the people 25 at a time with next_cursor. If the budget runs short, each post says how many people were not read (not_read) or withheld (withheld) and limited_by budget: raise budget_credits to get them. With author_filter, a title check also keeps people whose headline clearly means one of your terms in other words (a CCO for chief revenue officer): each is marked matched_by judged, and filter_basis says judged when it added anyone. It only adds people, and a full read checks at most 2,500 of them.

NameRequiredDescriptionDefault
leadsNoLeads mode: people from find_leads or enrich. Returns each one's best recent reason to reach out (own post, comment, reaction or company post). LinkedIn only: send no query, platforms or intent.
limitNo
queryNo
authorNo
intentNo
includeNo
audienceNo
per_postNoEngagers mode: up to this many people from each source (reactions, comments, replies) of each post.
read_allNoEngagers mode: read everyone who engaged, not a sample, in the background (about 2 minutes per 500 people). Needs budget_credits and idempotency_key. Returns an operation: poll get_operation, which returns the people 25 at a time with next_cursor.
platformsNo
engagers_ofNoEngagers mode: up to 5 post URLs (LinkedIn, X, Reddit, Facebook). Returns the people who reacted, commented, replied or reposted. Send no query, platforms, intent or audience.
within_daysNo
author_filterNoEngagers mode: keep only people whose headline contains one of these words, e.g. ["head of sales", "VP sales"]. Each person read costs a small scan fee; Reddit and Facebook are skipped (no headlines).
budget_creditsNoLeads mode, or engagers_of with read_all: a spend ceiling in credits. Leads beyond it come back not_processed; read_all reads people up to it.
company_domainNoCompany website domain or URL, e.g. acme.com or https://www.acme.com/about
idempotency_keyNoA payment_required refusal means services are stopped for unpaid billing; direct the owner to the billing link in the error. Campaigns stay paused after payment until restarted. Optional for search and enrichment tools: supply one so a retry returns the original result without paying again; if that call failed with provider_unavailable, rate_limited or insufficient_credits (after a top-up), a retry runs it once more after its cooldown (30 s, or a longer retry_after_seconds; insufficient_credits as soon as the balance covers it), unless its provider may already have done the work. Required for tools that create an external side effect; reuse the same value after a timeout or an approval. A stored failure comes back with details.replayed: true; with retry_after_seconds, retry the same value after that.

TDQS

A4.7/5.0
Behavior5/5

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

Annotations mark the tool as not read-only, open-world and destructive, and the description adds extensive behavioral detail beyond that: credit pricing, budget ceilings, billing refusals, background operations, withheld/not_read counts, and retry/idempotency behavior. No statement 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.

Conciseness3/5

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

The first two sentences front-load purpose and alternatives, but the rest is a very dense single paragraph mixing many modes, pricing rules and operational details, with repeated get_operation guidance. The length is partly justified by the tool's complexity, but the structure makes it harder to scan than necessary.

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

Completeness5/5

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

With no output schema and a 16-parameter surface, the description carries a large burden and largely meets it: it explains return shapes such as per-platform status, cost_breakdown, why_now, matched_by and read counts, plus background operation behavior. An agent has enough context to invoke the tool correctly across its main modes.

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

Parameters4/5

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

Schema description coverage is 50% across 16 parameters, and the description compensates substantially by explaining complex parameters such as intent, include, leads, engagers_of, read_all, budget_credits and author_filter. It still leaves some schema parameters like limit, platforms and within_days mostly to the schema, so it is strong but not complete.

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

Purpose5/5

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

The opening sentence states a specific verb and resource: 'Find public social posts by keyword ..., by a known author's profile URL or handle, or by LinkedIn company domain.' It also distinguishes the tool from research_company and prospect_picture, so an agent can identify both what it does and what it is not for.

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

Usage Guidelines5/5

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

It explicitly names alternatives and when to use them: 'For angles, what's changed, how to approach, or why now ... use research_company ... or prospect_picture ... instead.' It also gives mode-specific routing such as calling enrich first for name-only authors and using find_leads or enrich results as input to leads mode.

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

get_meWho am IA
Read-onlyIdempotent
Inspect

Returns this key's identity and permissions: scopes, monthly spend cap and remaining allowance, today's send and reply capacity, per-action limits, and workspace suspension state. Every external action (buying mailboxes, launching, adding leads to a live campaign, replying) needs a person's approval. Free.

NameRequiredDescriptionDefault

No parameters

TDQS

A4.3/5.0
Behavior4/5

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

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, so the safety profile is covered. The description adds valuable behavioral context beyond the annotations: the tool is free, and it discloses that external actions require a person's approval. This helps the agent understand the operational implications of the returned permissions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

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

Two sentences, front-loaded with the core purpose, followed by a compact list of returned fields. The closing 'Free.' is a single-word sentence that earns its place by conveying cost behavior without elaboration. No wasted words.

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

Completeness5/5

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

For a zero-parameter, read-only identity tool, the description fully covers what an agent needs to know: what data is returned and the approval context for external actions. No output schema exists, but the enumerated return fields provide sufficient completeness for correct invocation and interpretation.

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

Parameters4/5

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

The tool has zero parameters and schema description coverage is 100%, so there is no parameter burden. The baseline for zero-parameter tools is 4, and the description adds no unnecessary parameter-related noise.

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

Purpose5/5

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

The description opens with a specific verb and resource: 'Returns this key's identity and permissions.' It then enumerates the exact fields returned (scopes, spend cap, remaining allowance, send/reply capacity, per-action limits, suspension state), which clearly differentiates it from siblings like get_usage or get_operation that focus on operation or usage details.

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

Usage Guidelines3/5

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

The description implies this tool is useful for checking permissions and limits before taking external actions, especially with the note that 'Every external action... needs a person's approval.' However, it never explicitly states when to use this tool versus alternatives or mentions any exclusions, leaving usage guidance to inference.

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

get_operationCheck an operationA
Read-onlyIdempotent
Inspect

Returns the current state of provisioning, campaign creation, launch, company research, or prospect picture work by operation_id; completed research and pictures carry their result, and pictures list each component's progress in items.

NameRequiredDescriptionDefault
cursorNoFor operations whose results come in pages: the next_cursor from the previous page.
operation_idYes

TDQS

A3.9/5.0
Behavior4/5

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

Annotations already establish this as a read-only, idempotent, non-destructive, closed-world call, so the safety profile is covered. The description adds real behavioral value beyond that: completed research and pictures carry their result, and pictures expose per-component progress via items, which tells the agent what a terminal vs in-progress response looks like.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

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

A single front-loaded sentence covers purpose, scope, and return behavior with no filler. It is dense, and the trailing clause about pictures/items could be split for readability, but nothing is redundant.

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

Completeness4/5

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

For a read-only polling tool with no output schema, the description conveys enough: which operation families are valid, that results appear when complete, and how paginated picture results are structured. The only gap is how an agent acquires the operation_id, a minor omission given the schema's required-field marker.

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

Parameters3/5

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

Schema coverage is 50%: cursor is fully documented in the schema, while operation_id has only format/pattern constraints and no description. The description references operation_id implicitly and clarifies that results may be paginated ('items', per-component progress), but does not define what an operation_id represents or where the agent gets one, so it only partially compensates.

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

Purpose5/5

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

States a specific verb (returns current state) and resource (operation), and enumerates the exact operation categories it covers: provisioning, campaign creation, launch, company research, and prospect picture. No sibling tool provides operation status, so an agent can route to it without ambiguity.

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

Usage Guidelines3/5

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

The description implies usage by naming the operation types it serves, which nudges the agent toward polling after create/launch/research calls. However, it never states when to call it versus alternatives, nor when/whether to poll repeatedly or how to obtain the operation_id in the first place.

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

get_repliesList repliesA
Read-onlyIdempotent
Inspect

Read campaign replies (free): newest first, optionally filtered by campaign_id and/or since (ISO timestamp). classification is out_of_office for an automatic reply and other for every other reply; it does not judge interest, so read the reply with get_reply and record what it meant with set_lead_status. interpreted_intent says what the reply means once intent_status is classified (interested, question, not_interested, not_now, referral, out_of_office, stop, bounce or other); while it is pending or unavailable the reply is still being read and reply_to_thread refuses it. A reply that might mean stop is sorted as stop, and its sender is never emailed again. classification stays the provider's.

NameRequiredDescriptionDefault
limitNo
sinceNo
campaign_idNo
idempotency_keyNoA payment_required refusal means services are stopped for unpaid billing; direct the owner to the billing link in the error. Campaigns stay paused after payment until restarted. Optional for search and enrichment tools: supply one so a retry returns the original result without paying again; if that call failed with provider_unavailable, rate_limited or insufficient_credits (after a top-up), a retry runs it once more after its cooldown (30 s, or a longer retry_after_seconds; insufficient_credits as soon as the balance covers it), unless its provider may already have done the work. Required for tools that create an external side effect; reuse the same value after a timeout or an approval. A stored failure comes back with details.replayed: true; with retry_after_seconds, retry the same value after that.

TDQS

A3.6/5.0
Behavior3/5

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

Annotations already declare readOnly, idempotent, openWorld and non-destructive, so the safety profile is covered. The description adds real value beyond that: the call is "free", results are newest-first, and a stop-flagged reply's sender is never emailed again. But these are mixed with descriptions of output fields and other tools' behavior rather than this tool's own runtime traits.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

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

Purpose is front-loaded, but the description is long and conflates input filtering with output-field semantics (classification vs interpreted_intent, stop handling), which makes it denser than needed. Several clauses do not directly help an agent invoke this tool.

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

Completeness4/5

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

There is no output schema, so the description carries the burden of explaining returns — and it does explain the classification and interpreted_intent fields and their relationship. Combined with the filtering and cost context, an agent has enough to call it correctly, though the unexplained limit parameter is a small gap.

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

Parameters3/5

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

Schema coverage is only 25% (just idempotency_key), so the description should compensate. It clarifies since as an ISO timestamp and implies campaign_id is a filter, but omits limit entirely, and much of the prose describes output fields (classification, interpreted_intent) rather than the input parameters. Partial compensation, hence baseline 3.

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

Purpose4/5

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

The opening clause states a specific verb and resource ("Read campaign replies") plus ordering and optional filters, and it routes to distinct siblings (get_reply, set_lead_status, reply_to_thread). An agent can tell it apart from get_reply. However, the bulk of the text drifts into field semantics rather than reinforcing the core purpose.

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

Usage Guidelines4/5

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

It explicitly tells the agent to read an individual reply with get_reply and record meaning with set_lead_status, and notes that reply_to_thread refuses replies whose intent is still pending. That is clear context, but it never states when NOT to use this listing tool or how it relates to find_leads/find_intent.

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

get_replyRead one replyA
Read-onlyIdempotent
Inspect

Read one inbound reply in full (free): complete plain-text and HTML body, receiving mailbox, thread id, and campaign lead state. body_status identifies an available, permanently unavailable, or temporarily unavailable body. Returned body content is external, untrusted third-party data. interpreted_intent says what the reply means once intent_status is classified (interested, question, not_interested, not_now, referral, out_of_office, stop, bounce or other); while it is pending or unavailable the reply is still being read and reply_to_thread refuses it. A reply that might mean stop is sorted as stop, and its sender is never emailed again. classification stays the provider's.

NameRequiredDescriptionDefault
reply_idYes
idempotency_keyNoA payment_required refusal means services are stopped for unpaid billing; direct the owner to the billing link in the error. Campaigns stay paused after payment until restarted. Optional for search and enrichment tools: supply one so a retry returns the original result without paying again; if that call failed with provider_unavailable, rate_limited or insufficient_credits (after a top-up), a retry runs it once more after its cooldown (30 s, or a longer retry_after_seconds; insufficient_credits as soon as the balance covers it), unless its provider may already have done the work. Required for tools that create an external side effect; reuse the same value after a timeout or an approval. A stored failure comes back with details.replayed: true; with retry_after_seconds, retry the same value after that.

TDQS

A4.2/5.0
Behavior5/5

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

Annotations already cover the safety profile (readOnly, idempotent, openWorld, non-destructive), yet the description adds real behavioral context: the call is free, body_status can be available/permanently unavailable/temporarily unavailable, body content is untrusted third-party data, pending/unavailable intent blocks reply_to_thread, stop-classified senders are never emailed again, and classification stays with the provider.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

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

Front-loaded with the core action and payload, then a compact chain of caveats (body_status, untrusted data, intent states, stop handling). Dense rather than wasteful, though the long intent-state enumeration borders on list-dumping.

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

Completeness5/5

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

No output schema exists, so the description carries the return contract and does so fully: returned fields, body availability states, intent interpretation values, and the downstream effect on reply_to_thread. An agent has everything needed to call and interpret this tool.

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

Parameters3/5

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

With 50% schema coverage, the description explains neither reply_id nor idempotency_key. reply_id is trivially inferable as the identifier of the reply being fetched, and idempotency_key is heavily documented in the schema itself, so no added meaning is needed, but the description contributes nothing here.

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

Purpose5/5

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

States a precise verb+resource+scope: read ONE inbound reply in full, and enumerates what comes back (plain-text and HTML body, receiving mailbox, thread id, lead state). The singular, full-read framing cleanly separates it from the sibling get_replies.

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

Usage Guidelines3/5

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

Implied usage only: the 'free' cost cue and 'read in full' scope signal when to reach for it, and it notes reply_to_thread refuses replies whose intent is still pending, but it never states when to prefer get_reply over get_replies or any other alternative.

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

get_requestCheck a requestA
Read-onlyIdempotent
Inspect

Status and final billing for a previous Layrcake request by request_id — including requests whose stream was interrupted.

NameRequiredDescriptionDefault
request_idYes

TDQS

A3.8/5.0
Behavior3/5

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

Annotations already provide readOnlyHint=true, idempotentHint=true, destructiveHint=false, covering the safety profile. Description adds context that interrupted streams still have status/billing, which goes beyond annotations. It doesn't disclose not-found behavior or response shape, but with annotations present, 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.

Conciseness5/5

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

One sentence, front-loaded with 'Status and final billing', all content is useful and no fluff. The edge case about interrupted streams earns its place.

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

Completeness4/5

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

For a simple read-only lookup with one parameter, the description covers purpose, input semantics, and mentions interrupted streams. No output schema exists, but it states what's returned (status and billing). It could provide more context on the domain meaning of 'request', but overall adequate.

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

Parameters3/5

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

Schema description coverage is 0%, so the description must compensate. It connects request_id to 'previous Layrcake request', adding meaning beyond the schema's format/pattern. It doesn't explain how to obtain the ID or what 'request' means exactly, so 3 is fair.

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

Purpose5/5

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

Description states a specific verb ('Status and final billing') and resource ('previous Layrcake request by request_id'), and distinguishes from siblings like get_operation and get_usage by focusing on final billing and interrupted streams. It clearly answers 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.

Usage Guidelines3/5

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

Usage is implied: use when you have a request_id and want status/billing. No explicit alternatives or exclusions; it doesn't mention when to prefer get_operation or get_usage. The 'including requests whose stream was interrupted' hints at a use case but doesn't name sibling tools.

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

get_usageCredit balance and usageA
Read-onlyIdempotent
Inspect

Returns the Layrcake credit balance, reserved holds, available credits, and per-verb usage for the last 30 days.

NameRequiredDescriptionDefault

No parameters

TDQS

A4.3/5.0
Behavior3/5

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

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, covering the safety profile. The description adds useful context about the 30-day lookback and returned breakdowns, but does not discuss rate limits, authentication, or other behavioral traits. This aligns with the calibration baseline for annotation-covered read tools.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

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

A single front-loaded sentence contains every meaningful detail: credit balance, reserved holds, available credits, per-verb usage, and the 30-day window. There is no repetition of the title or the parameter schema, and no filler.

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

Completeness5/5

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

For a zero-parameter, read-only tool with no output schema, the description fully enumerates what will be returned. There are no required inputs, side effects, or alternatives that need explanation, so nothing essential is missing.

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

Parameters4/5

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

The tool has zero parameters, so there is nothing for the schema to document. The description adds value by enumerating the kinds of results the agent should expect, which is the only semantic dimension available here.

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

Purpose5/5

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

The description leads with the verb "Returns" and names the exact resources: credit balance, reserved holds, available credits, and per-verb usage. This clearly distinguishes it from all listed sibling tools, none of which target credit or usage data.

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

Usage Guidelines4/5

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

The description makes the tool's context clear: call it when you need credit balance, holds, available credits, or 30-day per-verb usage. It does not explicitly name alternatives or exclusions, but no sibling tool competes for this purpose, so the usage context is sufficient.

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

launch_campaignLaunch campaignA
Destructive
Inspect

Launch a draft campaign so real emails begin sending. An unconfirmed request returns a preview, confirmation_token, approval_url, and removed counts from the launch-time recipient recheck. After a person approves, Layrcake runs it itself when the result's approval block says execution: server (a launch starts at its first-send time); otherwise, repeat the call with that token and a stable idempotency_key. Repeating is always safe and never runs it twice. Calling again without a token while the same request is still waiting for a decision returns that approval and sends no second email; after it was declined, expired or cancelled, calling again without a token asks again with a new confirmation_token. Requires active sending capacity and campaign:launch. Suppression and active do-not-contact entries are rechecked and provider removals fail closed before activation. dry_run: true returns an advisory estimate as of evaluated_at, reserves nothing, and may differ from a later execution plan.

NameRequiredDescriptionDefault
dry_runNo
supersedesNoThe confirmation_token of the approval this request replaces. Needed only when that approval was already approved and hasn't started yet; one still waiting for a decision is replaced automatically. Only where Layrcake runs approved actions itself (the result's approval block says execution: server); anywhere else it is refused. A dry run doesn't check it, so it refuses it: send it on the call itself.
campaign_idYes
idempotency_keyNoA payment_required refusal means services are stopped for unpaid billing; direct the owner to the billing link in the error. Campaigns stay paused after payment until restarted. Optional for search and enrichment tools: supply one so a retry returns the original result without paying again; if that call failed with provider_unavailable, rate_limited or insufficient_credits (after a top-up), a retry runs it once more after its cooldown (30 s, or a longer retry_after_seconds; insufficient_credits as soon as the balance covers it), unless its provider may already have done the work. Required for tools that create an external side effect; reuse the same value after a timeout or an approval. A stored failure comes back with details.replayed: true; with retry_after_seconds, retry the same value after that.
daily_send_limitNo
confirmation_tokenNo
first_send_not_beforeNoThe earliest the first emails may go out (ISO 8601). They start at the first sending-window opening at least 60 minutes after a person approves, and not before this time. It can't be later than the approval's lifetime after this request (7 days by default); a later time is refused. Only where Layrcake runs approved actions itself (the result's approval block says execution: server); anywhere else it is refused. A dry run doesn't check it, so it refuses it: send it on the call itself.

TDQS

A3.5/5.0
Behavior1/5

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

The annotations declare idempotentHint: false, but the description says 'Repeating is always safe and never runs it twice' and describes an idempotency_key preventing double execution. That directly contradicts the annotation. Although the description otherwise adds useful approval, permission, and fail-closed context, the contradiction forces the minimum score.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

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

The description is long but front-loaded with the core action and dense with operational detail. Most sentences earn their place, though the idempotency and approval repetition details could be tightened without losing meaning.

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

Completeness4/5

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

For a complex, approval-gated launch tool with no output schema, the description covers the return preview, confirmation_token, approval_url, removed counts, and execution-mode branching. It still leaves daily_send_limit and supersedes under-explained, but it is largely complete.

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

Parameters3/5

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

Schema description coverage is only 43%, so the description must compensate. It adds meaning for dry_run and the confirmation_token/idempotency_key workflow, but it omits guidance for daily_send_limit, campaign_id, and supersedes semantics, leaving several parameters dependent on the schema alone.

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

Purpose5/5

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

The description states a specific verb and resource: 'Launch a draft campaign so real emails begin sending.' It clearly separates the launch action from sibling tools such as create_campaign, and an agent can identify the operation without opening the schema.

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

Usage Guidelines4/5

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

It gives clear context for when to call the tool, including the approval flow, dry_run for advisory estimates, and repeating with a confirmation token when server-side execution is not available. It does not name explicit sibling alternatives or state when not to use the tool, which keeps it below a 5.

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

prospect_pictureBuild a prospect pictureA
DestructiveIdempotent
Inspect

One picture of a person, a company, or both, for goal-style asks: who to contact, how to approach them, angles, what's changed, and why now. Optional audience (3–2,000 characters) orders why_now for your goal when checks are available; otherwise dated reasons remain newest first. ranking.by discloses goal or recency; ranking.why_now_judged counts judged reasons at the front of the top 20. Judged-no reasons leave only why_now; datapoints, claims and facts remain. The goal changes neither parts, budget admission nor charges. depth quick = verified contact and current intent signals; standard adds the company profile and funding and source-backed research; deep adds the person's recent LinkedIn posts and deep research. Returns an operation_id to poll with get_operation using the same data:read scope; the finished result has typed datapoints, research claims that each cite a source and a verbatim excerpt, why_now, every component's status with its reason, and the exact cost. Reserves the planner's maximum once and settles once: each completed component at its own verb's price plus a 3-credit assembly fee when data is returned. Eligible pooled research is selected during execution and costs 40% of its equivalent fresh component, so the discount may or may not apply after a dry-run quote; the quoted maximum never increases. An ambiguous provider outcome keeps the whole parent reservation held for operator reconciliation. budget_credits skips components that do not fit, in order, and refuses below the minimum. dry_run: true returns the plan and maxima as of evaluated_at with nothing reserved. idempotency_key is required; reuse it only to retry creation of the same picture.

NameRequiredDescriptionDefault
depthNostandard
personNo
dry_runNo
audienceNo
budget_creditsNo
company_domainNoCompany website domain or URL, e.g. acme.com or https://www.acme.com/about
idempotency_keyYesA payment_required refusal means services are stopped for unpaid billing; direct the owner to the billing link in the error. Campaigns stay paused after payment until restarted. Optional for search and enrichment tools: supply one so a retry returns the original result without paying again; if that call failed with provider_unavailable, rate_limited or insufficient_credits (after a top-up), a retry runs it once more after its cooldown (30 s, or a longer retry_after_seconds; insufficient_credits as soon as the balance covers it), unless its provider may already have done the work. Required for tools that create an external side effect; reuse the same value after a timeout or an approval. A stored failure comes back with details.replayed: true; with retry_after_seconds, retry the same value after that.

TDQS

A3.9/5.0
Behavior5/5

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

With annotations already declaring destructive/idempotent/open-world, the description still adds substantial behavior: reservation of the planner maximum and single settlement, the 3-credit assembly fee, the 40% pooled-research discount and its uncertainty after a dry-run, the ambiguous-provider holds, budget_credits skipping order, and the fact that reuse of idempotency_key is only for retrying the same creation. That is far beyond what the 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.

Conciseness3/5

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

The opening sentence is well front-loaded and the depth tiers are clear, but the middle is a dense run of cryptic clauses ('ranking.why_now_judged counts judged reasons at the front of the top 20', 'Judged-no reasons leave only why_now') that reference fields never defined in the schema. Information is high-value but packed into overlong sentences with weak structure.

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

Completeness4/5

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

No output schema exists, and the description compensates by describing the finished result (typed datapoints, source-cited research claims with verbatim excerpts, why_now, per-component status, exact cost) and the operation_id/get_operation polling flow with the same data:read scope. It is essentially complete for this complexity, though the undefined ranking fields and nested person/company input semantics leave small gaps.

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

Parameters4/5

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

Schema coverage is only 29%, so the description carries real weight: it explains what quick/standard/deep each add, that audience (3-2,000 chars) reorders why_now, that budget_credits skips non-fitting components and refuses below the minimum, and that dry_run reserves nothing. It leaves the person vs. company_domain object semantics (which identifiers are required, precedence when both are supplied) largely unexplained.

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

Purpose4/5

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

The description states a specific verb and composite resource ('One picture of a person, a company, or both') and enumerates the outputs it produces (who to contact, angles, why now), so an agent can tell it is a research/assembly tool rather than a raw lookup. It never names the sibling tools it overlaps with (enrich, research_company, find_intent), so differentiation is inferred rather than explicit.

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

Usage Guidelines3/5

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

Usage context is implied by 'for goal-style asks' and by the depth tiers (quick/standard/deep) plus dry_run, which tells the agent how to scope a call. There is no explicit when-to-use-this-vs-alternatives guidance, no prerequisites, and no statement of when a cheaper sibling should be preferred.

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

reply_to_threadSend a reply emailA
Destructive
Inspect

Send a real email in an inbound reply's existing thread from the mailbox that received it. An unconfirmed request returns a preview, confirmation_token, and approval_url. After a person approves, Layrcake runs it itself when the result's approval block says execution: server (a launch starts at its first-send time); otherwise, repeat the call with that token and a stable idempotency_key. Repeating is always safe and never runs it twice. Calling again without a token while the same request is still waiting for a decision returns that approval and sends no second email; after it was declined, expired or cancelled, calling again without a token asks again with a new confirmation_token. Requires reply:send, which is not granted by default. Refuses while any reply from this sender is pending or unavailable; wait until get_reply shows its interpreted_intent. Only one reply is allowed per inbound message; suppressed contacts are refused, and sender and subject are derived. operation_unknown_state includes an operation_id whose status is available from get_operation. dry_run: true returns an advisory estimate as of evaluated_at, reserves nothing, and may differ from a later execution plan.

NameRequiredDescriptionDefault
dry_runNo
reply_idYes
body_textYes
supersedesNoThe confirmation_token of the approval this request replaces. Needed only when that approval was already approved and hasn't started yet; one still waiting for a decision is replaced automatically. Only where Layrcake runs approved actions itself (the result's approval block says execution: server); anywhere else it is refused. A dry run doesn't check it, so it refuses it: send it on the call itself.
idempotency_keyNoA payment_required refusal means services are stopped for unpaid billing; direct the owner to the billing link in the error. Campaigns stay paused after payment until restarted. Optional for search and enrichment tools: supply one so a retry returns the original result without paying again; if that call failed with provider_unavailable, rate_limited or insufficient_credits (after a top-up), a retry runs it once more after its cooldown (30 s, or a longer retry_after_seconds; insufficient_credits as soon as the balance covers it), unless its provider may already have done the work. Required for tools that create an external side effect; reuse the same value after a timeout or an approval. A stored failure comes back with details.replayed: true; with retry_after_seconds, retry the same value after that.
confirmation_tokenNo

TDQS

A4.7/5.0
Behavior5/5

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

Beyond the annotations (destructiveHint=true, openWorldHint=true) it discloses the approval flow and its return (preview, confirmation_token, approval_url), who executes it (server vs. client repeat), that permission reply:send is not granted by default, and the exact refusal conditions. The idempotency claim is explicitly conditioned ("with that token"), so it does not contradict idempotentHint=false for raw repeats.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

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

Purpose is front-loaded, but the body is a dense run of long, nested sentences ("After a person approves, Layrcake runs it itself when...") and includes tangential detail such as launches starting at their first-send time and operation_unknown_state handling. Most content is non-redundant, but the parsing cost is high for a tool an agent must call correctly.

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

Completeness5/5

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

This is a complex asynchronous, approval-gated, side-effecting tool with no output schema, and the description covers return values, execution ownership, permissions, refusals, retry/idempotency behavior and dry-run semantics. Nothing material an agent needs to invoke it safely is missing.

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

Parameters4/5

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

With only 33% schema description coverage, the description compensates for the important unknowns: dry_run semantics (advisory estimate as of evaluated_at, reserves nothing, may differ), what confirmation_token does across retries, and that idempotency_key must be stable across a retry. reply_id and body_text are self-evident and left to the schema, which is acceptable.

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

Purpose5/5

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

The opening sentence gives a specific verb, resource and scope: send a real email into an inbound reply's existing thread, from the receiving mailbox. It also implicitly distinguishes the real send from the preview/dry-run path, so an agent can tell it apart from sibling read tools like get_reply or get_replies.

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

Usage Guidelines5/5

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

It states when-not as well as when: refuses while any reply from this sender is pending or unavailable, one reply per inbound message, suppressed contacts refused. It names the alternatives for the adjacent needs — repeat with confirmation_token plus idempotency_key after approval, get_reply to wait for interpreted_intent, get_operation to resolve operation_unknown_state.

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

research_companyResearch a companyA
DestructiveIdempotent
Inspect

Source-backed research on one company, for goal-style asks: angles, what's changed, how to approach it, why now. Recent news and identity searches (deep adds the homepage and up to three same-origin pages) are rewritten into typed claims (what it sells, customers, funding, hiring, leadership, partnerships, expansion) that each cite a source URL and a verbatim excerpt; why_now lists the recent dated ones. Optional audience (3–2,000 characters) ranks claims for your goal when goal checks are available; otherwise extraction order and the date rule apply. ranking.by discloses goal or recency, ranking.judged counts claims judged, and ranking.why_now_judged counts the judged reasons at the front of why_now; the rest are dated only. Judged no reasons leave why_now but remain in claims. The goal changes neither the price nor the workspace research cache. Returns an operation_id to poll with get_operation using the same data:read scope (a fresh cache hit arrives already completed with its result). Reserves the planner's maximum (standard: the research price; deep adds per-page reads) and settles the components actually used. An ambiguous provider outcome keeps that reservation held for operator reconciliation. budget_credits trims deep page reads to fit and refuses below the standard minimum. dry_run: true returns the plan as of evaluated_at with nothing reserved. idempotency_key is required; reuse it only to retry creation of the same research.

NameRequiredDescriptionDefault
depthNostandard
dry_runNo
audienceNoOptional goal for ranking facts. Always accepted; when checks are off or unavailable, extraction order and the date rule apply, disclosed by ranking. Charges are unchanged.
budget_creditsNo
company_domainYesCompany website domain or URL, e.g. acme.com or https://www.acme.com/about
idempotency_keyYesA payment_required refusal means services are stopped for unpaid billing; direct the owner to the billing link in the error. Campaigns stay paused after payment until restarted. Optional for search and enrichment tools: supply one so a retry returns the original result without paying again; if that call failed with provider_unavailable, rate_limited or insufficient_credits (after a top-up), a retry runs it once more after its cooldown (30 s, or a longer retry_after_seconds; insufficient_credits as soon as the balance covers it), unless its provider may already have done the work. Required for tools that create an external side effect; reuse the same value after a timeout or an approval. A stored failure comes back with details.replayed: true; with retry_after_seconds, retry the same value after that.

TDQS

A4.1/5.0
Behavior5/5

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

Goes well beyond the annotations: reservation/settlement mechanics, cache behavior ('a fresh cache hit arrives already completed'), the data:read scope needed for polling with get_operation, the held reservation on ambiguous provider outcomes, and idempotency retry semantics. The annotations (destructive/readOnly/openWorld) are consistent with the spend-and-external-call model described.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

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

Front-loaded with the core purpose, but the middle is dense internal jargon ('ranking.judged counts claims judged', 'ranking.why_now_judged counts the judged reasons at the front of why_now') that is hard to parse and partially duplicates the audience parameter's schema description.

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

Completeness4/5

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

With no output schema, the description carries the burden of describing returns and does so: typed claims with source URL and verbatim excerpt, why_now, ranking fields, and an operation_id to poll. The claim object's structure is only sketched, but an agent has enough to call and interpret the result.

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

Parameters4/5

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

Schema coverage is only 50%, and the description compensates: it defines what deep adds, the 3–2,000 character audience constraint (absent from the schema), how budget_credits trims and refuses below the standard minimum, and what dry_run returns. It adds less for company_domain, which the schema already documents well.

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

Purpose4/5

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

States a specific verb+resource ('Source-backed research on one company') and specifies the flavor of ask it serves (goal-style: angles, what's changed, how to approach, why now). It never names or contrasts with the close siblings (enrich_company, check_companies, find_companies), so an agent must still infer which company tool to pick.

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

Usage Guidelines4/5

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

Gives clear context for use ('for goal-style asks', recent news + identity searches, deep for homepage/same-origin pages) and describes the dry_run and budget_credits paths. It stops short of explicit exclusions or naming the alternative tools to use when the ask is not goal-style.

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

set_lead_statusSet lead statusA
DestructiveIdempotent
Inspect

Record a campaign lead's interest status (free, idempotent): interested, meeting_booked, won, not_interested, out_of_office, or neutral. Accepts the campaign_lead_id exposed by get_reply. not_interested irreversibly suppresses the contact from future campaigns in the workspace and removes them from active campaigns. The status is mirrored to the sending provider in the background; provider_sync_status reports pending, synced, failed, or unsupported. dry_run: true returns an advisory estimate as of evaluated_at, reserves nothing, and may differ from a later execution plan.

NameRequiredDescriptionDefault
proofNo
statusYes
dry_runNo
idempotency_keyYesA payment_required refusal means services are stopped for unpaid billing; direct the owner to the billing link in the error. Campaigns stay paused after payment until restarted. Optional for search and enrichment tools: supply one so a retry returns the original result without paying again; if that call failed with provider_unavailable, rate_limited or insufficient_credits (after a top-up), a retry runs it once more after its cooldown (30 s, or a longer retry_after_seconds; insufficient_credits as soon as the balance covers it), unless its provider may already have done the work. Required for tools that create an external side effect; reuse the same value after a timeout or an approval. A stored failure comes back with details.replayed: true; with retry_after_seconds, retry the same value after that.
campaign_lead_idYes

TDQS

A4.1/5.0
Behavior5/5

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

Goes well beyond the annotations (destructiveHint, idempotentHint, openWorldHint) by naming the irreversible consequence of not_interested (suppression from future campaigns and removal from active ones), the asynchronous provider mirror with its provider_sync_status states, and the semantics of dry_run. This is exactly the kind of consequence detail annotations cannot convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

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

Front-loaded with the core action and enum, then layers consequence and dry_run semantics in dense but purposeful sentences. Nothing is filler, though the middle sentence packs several distinct facts (irreversibility, campaign removal, provider sync) together.

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

Completeness5/5

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

With no output schema, the description compensates by naming the observable return signal (provider_sync_status) and the dry_run response shape (advisory estimate with evaluated_at). For a destructive, open-world mutation with five parameters, this covers what an agent needs to invoke and interpret the call.

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

Parameters3/5

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

Schema description coverage is only 20%, so the description must carry weight. It explains dry_run behavior, implies idempotency for idempotency_key, and traces campaign_lead_id to get_reply, which is useful. However, the `proof` parameter is never mentioned in either schema or description, and no format/syntax guidance is added for the parameters, leaving a real gap.

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

Purpose4/5

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

States a specific verb and resource (record a lead's interest status) and enumerates the exact accepted status values, so the agent knows precisely what the call does. No sibling tool overlaps in name or function, but the description does not explicitly position itself against any alternative, keeping it at 4 rather than 5.

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

Usage Guidelines4/5

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

Gives clear usage context: the campaign_lead_id comes from get_reply, and dry_run:true is framed as an advisory estimate that reserves nothing. It does not state when NOT to use the tool (e.g., for non-campaign contacts), so it stops short of explicit exclusions.

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

setup_sendingBuy sending capacityA
Destructive
Inspect

Provision warmed sending capacity (domains, mailboxes, DNS and warmup). An unconfirmed request returns a free quote, confirmation_token, and approval_url. After signed-in human approval, a request with that token and a stable idempotency_key executes the purchase. Requires assets:purchase. Successful execution returns an operation_id whose status is available from get_operation. dry_run: true returns an advisory estimate as of evaluated_at, reserves nothing, and may differ from a later execution plan.

NameRequiredDescriptionDefault
senderNo
dry_runNo
brand_hintNo
approval_urlNo
emails_per_weekYes
idempotency_keyNoA payment_required refusal means services are stopped for unpaid billing; direct the owner to the billing link in the error. Campaigns stay paused after payment until restarted. Optional for search and enrichment tools: supply one so a retry returns the original result without paying again; if that call failed with provider_unavailable, rate_limited or insufficient_credits (after a top-up), a retry runs it once more after its cooldown (30 s, or a longer retry_after_seconds; insufficient_credits as soon as the balance covers it), unless its provider may already have done the work. Required for tools that create an external side effect; reuse the same value after a timeout or an approval. A stored failure comes back with details.replayed: true; with retry_after_seconds, retry the same value after that.
prefer_prewarmedNo
confirmation_tokenNo

TDQS

A4.5/5.0
Behavior5/5

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

Goes well beyond the annotations (readOnlyHint=false, destructiveHint=true, openWorldHint=true, idempotentHint=false) by disclosing the required assets:purchase scope, the human-approval gate, the side-effect-free nature of dry_run, and that the operation_id status is retrievable via get_operation. The 'stable idempotency_key' retry guidance is compatible with idempotentHint=false, since deduplication depends on the caller supplying the same key.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

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

Four sentences, front-loaded with the purpose and then the quote/approve/execute flow, with dry_run's caveat last. Dense but every sentence carries operational information; no filler.

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

Completeness4/5

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

For an 8-parameter, nested-object, no-output-schema tool this covers the risky parts well: the approval flow, permission requirement, what dry_run returns, and how to poll the resulting operation. The remaining gap is that several input parameters (sender, brand_hint, prefer_prewarmed) are left entirely unexplained.

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

Parameters3/5

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

Schema description coverage is only 13% (just idempotency_key), so the description must compensate. It meaningfully explains dry_run, confirmation_token, approval_url, and idempotency_key, but says nothing about sender, brand_hint, prefer_prewarmed, or the 50–50000 emails_per_week bounds, leaving half the parameters undocumented.

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

Purpose5/5

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

States a concrete verb and resource ('Provision warmed sending capacity') and enumerates what is provisioned (domains, mailboxes, DNS, warmup). This is clearly distinguishable from every sibling, which are search, enrichment, and campaign tools.

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

Usage Guidelines5/5

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

Explicitly lays out the two-phase workflow: an unconfirmed request yields a quote plus confirmation_token/approval_url, and only a signed-in human approval followed by a request carrying that token executes the purchase. It also states exactly when to use dry_run:true (advisory estimate, reserves nothing) versus a real execution.

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

verify_emailVerify email addressA
Destructive
Inspect

Verify the deliverability of one email address (two-stage check incl. catch-all analysis). Returns status valid|invalid|catch_all_valid|catch_all_unknown|unknown|risky and is_catch_all_domain. Costs credits per call. An address from enrich already carries this check (its contact.email_verdict): call verify_email only for an address you got elsewhere. budget_credits is a spend ceiling, never permission to use a dearer source: above it, the call is refused before anything is reserved. dry_run: true returns the plan instead (the most the call can cost, how many sources could answer, and each limit it would trip) with nothing looked up, reserved or charged.

NameRequiredDescriptionDefault
emailYes
dry_runNoReturn this call's plan instead of running it, as of evaluated_at: the most it can cost, how many sources could answer, what budget_credits changes, and every limit the real call would trip. Nothing is looked up, reserved or charged, and a later call may differ. Where previews aren't available to this key yet, a request that sets it is refused with the reason.
budget_creditsNoSpend ceiling for this call, in credits. If the most the call can cost is above it, the call is refused before anything is reserved or charged. It is a ceiling only: it never lets the call use a dearer source. Where spend ceilings aren't available to this key yet, a request that sets it is refused with the reason.
idempotency_keyNoA payment_required refusal means services are stopped for unpaid billing; direct the owner to the billing link in the error. Campaigns stay paused after payment until restarted. Optional for search and enrichment tools: supply one so a retry returns the original result without paying again; if that call failed with provider_unavailable, rate_limited or insufficient_credits (after a top-up), a retry runs it once more after its cooldown (30 s, or a longer retry_after_seconds; insufficient_credits as soon as the balance covers it), unless its provider may already have done the work. Required for tools that create an external side effect; reuse the same value after a timeout or an approval. A stored failure comes back with details.replayed: true; with retry_after_seconds, retry the same value after that.

TDQS

A4.8/5.0
Behavior5/5

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

Goes well beyond annotations by disclosing credit cost per call, that an over-ceiling call is refused before any reservation, and that dry_run returns a plan with nothing looked up, reserved or charged. The two-stage/catch-all behavior and the exact return fields (status, is_catch_all_domain) are also disclosed, which annotations alone never convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

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

Front-loads purpose, then result values, then cost, then the sibling routing rule, then the two optional parameters — a sensible order. Sentences are dense but each carries information; the closing dry_run sentence is long and slightly overlaps the schema's own dry_run description.

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

Completeness5/5

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

With no output schema, the description still names the returned status enum and is_catch_all_domain, plus cost and refusal semantics for the spend ceiling. An agent has everything needed to decide whether to call it and how to interpret a result.

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

Parameters4/5

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

Schema coverage is 75%, so the schema already documents dry_run and budget_credits at length; the description nevertheless adds interpretive nuance the schema lacks, notably that budget_credits is a ceiling and 'never permission to use a dearer source.' The email parameter itself gets no added guidance, which is the only gap.

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

Purpose5/5

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

States a specific verb and resource ('Verify the deliverability of one email address') and pins the scope to a single address, distinguishing it from bulk enrichment siblings. It even enumerates the possible return statuses, so the agent knows exactly what kind of answer to expect.

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

Usage Guidelines5/5

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

Explicitly routes the agent away from redundant calls: 'An address from enrich already carries this check (its contact.email_verdict): call verify_email only for an address you got elsewhere.' This names the sibling, the field to check instead, and the condition that selects this tool.

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

Tool Schema Changelog

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

  1. 2 tool updates
    • Changedfind_companies2 fields changed
      • addedInput schema / properties / exclude_domains
        Added value: +{
        +  "description": "Company domains to leave out, up to 500: companies you've already seen. They are never returned or charged, and result.left_out.excluded counts those the search came across. In mode firmographic the search fetches further to fill the limit.",
        +  "items": {
        +    "description": "Company website domain or URL, e.g. acme.com or https://www.acme.com/about",
        +    "maxLength": 2048,
        +    "minLength": 1,
        +    "type": "string"
        +  },
        +  "maxItems": 1000,
        +  "type": "array"
        +}
      • addedInput schema / properties / include_handled
        Added value: +{
        +  "description": "Only inside an agent run: true includes companies this agent already checked (yes or not_found) in the last 90 days, which the run's searches otherwise leave out. Outside an agent run it changes nothing.",
        +  "type": "boolean"
        +}
    • Changedfind_leads1 field changed
      • addedInput schema / properties / include_handled
        Added value: +{
        +  "description": "Only inside an agent run: true includes people this agent already put in a campaign in the last 90 days, which the run's searches otherwise leave out. Outside an agent run it changes nothing.",
        +  "type": "boolean"
        +}
  2. 1 tool update
    • Changedfind_companies5 fields changed
      • addedInput schema / properties / event
        Added value: +{
        +  "description": "Only with mode events: what happened to the companies, in plain words, for example \"opened a new office in London\" or \"disclosed a data breach\".",
        +  "type": "string"
        +}
      • addedInput schema / properties / limit / description
        Added value: +"Most companies to return: up to 100, default 25. Mode events: up to 25, default 15."
      • changedInput schema / properties / mode / description
        Previous value: -"firmographic: companies by industries (LinkedIn's names, as on find_leads), country_codes, and optionally locations and company_headcount. local: local businesses by categories (for example \"dentist\") in locations. Leave it out for hiring, technologies, similar_to or query. Where a mode isn't available to this key yet, a request that sets it is refused with the reason."New value: +"firmographic: companies by industries (LinkedIn's names, as on find_leads), country_codes, and optionally locations and company_headcount. local: local businesses by categories (for example \"dentist\") in locations. events: companies that had something happen (event, within within_days), each with a verbatim quote, its source and date; runs in the background and needs an Idempotency-Key. Leave it out for hiring, technologies, similar_to or query. Where a mode isn't available to this key yet, a request that sets it is refused with the reason."
      • changedInput schema / properties / mode / enum
        Previous value: -[
        -  "firmographic",
        -  "local"
        -]New value: +[
        +  "firmographic",
        +  "local",
        +  "events"
        +]
      • addedInput schema / properties / within_days
        Added value: +{
        +  "description": "Only with mode events: the event happened in the last this many days (1 to 365, default 90). A company whose event has no date is left out.",
        +  "maximum": 365,
        +  "minimum": 1,
        +  "type": "integer"
        +}
  3. 1 tool update
    • Changedfind_companies2 fields changed
      • addedInput schema / properties / min_rating
        Added value: +{
        +  "description": "Only with mode local: the lowest public map rating to keep, 1 to 5 with one decimal, for example 4.5. A business with no rating is left out and not charged. Where it isn't available to this key yet, a request that sets it is refused with the reason.",
        +  "maximum": 5,
        +  "minimum": 1,
        +  "type": "number"
        +}
      • addedInput schema / properties / min_reviews
        Added value: +{
        +  "description": "Only with mode local: the fewest public map reviews to keep, for example 20. A business with no review count is left out and not charged. Where it isn't available to this key yet, a request that sets it is refused with the reason.",
        +  "maximum": 1000000,
        +  "minimum": 1,
        +  "type": "integer"
        +}
  4. 2 tool updates
    • Changedfind_companies3 fields changed
      • addedInput schema / properties / industries / description
        Added value: +"LinkedIn industry names, for example \"Software Development\" or \"Online and Mail Order Retail\"; other words go in keywords (firmographic)."
      • changedInput schema / properties / keywords / description
        Previous value: -"Only with mode firmographic: 1 to 10 phrases, for example \"carbon accounting\" or \"dental practice management\". A company matches when its own description, products or specialties mention any of them; with keywords, industries may be left out. Each company then comes back with its description. Where keywords aren't available to this key yet, a request that sets them is refused with the reason."New value: +"Only with mode firmographic: 1 to 10 phrases, for example \"carbon accounting\"; for a non-English-speaking country add its own words too. A company matches when its own description, products or specialties mention any of them, in the language they are written in; with keywords, industries may be left out, and an industry that means the same as a keyword asks for it twice. Each company then comes back with its description. Where keywords aren't available to this key yet, a request that sets them is refused with the reason."
      • addedInput schema / properties / query / description
        Added value: +"Plain-language description of the companies; one with no hiring or technology in it also needs a country (country_codes, or in the words)."
    • Changedfind_leads1 field changed
      • addedInput schema / properties / industries / description
        Added value: +"LinkedIn industry names, for example \"Hospitals and Health Care\" or \"Software Development\"."
  5. 1 tool update
    • Changedset_lead_status1 field changed
      • addedInput schema / properties / proof
        Added value: +{
        +  "maxLength": 500,
        +  "minLength": 1,
        +  "type": "string"
        +}
  6. 1 tool update
    • Changedfind_companies2 fields changed
      • addedInput schema / properties / exclude_keywords
        Added value: +{
        +  "description": "Only with mode firmographic: up to 10 phrases, for example \"recruitment agency\" or \"consultancy\". Companies whose own description mentions any of them are left out. Each company then comes back with its description. Where exclude_keywords aren't available to this key yet, a request that sets them is refused with the reason.",
        +  "items": {
        +    "maxLength": 120,
        +    "minLength": 1,
        +    "type": "string"
        +  },
        +  "maxItems": 20,
        +  "type": "array"
        +}
      • addedInput schema / properties / keywords
        Added value: +{
        +  "description": "Only with mode firmographic: 1 to 10 phrases, for example \"carbon accounting\" or \"dental practice management\". A company matches when its own description, products or specialties mention any of them; with keywords, industries may be left out. Each company then comes back with its description. Where keywords aren't available to this key yet, a request that sets them is refused with the reason.",
        +  "items": {
        +    "maxLength": 120,
        +    "minLength": 1,
        +    "type": "string"
        +  },
        +  "maxItems": 20,
        +  "type": "array"
        +}
  7. 2 tool updates
    • Changedadd_leads1 field changed
      • addedInput schema / properties / leads / items / properties / location
        Added value: +{
        +  "maxLength": 200,
        +  "type": "string"
        +}
    • Changedcreate_campaign1 field changed
      • addedInput schema / properties / leads / items / properties / location
        Added value: +{
        +  "maxLength": 200,
        +  "type": "string"
        +}
  8. 18 tool updates
    • Changedadd_leads1 field changed
      • changedInput schema / properties / idempotency_key / description
        Previous value: -"Optional for search and enrichment tools: supply one so a retry returns the original result without paying again; if that call failed with provider_unavailable, rate_limited or insufficient_credits (after a top-up), a retry runs it once more after its cooldown (30 s, or a longer retry_after_seconds; insufficient_credits as soon as the balance covers it), unless its provider may already have done the work. Required for tools that create an external side effect; reuse the same value after a timeout or an approval. A stored failure comes back with details.replayed: true; with retry_after_seconds, retry the same value after that."New value: +"A payment_required refusal means services are stopped for unpaid billing; direct the owner to the billing link in the error. Campaigns stay paused after payment until restarted. Optional for search and enrichment tools: supply one so a retry returns the original result without paying again; if that call failed with provider_unavailable, rate_limited or insufficient_credits (after a top-up), a retry runs it once more after its cooldown (30 s, or a longer retry_after_seconds; insufficient_credits as soon as the balance covers it), unless its provider may already have done the work. Required for tools that create an external side effect; reuse the same value after a timeout or an approval. A stored failure comes back with details.replayed: true; with retry_after_seconds, retry the same value after that."
    • Changedcheck_companies1 field changed
      • changedInput schema / properties / idempotency_key / description
        Previous value: -"Optional for search and enrichment tools: supply one so a retry returns the original result without paying again; if that call failed with provider_unavailable, rate_limited or insufficient_credits (after a top-up), a retry runs it once more after its cooldown (30 s, or a longer retry_after_seconds; insufficient_credits as soon as the balance covers it), unless its provider may already have done the work. Required for tools that create an external side effect; reuse the same value after a timeout or an approval. A stored failure comes back with details.replayed: true; with retry_after_seconds, retry the same value after that."New value: +"A payment_required refusal means services are stopped for unpaid billing; direct the owner to the billing link in the error. Campaigns stay paused after payment until restarted. Optional for search and enrichment tools: supply one so a retry returns the original result without paying again; if that call failed with provider_unavailable, rate_limited or insufficient_credits (after a top-up), a retry runs it once more after its cooldown (30 s, or a longer retry_after_seconds; insufficient_credits as soon as the balance covers it), unless its provider may already have done the work. Required for tools that create an external side effect; reuse the same value after a timeout or an approval. A stored failure comes back with details.replayed: true; with retry_after_seconds, retry the same value after that."
    • Changedcreate_campaign1 field changed
      • changedInput schema / properties / idempotency_key / description
        Previous value: -"Optional for search and enrichment tools: supply one so a retry returns the original result without paying again; if that call failed with provider_unavailable, rate_limited or insufficient_credits (after a top-up), a retry runs it once more after its cooldown (30 s, or a longer retry_after_seconds; insufficient_credits as soon as the balance covers it), unless its provider may already have done the work. Required for tools that create an external side effect; reuse the same value after a timeout or an approval. A stored failure comes back with details.replayed: true; with retry_after_seconds, retry the same value after that."New value: +"A payment_required refusal means services are stopped for unpaid billing; direct the owner to the billing link in the error. Campaigns stay paused after payment until restarted. Optional for search and enrichment tools: supply one so a retry returns the original result without paying again; if that call failed with provider_unavailable, rate_limited or insufficient_credits (after a top-up), a retry runs it once more after its cooldown (30 s, or a longer retry_after_seconds; insufficient_credits as soon as the balance covers it), unless its provider may already have done the work. Required for tools that create an external side effect; reuse the same value after a timeout or an approval. A stored failure comes back with details.replayed: true; with retry_after_seconds, retry the same value after that."
    • Changedenrich2 fields changed
      • changedInput schema / properties / idempotency_key / description
        Previous value: -"Optional for search and enrichment tools: supply one so a retry returns the original result without paying again; if that call failed with provider_unavailable, rate_limited or insufficient_credits (after a top-up), a retry runs it once more after its cooldown (30 s, or a longer retry_after_seconds; insufficient_credits as soon as the balance covers it), unless its provider may already have done the work. Required for tools that create an external side effect; reuse the same value after a timeout or an approval. A stored failure comes back with details.replayed: true; with retry_after_seconds, retry the same value after that."New value: +"A payment_required refusal means services are stopped for unpaid billing; direct the owner to the billing link in the error. Campaigns stay paused after payment until restarted. Optional for search and enrichment tools: supply one so a retry returns the original result without paying again; if that call failed with provider_unavailable, rate_limited or insufficient_credits (after a top-up), a retry runs it once more after its cooldown (30 s, or a longer retry_after_seconds; insufficient_credits as soon as the balance covers it), unless its provider may already have done the work. Required for tools that create an external side effect; reuse the same value after a timeout or an approval. A stored failure comes back with details.replayed: true; with retry_after_seconds, retry the same value after that."
      • changedInput schema / properties / want / description
        Previous value: -"What to look up. work_email and profile run the email lookup (5 credits on a hit), which returns a mobile number too when its source has one. mobile_phone also runs a separate mobile search when the email lookup found none: 15 credits when that search finds one, 5 when the mobile came with the email, nothing when no mobile is found; a mobile_phone-only request that finds only an email is free and returns nothing. Where this isn't applied for your key yet, every call runs the same email lookup whatever this lists."New value: +"What to look up. work_email and profile run the email lookup (5 credits on a hit), which returns a mobile number too when its source has one. mobile_phone also runs a separate mobile search when the email lookup found none: 17 credits when that search finds one, 5 when the mobile came with the email, nothing when no mobile is found; a mobile_phone-only request that finds only an email is free and returns nothing. Where this isn't applied for your key yet, every call runs the same email lookup whatever this lists."
    • Changedenrich_company1 field changed
      • changedInput schema / properties / idempotency_key / description
        Previous value: -"Optional for search and enrichment tools: supply one so a retry returns the original result without paying again; if that call failed with provider_unavailable, rate_limited or insufficient_credits (after a top-up), a retry runs it once more after its cooldown (30 s, or a longer retry_after_seconds; insufficient_credits as soon as the balance covers it), unless its provider may already have done the work. Required for tools that create an external side effect; reuse the same value after a timeout or an approval. A stored failure comes back with details.replayed: true; with retry_after_seconds, retry the same value after that."New value: +"A payment_required refusal means services are stopped for unpaid billing; direct the owner to the billing link in the error. Campaigns stay paused after payment until restarted. Optional for search and enrichment tools: supply one so a retry returns the original result without paying again; if that call failed with provider_unavailable, rate_limited or insufficient_credits (after a top-up), a retry runs it once more after its cooldown (30 s, or a longer retry_after_seconds; insufficient_credits as soon as the balance covers it), unless its provider may already have done the work. Required for tools that create an external side effect; reuse the same value after a timeout or an approval. A stored failure comes back with details.replayed: true; with retry_after_seconds, retry the same value after that."
    • Changedfind_companies1 field changed
      • changedInput schema / properties / idempotency_key / description
        Previous value: -"Optional for search and enrichment tools: supply one so a retry returns the original result without paying again; if that call failed with provider_unavailable, rate_limited or insufficient_credits (after a top-up), a retry runs it once more after its cooldown (30 s, or a longer retry_after_seconds; insufficient_credits as soon as the balance covers it), unless its provider may already have done the work. Required for tools that create an external side effect; reuse the same value after a timeout or an approval. A stored failure comes back with details.replayed: true; with retry_after_seconds, retry the same value after that."New value: +"A payment_required refusal means services are stopped for unpaid billing; direct the owner to the billing link in the error. Campaigns stay paused after payment until restarted. Optional for search and enrichment tools: supply one so a retry returns the original result without paying again; if that call failed with provider_unavailable, rate_limited or insufficient_credits (after a top-up), a retry runs it once more after its cooldown (30 s, or a longer retry_after_seconds; insufficient_credits as soon as the balance covers it), unless its provider may already have done the work. Required for tools that create an external side effect; reuse the same value after a timeout or an approval. A stored failure comes back with details.replayed: true; with retry_after_seconds, retry the same value after that."
    • Changedfind_intent1 field changed
      • changedInput schema / properties / idempotency_key / description
        Previous value: -"Optional for search and enrichment tools: supply one so a retry returns the original result without paying again; if that call failed with provider_unavailable, rate_limited or insufficient_credits (after a top-up), a retry runs it once more after its cooldown (30 s, or a longer retry_after_seconds; insufficient_credits as soon as the balance covers it), unless its provider may already have done the work. Required for tools that create an external side effect; reuse the same value after a timeout or an approval. A stored failure comes back with details.replayed: true; with retry_after_seconds, retry the same value after that."New value: +"A payment_required refusal means services are stopped for unpaid billing; direct the owner to the billing link in the error. Campaigns stay paused after payment until restarted. Optional for search and enrichment tools: supply one so a retry returns the original result without paying again; if that call failed with provider_unavailable, rate_limited or insufficient_credits (after a top-up), a retry runs it once more after its cooldown (30 s, or a longer retry_after_seconds; insufficient_credits as soon as the balance covers it), unless its provider may already have done the work. Required for tools that create an external side effect; reuse the same value after a timeout or an approval. A stored failure comes back with details.replayed: true; with retry_after_seconds, retry the same value after that."
    • Changedfind_leads1 field changed
      • changedInput schema / properties / idempotency_key / description
        Previous value: -"Optional for search and enrichment tools: supply one so a retry returns the original result without paying again; if that call failed with provider_unavailable, rate_limited or insufficient_credits (after a top-up), a retry runs it once more after its cooldown (30 s, or a longer retry_after_seconds; insufficient_credits as soon as the balance covers it), unless its provider may already have done the work. Required for tools that create an external side effect; reuse the same value after a timeout or an approval. A stored failure comes back with details.replayed: true; with retry_after_seconds, retry the same value after that."New value: +"A payment_required refusal means services are stopped for unpaid billing; direct the owner to the billing link in the error. Campaigns stay paused after payment until restarted. Optional for search and enrichment tools: supply one so a retry returns the original result without paying again; if that call failed with provider_unavailable, rate_limited or insufficient_credits (after a top-up), a retry runs it once more after its cooldown (30 s, or a longer retry_after_seconds; insufficient_credits as soon as the balance covers it), unless its provider may already have done the work. Required for tools that create an external side effect; reuse the same value after a timeout or an approval. A stored failure comes back with details.replayed: true; with retry_after_seconds, retry the same value after that."
    • Changedfind_posts1 field changed
      • changedInput schema / properties / idempotency_key / description
        Previous value: -"Optional for search and enrichment tools: supply one so a retry returns the original result without paying again; if that call failed with provider_unavailable, rate_limited or insufficient_credits (after a top-up), a retry runs it once more after its cooldown (30 s, or a longer retry_after_seconds; insufficient_credits as soon as the balance covers it), unless its provider may already have done the work. Required for tools that create an external side effect; reuse the same value after a timeout or an approval. A stored failure comes back with details.replayed: true; with retry_after_seconds, retry the same value after that."New value: +"A payment_required refusal means services are stopped for unpaid billing; direct the owner to the billing link in the error. Campaigns stay paused after payment until restarted. Optional for search and enrichment tools: supply one so a retry returns the original result without paying again; if that call failed with provider_unavailable, rate_limited or insufficient_credits (after a top-up), a retry runs it once more after its cooldown (30 s, or a longer retry_after_seconds; insufficient_credits as soon as the balance covers it), unless its provider may already have done the work. Required for tools that create an external side effect; reuse the same value after a timeout or an approval. A stored failure comes back with details.replayed: true; with retry_after_seconds, retry the same value after that."
    • Changedget_replies1 field changed
      • changedInput schema / properties / idempotency_key / description
        Previous value: -"Optional for search and enrichment tools: supply one so a retry returns the original result without paying again; if that call failed with provider_unavailable, rate_limited or insufficient_credits (after a top-up), a retry runs it once more after its cooldown (30 s, or a longer retry_after_seconds; insufficient_credits as soon as the balance covers it), unless its provider may already have done the work. Required for tools that create an external side effect; reuse the same value after a timeout or an approval. A stored failure comes back with details.replayed: true; with retry_after_seconds, retry the same value after that."New value: +"A payment_required refusal means services are stopped for unpaid billing; direct the owner to the billing link in the error. Campaigns stay paused after payment until restarted. Optional for search and enrichment tools: supply one so a retry returns the original result without paying again; if that call failed with provider_unavailable, rate_limited or insufficient_credits (after a top-up), a retry runs it once more after its cooldown (30 s, or a longer retry_after_seconds; insufficient_credits as soon as the balance covers it), unless its provider may already have done the work. Required for tools that create an external side effect; reuse the same value after a timeout or an approval. A stored failure comes back with details.replayed: true; with retry_after_seconds, retry the same value after that."
    • Changedget_reply1 field changed
      • changedInput schema / properties / idempotency_key / description
        Previous value: -"Optional for search and enrichment tools: supply one so a retry returns the original result without paying again; if that call failed with provider_unavailable, rate_limited or insufficient_credits (after a top-up), a retry runs it once more after its cooldown (30 s, or a longer retry_after_seconds; insufficient_credits as soon as the balance covers it), unless its provider may already have done the work. Required for tools that create an external side effect; reuse the same value after a timeout or an approval. A stored failure comes back with details.replayed: true; with retry_after_seconds, retry the same value after that."New value: +"A payment_required refusal means services are stopped for unpaid billing; direct the owner to the billing link in the error. Campaigns stay paused after payment until restarted. Optional for search and enrichment tools: supply one so a retry returns the original result without paying again; if that call failed with provider_unavailable, rate_limited or insufficient_credits (after a top-up), a retry runs it once more after its cooldown (30 s, or a longer retry_after_seconds; insufficient_credits as soon as the balance covers it), unless its provider may already have done the work. Required for tools that create an external side effect; reuse the same value after a timeout or an approval. A stored failure comes back with details.replayed: true; with retry_after_seconds, retry the same value after that."
    • Changedlaunch_campaign1 field changed
      • changedInput schema / properties / idempotency_key / description
        Previous value: -"Optional for search and enrichment tools: supply one so a retry returns the original result without paying again; if that call failed with provider_unavailable, rate_limited or insufficient_credits (after a top-up), a retry runs it once more after its cooldown (30 s, or a longer retry_after_seconds; insufficient_credits as soon as the balance covers it), unless its provider may already have done the work. Required for tools that create an external side effect; reuse the same value after a timeout or an approval. A stored failure comes back with details.replayed: true; with retry_after_seconds, retry the same value after that."New value: +"A payment_required refusal means services are stopped for unpaid billing; direct the owner to the billing link in the error. Campaigns stay paused after payment until restarted. Optional for search and enrichment tools: supply one so a retry returns the original result without paying again; if that call failed with provider_unavailable, rate_limited or insufficient_credits (after a top-up), a retry runs it once more after its cooldown (30 s, or a longer retry_after_seconds; insufficient_credits as soon as the balance covers it), unless its provider may already have done the work. Required for tools that create an external side effect; reuse the same value after a timeout or an approval. A stored failure comes back with details.replayed: true; with retry_after_seconds, retry the same value after that."
    • Changedprospect_picture1 field changed
      • changedInput schema / properties / idempotency_key / description
        Previous value: -"Optional for search and enrichment tools: supply one so a retry returns the original result without paying again; if that call failed with provider_unavailable, rate_limited or insufficient_credits (after a top-up), a retry runs it once more after its cooldown (30 s, or a longer retry_after_seconds; insufficient_credits as soon as the balance covers it), unless its provider may already have done the work. Required for tools that create an external side effect; reuse the same value after a timeout or an approval. A stored failure comes back with details.replayed: true; with retry_after_seconds, retry the same value after that."New value: +"A payment_required refusal means services are stopped for unpaid billing; direct the owner to the billing link in the error. Campaigns stay paused after payment until restarted. Optional for search and enrichment tools: supply one so a retry returns the original result without paying again; if that call failed with provider_unavailable, rate_limited or insufficient_credits (after a top-up), a retry runs it once more after its cooldown (30 s, or a longer retry_after_seconds; insufficient_credits as soon as the balance covers it), unless its provider may already have done the work. Required for tools that create an external side effect; reuse the same value after a timeout or an approval. A stored failure comes back with details.replayed: true; with retry_after_seconds, retry the same value after that."
    • Changedreply_to_thread1 field changed
      • changedInput schema / properties / idempotency_key / description
        Previous value: -"Optional for search and enrichment tools: supply one so a retry returns the original result without paying again; if that call failed with provider_unavailable, rate_limited or insufficient_credits (after a top-up), a retry runs it once more after its cooldown (30 s, or a longer retry_after_seconds; insufficient_credits as soon as the balance covers it), unless its provider may already have done the work. Required for tools that create an external side effect; reuse the same value after a timeout or an approval. A stored failure comes back with details.replayed: true; with retry_after_seconds, retry the same value after that."New value: +"A payment_required refusal means services are stopped for unpaid billing; direct the owner to the billing link in the error. Campaigns stay paused after payment until restarted. Optional for search and enrichment tools: supply one so a retry returns the original result without paying again; if that call failed with provider_unavailable, rate_limited or insufficient_credits (after a top-up), a retry runs it once more after its cooldown (30 s, or a longer retry_after_seconds; insufficient_credits as soon as the balance covers it), unless its provider may already have done the work. Required for tools that create an external side effect; reuse the same value after a timeout or an approval. A stored failure comes back with details.replayed: true; with retry_after_seconds, retry the same value after that."
    • Changedresearch_company1 field changed
      • changedInput schema / properties / idempotency_key / description
        Previous value: -"Optional for search and enrichment tools: supply one so a retry returns the original result without paying again; if that call failed with provider_unavailable, rate_limited or insufficient_credits (after a top-up), a retry runs it once more after its cooldown (30 s, or a longer retry_after_seconds; insufficient_credits as soon as the balance covers it), unless its provider may already have done the work. Required for tools that create an external side effect; reuse the same value after a timeout or an approval. A stored failure comes back with details.replayed: true; with retry_after_seconds, retry the same value after that."New value: +"A payment_required refusal means services are stopped for unpaid billing; direct the owner to the billing link in the error. Campaigns stay paused after payment until restarted. Optional for search and enrichment tools: supply one so a retry returns the original result without paying again; if that call failed with provider_unavailable, rate_limited or insufficient_credits (after a top-up), a retry runs it once more after its cooldown (30 s, or a longer retry_after_seconds; insufficient_credits as soon as the balance covers it), unless its provider may already have done the work. Required for tools that create an external side effect; reuse the same value after a timeout or an approval. A stored failure comes back with details.replayed: true; with retry_after_seconds, retry the same value after that."
    • Changedset_lead_status1 field changed
      • changedInput schema / properties / idempotency_key / description
        Previous value: -"Optional for search and enrichment tools: supply one so a retry returns the original result without paying again; if that call failed with provider_unavailable, rate_limited or insufficient_credits (after a top-up), a retry runs it once more after its cooldown (30 s, or a longer retry_after_seconds; insufficient_credits as soon as the balance covers it), unless its provider may already have done the work. Required for tools that create an external side effect; reuse the same value after a timeout or an approval. A stored failure comes back with details.replayed: true; with retry_after_seconds, retry the same value after that."New value: +"A payment_required refusal means services are stopped for unpaid billing; direct the owner to the billing link in the error. Campaigns stay paused after payment until restarted. Optional for search and enrichment tools: supply one so a retry returns the original result without paying again; if that call failed with provider_unavailable, rate_limited or insufficient_credits (after a top-up), a retry runs it once more after its cooldown (30 s, or a longer retry_after_seconds; insufficient_credits as soon as the balance covers it), unless its provider may already have done the work. Required for tools that create an external side effect; reuse the same value after a timeout or an approval. A stored failure comes back with details.replayed: true; with retry_after_seconds, retry the same value after that."
    • Changedsetup_sending1 field changed
      • changedInput schema / properties / idempotency_key / description
        Previous value: -"Optional for search and enrichment tools: supply one so a retry returns the original result without paying again; if that call failed with provider_unavailable, rate_limited or insufficient_credits (after a top-up), a retry runs it once more after its cooldown (30 s, or a longer retry_after_seconds; insufficient_credits as soon as the balance covers it), unless its provider may already have done the work. Required for tools that create an external side effect; reuse the same value after a timeout or an approval. A stored failure comes back with details.replayed: true; with retry_after_seconds, retry the same value after that."New value: +"A payment_required refusal means services are stopped for unpaid billing; direct the owner to the billing link in the error. Campaigns stay paused after payment until restarted. Optional for search and enrichment tools: supply one so a retry returns the original result without paying again; if that call failed with provider_unavailable, rate_limited or insufficient_credits (after a top-up), a retry runs it once more after its cooldown (30 s, or a longer retry_after_seconds; insufficient_credits as soon as the balance covers it), unless its provider may already have done the work. Required for tools that create an external side effect; reuse the same value after a timeout or an approval. A stored failure comes back with details.replayed: true; with retry_after_seconds, retry the same value after that."
    • Changedverify_email1 field changed
      • changedInput schema / properties / idempotency_key / description
        Previous value: -"Optional for search and enrichment tools: supply one so a retry returns the original result without paying again; if that call failed with provider_unavailable, rate_limited or insufficient_credits (after a top-up), a retry runs it once more after its cooldown (30 s, or a longer retry_after_seconds; insufficient_credits as soon as the balance covers it), unless its provider may already have done the work. Required for tools that create an external side effect; reuse the same value after a timeout or an approval. A stored failure comes back with details.replayed: true; with retry_after_seconds, retry the same value after that."New value: +"A payment_required refusal means services are stopped for unpaid billing; direct the owner to the billing link in the error. Campaigns stay paused after payment until restarted. Optional for search and enrichment tools: supply one so a retry returns the original result without paying again; if that call failed with provider_unavailable, rate_limited or insufficient_credits (after a top-up), a retry runs it once more after its cooldown (30 s, or a longer retry_after_seconds; insufficient_credits as soon as the balance covers it), unless its provider may already have done the work. Required for tools that create an external side effect; reuse the same value after a timeout or an approval. A stored failure comes back with details.replayed: true; with retry_after_seconds, retry the same value after that."
  9. 1 tool update
    • Changedcreate_campaign1 field changed
      • changedInput schema / properties / sending_window / properties / timezone / enum
        Previous value: -[
        -  "Etc/UTC",
        -  "Etc/GMT+12",
        -  "Etc/GMT+11",
        -  "Etc/GMT+10",
        -  "America/Anchorage",
        -  "America/Dawson",
        -  "America/Creston",
        -  "America/Chihuahua",
        -  "America/Boise",
        -  "America/Belize",
        -  "America/Chicago",
        -  "America/Bahia_Banderas",
        -  "America/Regina",
        -  "America/Bogota",
        -  "America/Detroit",
        -  "America/Indiana/Marengo",
        -  "America/Caracas",
        -  "America/Asuncion",
        -  "America/Glace_Bay",
        -  "America/Campo_Grande",
        -  "America/Anguilla",
        -  "America/Santiago",
        -  "America/St_Johns",
        -  "America/Sao_Paulo",
        -  "America/Argentina/La_Rioja",
        -  "America/Araguaina",
        -  "America/Godthab",
        -  "America/Montevideo",
        -  "America/Bahia",
        -  "America/Noronha",
        -  "America/Scoresbysund",
        -  "Atlantic/Cape_Verde",
        -  "Africa/Casablanca",
        -  "America/Danmarkshavn",
        -  "Europe/Isle_of_Man",
        -  "Atlantic/Canary",
        -  "Africa/Abidjan",
        -  "Arctic/Longyearbyen",
        -  "Europe/Belgrade",
        -  "Africa/Ceuta",
        -  "Europe/Madrid",
        -  "Europe/Sarajevo",
        -  "Africa/Algiers",
        -  "Africa/Windhoek",
        -  "Asia/Nicosia",
        -  "Asia/Beirut",
        -  "Africa/Cairo",
        -  "Asia/Damascus",
        -  "Europe/Bucharest",
        -  "Africa/Blantyre",
        -  "Europe/Helsinki",
        -  "Europe/Istanbul",
        -  "Asia/Jerusalem",
        -  "Africa/Tripoli",
        -  "Asia/Amman",
        -  "Asia/Baghdad",
        -  "Europe/Kaliningrad",
        -  "Asia/Aden",
        -  "Africa/Addis_Ababa",
        -  "Europe/Kirov",
        -  "Europe/Astrakhan",
        -  "Asia/Tehran",
        -  "Asia/Dubai",
        -  "Asia/Baku",
        -  "Indian/Mahe",
        -  "Asia/Tbilisi",
        -  "Asia/Yerevan",
        -  "Asia/Kabul",
        -  "Antarctica/Mawson",
        -  "Asia/Yekaterinburg",
        -  "Asia/Karachi",
        -  "Asia/Kolkata",
        -  "Asia/Colombo",
        -  "Asia/Kathmandu",
        -  "Antarctica/Vostok",
        -  "Asia/Dhaka",
        -  "Asia/Rangoon",
        -  "Antarctica/Davis",
        -  "Asia/Novokuznetsk",
        -  "Asia/Hong_Kong",
        -  "Asia/Krasnoyarsk",
        -  "Asia/Brunei",
        -  "Australia/Perth",
        -  "Asia/Taipei",
        -  "Asia/Choibalsan",
        -  "Asia/Irkutsk",
        -  "Asia/Dili",
        -  "Asia/Pyongyang",
        -  "Australia/Adelaide",
        -  "Australia/Darwin",
        -  "Australia/Brisbane",
        -  "Australia/Melbourne",
        -  "Antarctica/DumontDUrville",
        -  "Australia/Currie",
        -  "Asia/Chita",
        -  "Antarctica/Macquarie",
        -  "Asia/Sakhalin",
        -  "Pacific/Auckland",
        -  "Etc/GMT-12",
        -  "Pacific/Fiji",
        -  "Asia/Anadyr",
        -  "Asia/Kamchatka",
        -  "Etc/GMT-13",
        -  "Pacific/Apia"
        -]New value: +[
        +  "Europe/London",
        +  "Europe/Dublin",
        +  "Europe/Paris",
        +  "Europe/Berlin",
        +  "America/New_York",
        +  "America/Denver",
        +  "America/Phoenix",
        +  "America/Toronto",
        +  "Australia/Sydney",
        +  "Asia/Singapore",
        +  "Etc/UTC",
        +  "Etc/GMT+12",
        +  "Etc/GMT+11",
        +  "Etc/GMT+10",
        +  "America/Anchorage",
        +  "America/Dawson",
        +  "America/Creston",
        +  "America/Chihuahua",
        +  "America/Boise",
        +  "America/Belize",
        +  "America/Chicago",
        +  "America/Bahia_Banderas",
        +  "America/Regina",
        +  "America/Bogota",
        +  "America/Detroit",
        +  "America/Indiana/Marengo",
        +  "America/Caracas",
        +  "America/Asuncion",
        +  "America/Glace_Bay",
        +  "America/Campo_Grande",
        +  "America/Anguilla",
        +  "America/Santiago",
        +  "America/St_Johns",
        +  "America/Sao_Paulo",
        +  "America/Argentina/La_Rioja",
        +  "America/Araguaina",
        +  "America/Godthab",
        +  "America/Montevideo",
        +  "America/Bahia",
        +  "America/Noronha",
        +  "America/Scoresbysund",
        +  "Atlantic/Cape_Verde",
        +  "Africa/Casablanca",
        +  "America/Danmarkshavn",
        +  "Europe/Isle_of_Man",
        +  "Atlantic/Canary",
        +  "Africa/Abidjan",
        +  "Arctic/Longyearbyen",
        +  "Europe/Belgrade",
        +  "Africa/Ceuta",
        +  "Europe/Madrid",
        +  "Europe/Sarajevo",
        +  "Africa/Algiers",
        +  "Africa/Windhoek",
        +  "Asia/Nicosia",
        +  "Asia/Beirut",
        +  "Africa/Cairo",
        +  "Asia/Damascus",
        +  "Europe/Bucharest",
        +  "Africa/Blantyre",
        +  "Europe/Helsinki",
        +  "Europe/Istanbul",
        +  "Asia/Jerusalem",
        +  "Africa/Tripoli",
        +  "Asia/Amman",
        +  "Asia/Baghdad",
        +  "Europe/Kaliningrad",
        +  "Asia/Aden",
        +  "Africa/Addis_Ababa",
        +  "Europe/Kirov",
        +  "Europe/Astrakhan",
        +  "Asia/Tehran",
        +  "Asia/Dubai",
        +  "Asia/Baku",
        +  "Indian/Mahe",
        +  "Asia/Tbilisi",
        +  "Asia/Yerevan",
        +  "Asia/Kabul",
        +  "Antarctica/Mawson",
        +  "Asia/Yekaterinburg",
        +  "Asia/Karachi",
        +  "Asia/Kolkata",
        +  "Asia/Colombo",
        +  "Asia/Kathmandu",
        +  "Antarctica/Vostok",
        +  "Asia/Dhaka",
        +  "Asia/Rangoon",
        +  "Antarctica/Davis",
        +  "Asia/Novokuznetsk",
        +  "Asia/Hong_Kong",
        +  "Asia/Krasnoyarsk",
        +  "Asia/Brunei",
        +  "Australia/Perth",
        +  "Asia/Taipei",
        +  "Asia/Choibalsan",
        +  "Asia/Irkutsk",
        +  "Asia/Dili",
        +  "Asia/Pyongyang",
        +  "Australia/Adelaide",
        +  "Australia/Darwin",
        +  "Australia/Brisbane",
        +  "Australia/Melbourne",
        +  "Antarctica/DumontDUrville",
        +  "Australia/Currie",
        +  "Asia/Chita",
        +  "Antarctica/Macquarie",
        +  "Asia/Sakhalin",
        +  "Pacific/Auckland",
        +  "Etc/GMT-12",
        +  "Pacific/Fiji",
        +  "Asia/Anadyr",
        +  "Asia/Kamchatka",
        +  "Etc/GMT-13",
        +  "Pacific/Apia"
        +]
  10. 1 tool update
    • Addedcheck_companies
  11. 1 tool update
    • Changedprospect_picture1 field changed
      • addedInput schema / properties / audience
        Added value: +{
        +  "type": "string"
        +}
  12. 1 tool update
    • Changedfind_posts2 fields changed
      • changedInput schema / properties / budget_credits / description
        Previous value: -"Leads mode only: a spend ceiling in credits; leads beyond it come back not_processed."New value: +"Leads mode, or engagers_of with read_all: a spend ceiling in credits. Leads beyond it come back not_processed; read_all reads people up to it."
      • addedInput schema / properties / read_all
        Added value: +{
        +  "const": true,
        +  "description": "Engagers mode: read everyone who engaged, not a sample, in the background (about 2 minutes per 500 people). Needs budget_credits and idempotency_key. Returns an operation: poll get_operation, which returns the people 25 at a time with next_cursor.",
        +  "type": "boolean"
        +}

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    Remote MCP server that lets AI assistants read tracked competitive intelligence — competitor news, reviews, website changes, social posts and ads — and act on it by managing projects, competitors, battle cards, reports and canvases. Every answer carries a source and a date, and write actions only publish when explicitly shared.
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    Enables brand visibility monitoring across major AI platforms like ChatGPT, Claude, Gemini, and Perplexity. It allows users to track visibility scores, analyze competitor data, and receive actionable insights to improve AI-generated brand recommendations.
    16
    18 npm
    1
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Browse IndustryLens's published competitive-intelligence reports and head-to-head competitor comparisons from any AI agent — real, source-backed data.
    MIT
Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources