LeadMarina
Server Details
Verified local-business leads: search by niche and US city, export to Close, GoHighLevel or Sheets.
- Status
- Healthy
- Uptime
- 100.0% over 75 days
- Last Tested
- Transport
- Streamable HTTP · MCP 2025-06-18
- URL
- Repository
- macgregordev/leadmarina-mcp
- GitHub Stars
- 0
- Server Listing
- LeadMarina MCP server
TDQS
Scored across 19 tools
Most tools target a distinct resource+action (search vs advanced search vs automation vs export vs enrichment), and the descriptions explicitly route ambiguous cases (e.g. 'for many keywords or places at once, use run_advanced_search'). The main soft spots are get_search_results vs query_leads (both return leads) and list_searches vs list_advanced_searches, but the descriptions draw clear lines between them.
Every name is snake_case with a leading verb (list_/get_/create_/update_/delete_/run_/estimate_/export_/enrich_/find_/query_/control_), and noun phrases are reused consistently across resources (search, advanced_search, automation, leads). No camelCase or mixed verb-style outliers.
19 tools is on the heavy side but each maps to a real operation across several sub-domains (live search, advanced search lifecycle, automations, export destinations, enrichment, balance, views). Nothing is obviously redundant, though the surface could likely be trimmed by folding estimate_advanced_search or control_advanced_search into siblings.
Automations have full CRUD-ish lifecycle (create/update/delete/list), advanced searches have run/estimate/get/list/control, and leads have query/export/enrich plus search polling. Gaps are minor: integrations can only be listed (no connect/disconnect), saved views are read-only, and there is no way to delete a past search, but agents can work around these.
Available Tools
19 toolscontrol_advanced_searchPause, resume or stop an advanced searchBDestructiveIdempotentInspect
action pause or stop takes effect after the batches running now (a queued batch is cancelled and refunded); resume carries on.
| Name | Required | Description | Default |
|---|---|---|---|
| action | Yes | ||
| campaign_id | Yes | An id from run_advanced_search or list_advanced_searches. |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | |
| name | No | |
| leads | No | Unique leads charged so far. |
| places | No | How many places it searches. |
| status | Yes | running | paused | completed | stopped. Paused by itself when a Free account runs out of leads (they don't renew: upgrade, then resume). |
| estimate | No | { expected_leads, low, high, minutes } as estimated when it started. |
| keywords | No | Each { keyword, exact }. |
| lead_cap | No | |
| resume_at | No | When a waiting search carries on by itself. |
| created_at | No | |
| leads_with | No | How to read its leads: query_leads or export_leads with campaign_id. |
| finished_at | No | |
| finish_reason | No | all_searched | lead_limit | stopped once finished; null while it runs. |
| searches_done | No | |
| status_detail | No | One sentence on where it is — e.g. waiting for the daily city budget, and until when, or why it was paused. |
| searches_total | No | Keywords × places. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and idempotentHint=true, and the description adds genuine context beyond them: pause/stop take effect only after in-flight batches, a queued batch is cancelled and refunded, and resume continues from where it left off. This is useful mutation semantics. It still omits whether stop is irreversible and what state the search ends in.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single sentence with a parenthetical, zero waste, but the most important element — the primary statement of what the tool does — is absent, so it is under-specified rather than well-structured. The action semantics are front-loaded, but the reader must reconstruct the purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema and rich annotations, the description needn't explain returns or safety. However, for a destructive control tool it should state valid preconditions (which search states each action accepts) and whether stop is final; those gaps leave an agent guessing about error cases.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 50%: campaign_id is documented in the schema, but the action enum has no per-value descriptions. The description compensates by explaining what pause, stop (queued batch cancelled and refunded) and resume actually do, which is meaning an agent cannot get from the bare enum. It says nothing extra about campaign_id beyond the schema's own pointer.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description never states the primary action ('pause, resume or stop an advanced search'); it only explains the timing semantics of those actions, leaving the title and name to convey purpose. An agent can infer the verb+resource, but the description itself is close to a restatement of the action enum. No differentiation from siblings like run_advanced_search or get_advanced_search.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no explicit when-to-use guidance, no prerequisites (e.g. the search must be running to pause, or paused to resume), and no routing against alternatives such as run_advanced_search or get_advanced_search. Only the action enum and the phrase 'resume carries on' imply usage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_automationSchedule a recurring searchAInspect
Create an automation: re-run a search on a schedule and send the results somewhere automatically. Pass cities as plain strings (e.g. ['Austin, TX', 'Dallas, TX']) — they're resolved for you. IT SPENDS LEADS ON EVERY RUN, one per result, so confirm the niche, cities and cadence with the user before creating one. A destination of 'close', 'ghl' or 'google_sheets' requires that integration to be connected already (Close with no saved field mapping sends Close's own fields); 'csv' | 'xlsx' | 'json' emails a file and needs nothing set up. Every city must resolve and the destination must be one of the listed values, or nothing is created and the error says what to fix. Up to 20 automations, 25 cities each. Automations search US places only for now: a city outside the US is refused. Advanced search's options (a country other than the US — a territory included — max_leads, exact_category) are refused here too.
| Name | Required | Description | Default |
|---|---|---|---|
| cities | Yes | Cities to search, e.g. ['Austin, TX'] (max 25). | |
| cadence | Yes | How often it repeats. | |
| keyword | Yes | The niche to search, e.g. 'roofing contractor' — up to 100 characters. | |
| start_at | No | ISO timestamp for the first run. Defaults to now (runs on the next tick, within 15 min). | |
| destination | No | Where each run's leads go. 'none' just saves them to the library. | |
| spreadsheet_id | No | google_sheets only: add each run to this existing LeadMarina-created sheet, updating rows already in it. |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | |
| note | No | |
| cities | No | |
| cadence | No | |
| keyword | No | |
| destination | No | The destination as saved — what each run will actually use. |
| next_run_at | No | |
| data_sources | No | Where the sources, licences and notices are for emails and owner names that may come from open datasets and public records. Pass it on with any of this data you share. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare this is a non-read-only, non-idempotent, open-world write, but the description adds the crucial cost behavior the annotations cannot express: it spends one lead per result on every run, and the user should be consulted first. It also discloses hard limits (20 automations, 25 cities each), integration prerequisites per destination, and the atomic failure mode ('nothing is created and the error says what to fix').
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The core action and its purpose are front-loaded, followed by the cost warning, then prerequisites and limits. It is dense and a few clauses are long (the Advanced-search exclusion list in particular), but essentially every sentence carries operational information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 6-parameter creation tool that spends credits, this covers cost, quotas, prerequisites, failure behavior, and geographic scope, while an output schema handles return values and annotations handle the safety profile. Nothing an agent needs before calling it is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema baseline is 3. The description still adds real meaning: cities are plain strings that get resolved server-side, destination values are grouped by setup requirement (close/ghl/google_sheets need a connected integration; csv/xlsx/json just email a file), and Close falls back to its own fields when no mapping is saved. It says nothing extra about start_at, leaving that to the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb+resource pair ('Create an automation') and immediately defines what an automation is: a scheduled re-run of a search that delivers results automatically. That definition cleanly separates it from list_automations, update_automation, and delete_automation without needing the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives an explicit precondition ('confirm the niche, cities and cadence with the user before creating one') and states when the tool is not usable: US places only, and Advanced-search options like non-US countries, max_leads, or exact_category are refused. It does not explicitly compare itself to update_automation for modifying an existing automation, so it is clear context rather than full routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
delete_automationDelete an automationADestructiveIdempotentInspect
Permanently delete an automation. This cannot be undone — confirm with the user first, and prefer update_automation with active=false if they only want it to stop for now. Leads already collected by past runs are kept; only the schedule is removed.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | The automation id from list_automations. |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | |
| note | No | |
| deleted | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare destructiveHint=true and readOnlyHint=false, but the description adds substantial context: the deletion is irreversible, leads already collected are retained, and only the schedule is removed. This goes well beyond the annotations and fully discloses the operational impact.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tightly written sentences, each earning its place: the first states the action, the second adds critical safety guidance, and the third clarifies behavioral consequences. No filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter destructive mutation, the description fully covers prerequisites (confirmation), alternatives (disable instead of delete), effects (schedule removed, leads kept), and irreversibility. An output schema exists, so return-value details are not required. The description is self-sufficient.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already provides 100% coverage for the single required parameter, id, and explicitly states it comes from list_automations. The description does not add parameter-specific details, but with complete schema coverage the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Permanently delete an automation,' using a specific verb and resource while clearly distinguishing this from the sibling update_automation. It also clarifies the destructive nature, leaving no ambiguity about the tool's purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when to use this tool and when not to, recommending update_automation with active=false as a less destructive alternative for temporary suspension. It also instructs the agent to confirm with the user first, providing direct guidance for safe invocation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
enrich_domainsEnrich business domainsAInspect
Already have businesses? Pass up to 10 website domains to run the full enrichment + verification pipeline on them (verified emails + phones, owner name, socials). Costs 1 lead per distinct domain — spellings of the same site (acme.com, www.acme.com, https://acme.com/contact) count once. Returns a search_id to poll with get_search_results. US businesses only for now: their phones are read as US numbers.
| Name | Required | Description | Default |
|---|---|---|---|
| domains | Yes | Business domains, e.g. ['acme.com'] (max 10). |
Output Schema
| Name | Required | Description |
|---|---|---|
| note | No | Present when a delivered domain was listed more than once, or when the balance left some domains out (named, not charged). |
| enriching | Yes | Domains accepted (balance-capped). |
| next_step | No | |
| search_id | Yes | |
| enrichment | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations cover the safety profile (readOnlyHint=false, openWorldHint=true, idempotentHint=false, destructiveHint=false), and the description adds substantial non-obvious behavior: 1 lead charged per distinct domain, spelling-variant deduplication, US-only phone handling, and the returned search_id polling flow.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences, front-loaded with the precondition, then cost rules, then the return/polling contract. Every clause carries information; nothing is filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite an output schema, the description still supplies the essential async contract (search_id → get_search_results), covers cost and eligibility limits, and fully specifies the one input. An agent has everything needed to call and follow up correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with a single documented array parameter, so the baseline is 3. The description adds real meaning beyond the schema by explaining the max-10 limit in context and, crucially, the distinct-domain billing/dedup semantics that the schema does not convey.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource (run enrichment + verification pipeline on website domains) and lists exactly what is produced (verified emails/phones, owner name, socials). It is clearly distinguishable from siblings like search_leads and get_search_results.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The opening 'Already have businesses?' frames the precondition for using this tool instead of a search tool, and it explicitly routes the follow-up to get_search_results by name. There is no explicit when-not-to-use or named alternative for the 'I don't have domains' case, so it falls short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
estimate_advanced_searchEstimate an advanced searchARead-onlyIdempotentInspect
What an advanced search (many keywords across many places) would find and how long it would take — without starting it or spending anything. expected_leads is the most likely number of unique leads (each business is charged once however many keywords or places find it); low–high is the range it lands in most of the time.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | Optional name, up to 80 characters. | |
| places | No | Single places by name ('Austin'), 'name, region' when a name is in several ('Springfield, Illinois'), or code (find_places). Up to 25,000 regions and places together; keywords × places may come to at most 50,000 searches. | |
| country | No | 'US' (the default), or a US territory's code ('PR', 'GU', 'VI', 'AS', 'MP') with a place from find_places. | |
| regions | No | Whole US states, by name or code (find_places). | |
| keywords | Yes | What to search for: up to 20 keywords or Google categories, each up to 100 characters. Each a string, or { keyword, exact } where exact keeps only businesses whose main Google category is that one. | |
| lead_cap | No | Stop after this many unique, charged leads: a whole number from 100 to 1,000,000. Omit to search every place. | |
| everywhere | No | Every place in the US (or in the territory sent as country). |
Output Schema
| Name | Required | Description |
|---|---|---|
| low | No | |
| high | No | |
| time | No | How long it would take, waits for the daily city budget included. |
| places | No | |
| country | No | |
| keywords | No | Each { keyword, exact }, as they would run. |
| searches | Yes | Keywords × places. |
| next_step | No | |
| charged_leads | No | Leads expected to be charged: expected_leads, capped by lead_cap. |
| expected_leads | Yes | |
| paced_by_daily_budget | No | True when the account's daily city budget, not the searching, sets the time. |
| campaign_searches_per_day | No | Places a day advanced searches may use on this plan. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint and destructiveHint=false, so the safety profile is covered. The description adds genuinely new behavior: nothing is started and nothing is spent, i.e., a free preview — a cost trait annotations cannot express. It stops short of noting any rate limits or latency expectations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, the cost-free preview claim front-loaded, and the return-value semantics confined to one follow-up sentence. No filler and nothing repeated from the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present and 100% parameter coverage, the definition covers what an agent needs to call it: it is a non-executing, non-charging estimator. It could still note whether an estimate must precede run_advanced_search or how stale an estimate becomes, but nothing essential is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so every parameter is already documented, and the description adds no syntax or format detail beyond that. It does clarify the lead accounting model ("each business is charged once however many keywords or places find it"), which gives useful context for lead_cap, but that is marginal against a fully described schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Specific verb (estimate) plus resource (an advanced search), with the scope spelled out: "What an advanced search (many keywords across many places) would find and how long it would take." The clause "without starting it or spending anything" cleanly separates it from run_advanced_search and control_advanced_search.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase "without starting it or spending anything" clearly signals the when: a dry-run check before committing. However, no sibling is named explicitly — an agent has to infer that run_advanced_search is the follow-up, and there are no stated preconditions or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
export_leadsExport leads to a destinationADestructiveInspect
Push leads into a connected destination: 'close' (CRM — uses the account's saved field mapping), 'ghl' (GoHighLevel sub-account), 'google_sheets' (new spreadsheet, or pass spreadsheet_id for one LeadMarina created before), or a file — 'csv' | 'xlsx' | 'json' (a 7-day download link in the answer; not emailed). Exports EITHER one search's leads (pass search_id) or the whole library (set all=true). Either can be narrowed with the same filter rows as query_leads — with search_id they apply within that search. Leads go out best-ranked first (rank, then id), the order of the leads table. LIMITS PER CALL, which differ by destination because CRMs take one API call per lead: csv/xlsx 50,000 · json 25,000 · google_sheets 5,000 · close/ghl 1,000. For a big library going to a CRM, export csv and import the file instead. If more leads match than the limit, the response sets truncated=true and returns next_cursor — relay that to the user, the export was partial; to send the next batch, call export_leads again with the SAME destination, search_id or all, and filters, plus cursor=next_cursor — for google_sheets also spreadsheet_id from this response, or the next batch goes into a new spreadsheet (up to 50,000 leads a spreadsheet; past that the response has no spreadsheet_id and the next batch starts a new one, or export csv). A next_cursor with not_sent means the destination's time limit cut this batch short: the same call with that cursor sends the rest. An all=true export spread over several calls reads the library live, so a lead that a search running between calls finds again can be skipped or sent twice; for one consistent copy, export the library in a single csv/xlsx (up to 50,000 leads) or json (up to 25,000) call while no search is running. Close, GoHighLevel and a LeadMarina-created sheet passed as spreadsheet_id UPDATE previously exported leads in place (matched by Google CID), never touching the user's own CRM notes/columns — unless update_existing is false (then Close skips leads it already has, and a sheet appends every row); a file or a new sheet is a fresh copy every time — so do not repeat a call that succeeded. Or pass campaign_id instead of search_id to export one advanced search's leads.
| Name | Required | Description | Default |
|---|---|---|---|
| all | No | Export the whole library instead of one search. | |
| cursor | No | Continue an export: the next_cursor a previous export_leads call returned. Pass it with the same search_id/all and filters. | |
| filters | No | Optional query_leads-style filter rows: within the search when search_id is given, across the library with all=true. | |
| search_id | No | Export this search's leads. | |
| batch_size | No | Fewer leads per call than the destination allows (it only ever lowers the limit): for an export that ran out of time, as its error says. Continue with cursor as usual. | |
| campaign_id | No | Only this advanced search's leads (an id from run_advanced_search or list_advanced_searches). Not with search_id. | |
| destination | Yes | Where the leads go. | |
| sheet_title | No | google_sheets without spreadsheet_id: the new spreadsheet's title (up to 100 characters). | |
| spreadsheet_id | No | google_sheets only: add to this existing LeadMarina-created sheet instead of a new one. | |
| update_existing | No | close, and google_sheets with spreadsheet_id: true (default) refreshes leads already there. false: Close sends only leads it hasn't had yet (the rest are skipped, not duplicated); a sheet appends every lead as a new row. |
Output Schema
| Name | Required | Description |
|---|---|---|
| file | No | File exports only: the file name. |
| note | No | |
| limit | No | The per-call limit that applied, when truncated. |
| outcome | Yes | Human-readable result, e.g. added/updated counts. |
| warning | No | Present when the per-call limit or this call's time limit left leads unsent: what happened and how to send them. Leads the destination refused are not covered here — outcome counts them as failed. |
| exported | Yes | Leads sent to the destination. |
| not_sent | No | Leads of this batch the destination's time limit did not reach. |
| truncated | No | True when more leads matched than this destination's limit — the export was PARTIAL. |
| next_cursor | No | Present when the per-call limit or this call's time limit left matching leads unsent: pass it as cursor, with the same destination (for google_sheets, plus the spreadsheet_id this response returned), search_id/all and filters, to send them. It does not offer again a lead the destination refused (counted as failed in outcome). |
| data_sources | No | Where the sources, licences and notices are for emails and owner names that may come from open datasets and public records. Pass it on with any of this data you share. |
| download_url | No | File exports only: 7-day download link. |
| spreadsheet_id | No | Google Sheets only: pass it as spreadsheet_id to send the next batch into this same spreadsheet. Absent once the spreadsheet holds 50,000 leads. |
| spreadsheet_url | No | Google Sheets only: the spreadsheet the leads went to (it does not expire). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds substantial behavior beyond annotations: per-destination limits, truncation and next_cursor semantics, live-library consistency caveats for multi-call exports, and exact update-in-place behavior for Close, GoHighLevel, and existing sheets. It clarifies that the tool never touches user CRM notes/columns and explains when update_existing changes semantics. This is rich, non-contradictory context for a destructive, non-idempotent write tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The first sentence is a strong, front-loaded purpose statement, and most sentences carry operational detail that an agent needs. The description is long and dense, but the complexity of six destinations, cursor continuation, and update semantics justifies most of the length. Some grouping or bullet-style structure would improve readability.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Although an output schema exists, the description supplies the return-value semantics an agent must act on: next_cursor, truncated, not_sent, and spreadsheet_id continuation. With 10 parameters, six destinations, and destructive writes, the description covers the key decisions an agent must make before and after calling.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds meaningful semantics beyond the schema: destination-specific limits, the interaction of filters with search_id/all, cursor reuse, spreadsheet_id continuation behavior, and update_existing effects. It explains parameter behavior in operational terms that the schema alone does not.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: pushing leads into a connected destination. It enumerates all destination types and makes the export scope clear (one search vs. whole library). This is far more specific than the title and distinguishes it from read-only siblings like query_leads.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly states when to use search_id, campaign_id, or all=true, and how filters interact with each. It also gives alternatives, such as exporting CSV and importing the file for large CRM exports, and explains cursor-based continuation with exact parameters to repeat. Exclusions and edge cases (e.g., not_sent, truncation) are covered.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_placesFind US states and placesARead-onlyIdempotentInspect
Where an advanced search can run — the US and its territories for now. With no arguments: the US and its territories (Puerto Rico, Guam …), with their codes. With country 'US': its states and their codes. With q: US places whose name contains q, with their codes and states — for run_advanced_search's places, or search_leads' location_code.
| Name | Required | Description | Default |
|---|---|---|---|
| q | No | Part of a place's name, at least 2 characters. | |
| country | No | 'US', or a US territory's code ('PR', 'GU', 'VI', 'AS', 'MP'). |
Output Schema
| Name | Required | Description |
|---|---|---|
| places | No | With country 'US' alone: how many places it has. With q: the matches, each { code, name, region } (up to 50). |
| region | No | With country 'US' alone: what its regions are called (state). |
| country | No | |
| regions | No | With country 'US' alone: each state, { code, name, places }. |
| countries | No | With no arguments: the US and its territories, each { code, name, region, places }. |
| total_matching | No | With q: every match, of which up to 50 are listed. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, non-destructive, closed-world, so the safety profile is covered. The description still adds a real behavioral constraint — coverage is limited to the US and territories 'for now' — plus what each input shape returns, which is context the annotations cannot supply.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The scoping statement is front-loaded and the three modes are laid out in a compact parallel structure with no filler. It is telegraphic to the point that the 'With country' / 'With q' clauses read as fragments, but every sentence carries information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, the description doesn't need to explain return shapes, and it still names the key returned fields (codes, states). All input modes are addressed; the one gap is the unspecified behavior for a territory code passed as `country`.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description goes further by tying each parameter to a distinct result set (country='US' → states; q → name substring matches with states). The only unexplained case is what a territory code like 'PR' returns under `country`, which keeps it from a 5.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states the specific resource — the places/codes an advanced search can run against — and explicitly scopes it to the US and its territories, which separates it from the list_*/search_* siblings. The verb 'find' is only implicit, but the phrase 'with their codes' makes the returned entity unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It enumerates every invocation mode and what each selects: no args → countries/territories, country='US' → states, q → matching places. It also routes the output to the exact consumers ('run_advanced_search's places, or search_leads' location_code'), so the agent knows both when to call it and where the result goes.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_advanced_searchGet an advanced searchBRead-onlyIdempotentInspect
One advanced search: status, leads so far, progress by keyword, its top places and the newest batch running now.
| Name | Required | Description | Default |
|---|---|---|---|
| campaign_id | Yes | An id from run_advanced_search or list_advanced_searches. |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | |
| name | No | |
| leads | No | Unique leads charged so far. |
| places | No | How many places it searches. |
| status | Yes | running | paused | completed | stopped. Paused by itself when a Free account runs out of leads (they don't renew: upgrade, then resume). |
| estimate | No | { expected_leads, low, high, minutes } as estimated when it started. |
| keywords | No | Each { keyword, exact }. |
| lead_cap | No | |
| resume_at | No | When a waiting search carries on by itself. |
| by_keyword | No | Each { keyword, exact, category, searches, searches_done, leads }. |
| created_at | No | |
| leads_with | No | How to read its leads: query_leads or export_leads with campaign_id. |
| top_places | No | Each { place, leads, basis }: basis "leads" — leads delivered there; or basis "businesses_checked" — leads null and businesses_checked the businesses checked there, when leads per place are not known. |
| finished_at | No | |
| running_now | No | The newest batch running now: { keyword, places, status, verified, of } — places is the batch's place names. |
| finish_reason | No | all_searched | lead_limit | stopped once finished; null while it runs. |
| searches_done | No | |
| status_detail | No | One sentence on where it is — e.g. waiting for the daily city budget, and until when, or why it was paused. |
| searches_total | No | Keywords × places. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false and openWorldHint=false, so the safety profile is fully covered. The description adds the shape of the payload (status, progress, top places, newest running batch), which is genuinely useful context, but because a full output schema exists it largely restates structured data rather than disclosing behavior beyond it.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One short sentence with no filler, and the key scoping word 'One' and the payload contents are front-loaded. The telegraphic, verbless phrasing means it reads more like a caption than a definition, which keeps it just short of a 5.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only single-record fetch, the description plus the 100%-covered single parameter, rich annotations and an output schema give the agent nearly everything needed to call it correctly. The missing piece is routing information versus the sibling list/search tools.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There is a single parameter with 100% schema description coverage, and the schema already explains where the campaign_id comes from. The description adds no further meaning about the id format, resolution, or error behavior, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description enumerates what is returned ('status, leads so far, progress by keyword, its top places and the newest batch') for a single advanced search, and the word 'One' implicitly distinguishes it from list_advanced_searches. However, there is no verb and no explicit statement that it retrieves a single search by id; the agent must infer that from the tool name and title alone.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to call this versus list_advanced_searches or get_search_results. The only reference to siblings appears in the schema's campaign_id description ('An id from run_advanced_search or list_advanced_searches'), which explains id provenance rather than tool selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_balanceGet lead balanceARead-onlyInspect
What the account has left, and when it resets. On a plan with a rate limit (no monthly quota) this is the leads left in the current 7-day period; on a metered plan it is the monthly allotment remaining.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| note | No | |
| plan | Yes | |
| period_used | No | |
| period_limit | No | |
| leads_remaining | Yes | |
| period_resets_at | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint=true and destructiveHint=false. The description adds valuable context: it explains the reset behavior and how balance differs by plan type, going beyond the binary annotations. No contradiction; it enriches understanding of the tool's output.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tightly worded sentences, with the core purpose ('what the account has left, and when it resets') front-loaded. The second sentence clarifies plan-specific nuances without redundancy. No wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no parameters and an output schema available, the description fully covers what the tool does and how to interpret the result. It clarifies reset timing and plan distinctions, leaving no ambiguity about the return value's meaning.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so baseline is 4 per rubric. The description adds no parameter details because none exist, but it effectively explains what the returned value represents, which is more relevant than parameter semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: reporting remaining lead balance and reset timing. It distinguishes between rate-limited (7-day period) and metered (monthly) plans, providing specificity beyond the title. No sibling tool covers balance queries, so it stands apart.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage: check balance to know remaining leads before operations. It does not explicitly contrast with alternatives, but given the sibling list contains no similar tools, that omission is acceptable. It clearly explains when the value applies (current period) without needing exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_search_resultsGet search resultsARead-onlyInspect
Fetch a search's leads with verification filled in as enrichment progresses. Poll until enrichment is 'complete'. Each lead includes verified emails (SMTP status), verified phones (line type + carrier), owner name where identified, socials, and the business profile.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Max leads to return (default 25, max 1000). | |
| offset | No | Pagination offset (default 0). | |
| search_id | Yes | The search_id returned by search_leads or enrich_domains. |
Output Schema
| Name | Required | Description |
|---|---|---|
| query | No | |
| stage | No | queued | discovering | enriching | verifying | complete | failed | cancelled. 'verifying' means every row is delivered and contacts are being verified — often the longest phase, not a stall. |
| period | No | On a rate-limited plan: { limit, used, resets_at }. Null on a metered plan. |
| results | Yes | |
| showing | No | Range shown, e.g. '1–25'. |
| location | No | |
| progress | No | { done, total } rows enriched so far. |
| search_id | Yes | |
| enrichment | Yes | 'pending' or 'complete'. |
| next_offset | No | Pass as offset to fetch the next page; null on the last page. |
| total_leads | Yes | |
| data_sources | No | Where the sources, licences and notices are for emails and owner names that may come from open datasets and public records. Pass it on with any of this data you share. |
| queue_position | No | For queued searches, the place in this account's own queue (1 = next). |
| leads_remaining | No | Leads spendable now. On a plan with no monthly quota this is what is left in the current 7-day period, not a monthly balance. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly, non-destructive, closed-world), but the description adds the non-obvious behavioral trait that results are asynchronous and progressively enriched, which drives polling. It also enumerates what each lead carries; that partially overlaps the output schema but the polling semantics are real added value.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three compact sentences, front-loaded with the core action and the polling rule right after. Minor redundancy in listing lead fields that the output schema already exposes, but nothing is wasted overall.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, the description does not need to detail return values, and annotations cover safety. It closes the main gap an agent would face—that results arrive asynchronously and require polling—though it stops short of stating pagination or completion-latency expectations.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so limit, offset, and search_id are already documented with defaults and ranges. The description adds nothing about parameter meaning or interaction (e.g. how pagination relates to the enrichment status), so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (fetch) and resource (a search's leads) plus the enrichment-fill behavior, which is more precise than the generic title. It implies results come from a search created elsewhere but never names the sibling tools (search_leads, query_leads, list_searches) that an agent might otherwise pick.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The instruction 'Poll until enrichment is complete' is a genuine usage cue about when to call this tool repeatedly. However, it gives no guidance on when to prefer this over query_leads, export_leads, or list_searches, so differentiation from the sibling set is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_advanced_searchesList advanced searchesBRead-onlyIdempotentInspect
This account's advanced searches, newest first: status, leads so far, searches done of total.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Up to 100; 25 by default. |
Output Schema
| Name | Required | Description |
|---|---|---|
| advanced_searches | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish read-only, idempotent, non-destructive behavior, so the description's main added value is ordering ('newest first') and a partial return-field preview. It does not explain pagination behavior beyond the schema's limit field or any other operational context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single compact fragment with no wasted words, and the ordering and return-field preview are front-loaded. It is efficient, though the sentence-fragment style is slightly terse.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, the description needn't explain return values in full, and annotations cover the safety profile. It is nearly complete for a simple one-parameter list tool, though it could mention sibling alternatives or pagination expectations.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and the single limit parameter is already documented in the schema. The description adds no further meaning about limit behavior, so the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies the resource (this account's advanced searches) and implies a list operation, plus it previews key return fields. It does not distinguish the tool from siblings like get_advanced_search or list_searches, which keeps it from a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It provides no explicit guidance on when to use this tool versus get_advanced_search, list_searches, or other search-related siblings. The list intent is implied by 'newest first' and the resource name, but no alternatives or exclusions are given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_automationsList scheduled searchesARead-onlyInspect
The account's automations — saved searches that re-run on a schedule and export themselves. Shows each one's niche, cities, cadence, destination, whether it's active, when it next runs, and how the last run went.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| count | Yes | |
| automations | Yes | |
| data_sources | No | Where the sources, licences and notices are for emails and owner names that may come from open datasets and public records. Pass it on with any of this data you share. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false and a closed world, so the safety profile is covered. The description adds a useful conceptual framing of what an automation is, but says nothing about pagination, result limits, or ordering that a listing caller might need.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two front-loaded sentences with no filler. The second sentence enumerates return fields, which partly duplicates the output schema, but it works as a quick orientation rather than padding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present and zero parameters, the description does not need to explain return values, and the safety profile is carried by annotations. Only the missing routing guidance against siblings keeps it from being fully complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so the baseline of 4 applies; there is nothing for the description to clarify or compensate for.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific resource and defines it: 'the account's automations — saved searches that re-run on a schedule and export themselves.' That definition is what separates it from the sibling list_searches, which lists plain saved searches without scheduling or export behavior.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance at all. It never says this is the way to discover automation IDs before calling update_automation or delete_automation, nor does it exclude any scenario, so the agent must infer routing from the name alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_integrationsList connected integrationsARead-onlyInspect
Which export destinations this account has connected (Close, GoHighLevel, Google Sheets) and whether each is ready to receive leads. Check this BEFORE export_leads or create_automation with a CRM destination — those fail if the integration isn't connected. Close with no saved field mapping sends Close's own fields (name, website, address, contact, phone, email). File destinations (csv/xlsx/json) always work and need nothing connected.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| integrations | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, openWorldHint=false and destructiveHint=false, so safety is covered; the description adds the operational prerequisite chain and the default Close field-mapping behavior (name, website, address, contact, phone, email) that determines readiness. The field-mapping sentence leans toward explaining export_leads rather than this tool, which slightly dilutes focus, but it does help interpret what "ready" means.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, each doing distinct work: what is returned, when to call it and why, and the caveat that file exports bypass the check. The prerequisite warning is front-loaded before the edge-case detail.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no parameters, a documented output schema, and full annotation coverage, the remaining burden is explaining call timing and failure conditions — both are covered explicitly. Nothing an agent needs to invoke this correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Zero-parameter tool, so the baseline is 4 and there is nothing for the description to disambiguate. The absence of arguments is implicitly conveyed by the description scoping everything to "this account".
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific resource (connected export destinations) and scope (Close, GoHighLevel, Google Sheets) plus what is reported for each (whether it is ready to receive leads). This is far more specific than the title and cannot be confused with any sibling tool, which all deal with searches, leads, or automations rather than connection state.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit timing ("Check this BEFORE export_leads or create_automation with a CRM destination") and names the exact failure mode those calls hit. It also states the exclusion — file destinations need nothing connected — so the agent knows when to skip the call entirely.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_searchesList recent searchesARead-onlyInspect
The account's recent searches (id, niche, location, result count, when) — use a search_id with get_search_results or export_leads.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Max searches (default 10, max 25). |
Output Schema
| Name | Required | Description |
|---|---|---|
| searches | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, covering the safety profile. The description adds value beyond this by clarifying account scoping ('the account's recent searches'), listing the return fields, and indicating how the results should be used downstream, which are behaviors not captured by the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence that front-loads the main purpose and returned fields, followed by a concise usage clause. Every word contributes useful information with no redundancy or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity (one optional parameter, existing output schema, read-only annotations), the description provides all essential context: what it returns, account scope, and how the results connect to sibling tools. This is fully complete for the tool's complexity level.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema provides 100% coverage for the single 'limit' parameter, including its default (10) and max (25) values. The description does not repeat or extend the parameter semantics, so it adds no extra meaning beyond what the schema already offers.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('List recent searches') and the resource ('account's recent searches'), and enumerates the returned fields (id, niche, location, result count, when). It differentiates from sibling tools by explicitly mentioning that search_ids from this tool are used with get_search_results or export_leads, making its role distinct.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the usage context by explaining that the search_id obtained from this tool is used with get_search_results or export_leads, which positions list_searches as the entry point for those operations. It does not provide explicit exclusions or alternative scenarios, but the guidance is clear and helpful for an agent deciding when to call it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_viewsList saved viewsARead-onlyInspect
The account's saved views from the leads table — each a named set of filters the user already built (e.g. 'Roofers with a mobile number'). Returns each view's filter conditions in the exact shape query_leads and export_leads accept, so "export my Hot Leads view to Close" works without rebuilding the filters by hand.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| count | Yes | |
| views | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is well covered. The description adds valuable behavioral context by stating the output format is compatible with query_leads and export_leads, and clarifies that views are user-defined named filters. This goes beyond the annotations and helps the agent understand the data and its reuse. No contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise, consisting of two sentences. It front-loads the purpose, provides an example, and explains the key integration point without unnecessary elaboration. Every sentence contributes meaning and earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no parameters, an existing output schema, and read-only annotations, the description covers all essential aspects: what is listed, the format compatibility, and the practical use case. It does not discuss pagination or limits, but these are likely in the output schema. Overall, it is complete for a simple list tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so the description correctly focuses on output rather than inputs. Schema description coverage is 100% by default, and the description adds no parameter details because none are needed. The baseline of 4 is appropriate for tools with no parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states that the tool lists the account's saved views from the leads table, each being a named set of filters, with a concrete example ('Roofers with a mobile number'). This distinguishes it from sibling tools like list_searches by specifying 'saved views' as the resource. The verb 'list' is unambiguous and directly matches the title.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains that the returned filter conditions are in the exact shape query_leads and export_leads accept, implying this tool is used to retrieve saved views before querying or exporting them. It does not explicitly state when not to use it or compare it to alternatives, but the context makes the primary use case clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
query_leadsQuery the lead libraryARead-onlyInspect
Search ALL leads the account has ever collected (across every search) with filters and sorting — no new search is run and no leads are spent. A Google listing found more than once appears once, with its most recent data. Up to 1,000 leads per call (default 25). When next_cursor is set, call again with cursor = next_cursor for the next page: the cursor carries its filters and sort, so it can be sent alone. Pass search_id to query one search's leads instead of the whole library. Example — plumbers in Austin rated 4.5 or higher with a safe email, most-reviewed first: filters=[{field:'category',operator:'contains',value:'plumb'},{field:'city',operator:'is',value:'Austin',conj:'and'},{field:'rating',operator:'gte',value:'4.5',conj:'and'},{field:'email_status',operator:'is',value:'safe',conj:'and'}], sort=[{id:'reviews',dir:-1}]. A field, operator or value the tool cannot use comes back as an error that names it and lists what works. Pass campaign_id instead of search_id to query one advanced search's leads.
| Name | Required | Description | Default |
|---|---|---|---|
| sort | No | Sort keys in priority order, e.g. [{id:'reviews',dir:-1}] for most-reviewed first. id is any filter field id (the column ids email_1, email_1_status, phone_1, phone_1_type and phone_1_carrier work too); dir is 1 ascending (the default) or -1 descending. A lead with no value for a key (null) sorts after the leads that have one, in either direction — except social_facebook, social_instagram, social_linkedin, social_x, social_youtube, social_tiktok, social_yelp, gbp_url, logo_url, main_image_url, which sort by whether a lead has one, not by the link: ascending puts the leads WITHOUT one first, so use dir -1 to put the leads that have one first. Without a sort the order is arbitrary but stable. | |
| limit | No | Max leads to return (default 25, max 1,000). | |
| cursor | No | next_cursor from the previous call, for the next page. It carries that call's filters and sort: send it alone, or with the same filters and sort — different ones are refused. Leave it out to start a new query. | |
| filters | No | Conditions, each {field, operator, value, conj}; omit to match every lead. text fields [operators: contains, not_contains, is, is_not, is_empty, is_not_empty]: name, category, city, state, country, postal_code, address, website, primary_email (or email_1), email_2, email_3, primary_phone (or phone_1), phone_carrier (or phone_1_carrier), phone_2, phone_2_carrier, phone_3, phone_3_carrier, owner_name, contact_name, contact_title, social_facebook, social_instagram, social_linkedin, social_x, social_youtube, social_tiktok, social_yelp, gbp_url, google_cid, logo_url, main_image_url. number fields [operators: eq, neq, gt, gte, lt, lte, is_empty, is_not_empty]: rank, rating, reviews, people. yes/no fields [operators: is_true, is_false, is_empty, is_not_empty]: claimed. choice fields [operators: is, is_not, is_empty, is_not_empty]: website_status take none (No website), live, unreachable, blocked (Blocked our crawler), unknown, pending; email_status (or email_1_status), email_2_status, email_3_status take safe, risky, invalid, unknown; phone_line_type (or phone_1_type), phone_2_type, phone_3_type take mobile, fixed_line (Landline), fixed_line_or_mobile (Landline or mobile), voip, non_fixed_voip, toll_free (Toll-free), premium_rate, shared_cost, personal_number (Personal), pager, uan, voicemail, unknown. value is one string (a number as text, e.g. '4.5'); is_empty, is_not_empty, is_true and is_false take none. Text matching ignores case. Phone fields compare digits, so '(512) 555' finds +15125550100; website is / is_not compare domains when given a domain ('acme.com', or 'https://www.acme.com/'), and whole addresses when given a path, a query or a fragment ('acme.com/locations/austin'), either way ignoring http(s)://, www. and a closing slash. conj ('and' or 'or') joins a condition to the one before it, and 'and' binds tighter: A and B or C means (A and B) or C. To match any of several values, send one condition per value joined with conj 'or', repeating the other conditions in each group. | |
| search_id | No | Only this search's leads (a search_id from search_leads or list_searches) — e.g. to narrow one search before export_leads with the same search_id and filters. Omit to query the whole library. | |
| campaign_id | No | Only this advanced search's leads (an id from run_advanced_search or list_advanced_searches). Not with search_id. |
Output Schema
| Name | Required | Description |
|---|---|---|
| results | Yes | |
| returned | Yes | |
| next_cursor | No | Pass back as 'cursor' for the next page (it carries the filters and sort); null on the last page. |
| data_sources | No | Where the sources, licences and notices are for emails and owner names that may come from open datasets and public records. Pass it on with any of this data you share. |
| total_matching | No | Exact match count — on the first page only; null on later pages. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/non-destructive/closed-world, but the description adds genuinely non-obvious behavior: no credits are spent, duplicate listings collapse to the most recent record, pagination is cursor-based with the cursor carrying its own filters and sort (and mismatched filters being refused), and invalid field/operator/value combos return a self-describing error. That is real operational context beyond the annotation set.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the differentiator and the pagination rule before any detail, and the example is compact. Minor weakness: the campaign_id clause is stranded at the very end after the error-handling sentence, breaking the otherwise logical flow of the search_id/campaign_id scoping discussion.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a six-parameter, zero-required query tool with a full output schema, everything an agent needs is present: scope, cost, dedup semantics, page size, cursor reuse rules, scoping by search or campaign, and error recovery. Nothing material is left to inference.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3; the description earns above baseline by supplying a concrete filter example (plumbers in Austin, rating >= 4.5, safe email, sorted by reviews desc) that shows how the nested objects compose, plus the default-25 / 1,000-cap behavior. It does not restate the operator taxonomies, which the schema already handles well, so it stops short of 5.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ("Search ALL leads the account has ever collected") and immediately scopes it against the obvious alternative: "no new search is run and no leads are spent," which is exactly what distinguishes it from search_leads. The dedup rule ("a Google listing found more than once appears once, with its most recent data") further pins down what the result set actually is.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit routing conditions: use this to query the existing library, pass search_id for one search, campaign_id for one advanced search, and it names the sibling that produces those ids (search_leads, list_searches, run_advanced_search, list_advanced_searches) as well as export_leads. The exclusion "Not with search_id" is stated in the schema and implied by "instead of search_id" in the description.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
run_advanced_searchRun an advanced searchAInspect
Start an advanced search: many keywords across many US places — the whole US, whole states or single places — run in the background in batches, each business charged once (1 lead), stopping at lead_cap if set. Estimate first with estimate_advanced_search and confirm with the user: it spends leads. Follow it with get_advanced_search; read its leads with query_leads or send them with export_leads (campaign_id). Up to 25 running or paused at once, and 40 new ones (or 250,000 searches) a day.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | Optional name, up to 80 characters. | |
| places | No | Single places by name ('Austin'), 'name, region' when a name is in several ('Springfield, Illinois'), or code (find_places). Up to 25,000 regions and places together; keywords × places may come to at most 50,000 searches. | |
| country | No | 'US' (the default), or a US territory's code ('PR', 'GU', 'VI', 'AS', 'MP') with a place from find_places. | |
| regions | No | Whole US states, by name or code (find_places). | |
| keywords | Yes | What to search for: up to 20 keywords or Google categories, each up to 100 characters. Each a string, or { keyword, exact } where exact keeps only businesses whose main Google category is that one. | |
| lead_cap | No | Stop after this many unique, charged leads: a whole number from 100 to 1,000,000. Omit to search every place. | |
| everywhere | No | Every place in the US (or in the territory sent as country). |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | No | |
| name | No | |
| leads | No | Unique leads charged so far. |
| places | No | How many places it searches. |
| status | No | running | paused | completed | stopped. Paused by itself when a Free account runs out of leads (they don't renew: upgrade, then resume). |
| estimate | No | { expected_leads, low, high, minutes } as estimated when it started. |
| keywords | No | Each { keyword, exact }. |
| lead_cap | No | |
| next_step | No | |
| resume_at | No | When a waiting search carries on by itself. |
| by_keyword | No | Each { keyword, exact, category, searches, searches_done, leads }. |
| created_at | No | |
| leads_with | No | How to read its leads: query_leads or export_leads with campaign_id. |
| top_places | No | Each { place, leads, basis }: basis "leads" — leads delivered there; or basis "businesses_checked" — leads null and businesses_checked the businesses checked there, when leads per place are not known. |
| campaign_id | Yes | |
| finished_at | No | |
| running_now | No | The newest batch running now: { keyword, places, status, verified, of } — places is the batch's place names. |
| finish_reason | No | all_searched | lead_limit | stopped once finished; null while it runs. |
| searches_done | No | |
| status_detail | No | One sentence on where it is — e.g. waiting for the daily city budget, and until when, or why it was paused. |
| searches_total | No | Keywords × places. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only say it is a non-idempotent write with open-world scope; the description adds the material traits: it runs in the background in batches, each business is charged once (1 lead), spending stops at lead_cap, and it requires user confirmation before spending. It also discloses hard concurrency and daily quota limits (25 running/paused, 40 new or 250,000 searches a day), which is exactly the operational context an agent cannot get from the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads what the tool does, then cost/confirmation, then chaining, then rate limits — dense but ordered by decision importance. Every clause carries a fact (cost, cap, quota) rather than filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a costly, non-idempotent, open-world mutation with an output schema already defined, the description covers everything an agent needs before invoking: cost model, confirmation requirement, prerequisite estimator, downstream retrieval tools, and throttling limits.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all seven parameters including lead_cap ranges and the keywords × places cap are already documented. The description reinforces the geographic trichotomy (whole US / whole states / single places) and the lead_cap stop rule, but adds no value beyond what the structured schema already states — baseline 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ("Start an advanced search") and immediately scopes it as "many keywords across many US places — the whole US, whole states or single places," which separates it from single-query siblings like search_leads and from the non-mutating estimate_advanced_search.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit pre-call workflow ("Estimate first with estimate_advanced_search and confirm with the user: it spends leads") and an explicit post-call path ("Follow it with get_advanced_search; read its leads with query_leads or send them with export_leads (campaign_id)"). It names the alternatives and the condition that selects each, leaving nothing to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_leadsSearch local-business leadsAInspect
Run a live search for local businesses by niche + city (e.g. query 'electrician', location 'Austin, TX'). Returns a search_id and, usually, the first batch immediately (its listings are in results; their emails and phones are not verified yet — when discovery is 'in_progress' the provider was slow and the whole search was queued, so the leads arrive through get_search_results); more results are found and verified in the background — every email is SMTP-checked and phones are verified with line type + carrier. Spends 1 lead per result. Poll get_search_results until enrichment is 'complete'. If enrichment is already 'complete', nothing was found and nothing more is coming; if capped is true, the balance covered fewer leads than were found. With country, a US territory (PR, GU, VI, AS, MP) is searched; max_leads stops it early and exact_category keeps only that Google category. For many keywords or places at once, use run_advanced_search.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | Business niche/category keyword, e.g. 'electrician'. | |
| country | No | 'US' (the default), or a US territory's code ('PR', 'GU', 'VI', 'AS', 'MP') with a place from find_places. | |
| location | No | City, e.g. 'Austin, TX'. Not needed with location_code, which is always what is searched. | |
| max_leads | No | Stop after this many leads: a whole number from 100 to 1,000,000. | |
| location_code | No | Optional exact location code. When given, it is what is searched, whatever location says. Sent with location, the search is named after the code's own place (or after location when the code's own name cannot be looked up); sent alone, the search is unnamed and location comes back null. A code for a place outside the US is refused, as is a location ending in another country ('London, UK'). | |
| exact_category | No | Only businesses whose MAIN Google category is the query's: true (the query must be a Google category, e.g. 'Plumber'), or the category's id. Runs in the background — results arrive through get_search_results. |
Output Schema
| Name | Required | Description |
|---|---|---|
| found | No | Listings found in the first batch, before the balance capped delivery. |
| query | Yes | |
| capped | No | True when the lead balance covered fewer leads than were found — relay this to the user. |
| results | No | The first batch, as delivered — contacts are verified in the background (get_search_results). |
| location | No | The place searched, as the location list names it (the location sent, when a code's own name could not be looked up); null for a location_code sent alone. |
| discovery | No | 'complete', or 'in_progress' when the search was queued whole. |
| next_step | No | |
| search_id | Yes | |
| enrichment | Yes | 'pending' until background verification finishes; 'complete' at once when nothing was found. |
| data_sources | No | Where the sources, licences and notices are for emails and owner names that may come from open datasets and public records. Pass it on with any of this data you share. |
| leads_remaining | No | Leads spendable now. On a plan with no monthly quota this is what is left in the current 7-day period. |
| delivered_so_far | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=false and openWorldHint=true, and the description adds far more: 1 lead spent per result, background enrichment with SMTP email checks and phone line-type/carrier verification, the queued 'in_progress' discovery path, and what `capped` means. This is exactly the cost/async/side-effect context an agent needs before a metered call.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core action and return shape, and essentially every clause carries real information. The long em-dash-chained sentences make it denser than ideal to parse, which keeps it from a 5.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Output schema exists, yet the description still explains the tricky return semantics an agent can't infer: `search_id` plus immediate `results` with unverified contacts, enrichment lifecycle, and `capped`. Combined with annotations and a full schema, nothing needed to invoke or follow up is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds cross-parameter behavior beyond the schema: territory search with `country`, `max_leads` stopping early, and `exact_category` restricting to the query's Google category while running in the background. It stops short of restating formats (e.g. code ranges) already in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Run a live search for local businesses by niche + city') and grounds it with a concrete example query/location. It is clearly distinguishable from run_advanced_search, which it calls out by name for multi-keyword/multi-place work.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says to poll get_search_results until enrichment is 'complete', points to find_places for territory place codes, and routes the agent to run_advanced_search for many keywords or places. It also states the degenerate case ('if enrichment is already complete, nothing was found').
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_automationPause or resume an automationAIdempotentInspect
Pause an automation (active=false) so it stops running and stops spending leads, or resume it (active=true). Pausing is the safe way to stop an automation you might want back — use delete_automation only when the user wants it gone for good.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | The automation id from list_automations. | |
| active | Yes | false to pause, true to resume. |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | |
| note | No | |
| active | Yes | |
| data_sources | No | Where the sources, licences and notices are for emails and owner names that may come from open datasets and public records. Pass it on with any of this data you share. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, destructiveHint=false and idempotentHint=true, so the safety profile is covered. The description adds real behavioral context beyond that: pausing stops the automation from running and from spending leads, and is framed as the reversible option. It does not discuss auth requirements or what happens to in-flight leads, keeping it short of a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, zero filler, and the primary behavior plus the cost consequence are front-loaded ahead of the alternative-tool guidance.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need no explanation. For a two-parameter state-toggle with clear safety annotations, the description covers purpose, the consequence of the action, and routing to the destructive sibling.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and both parameters are documented in-schema (id source, true/false meaning). The description's restatement of active=false/true adds emphasis but no new syntax or format detail beyond the schema, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (pause/resume) on a specific resource (automation), and pins each state to its parameter value (active=false / active=true). It is immediately distinguishable from delete_automation, the other mutating sibling.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly names the alternative and the condition that selects it: pause is for automations you might want back, delete_automation only when the user wants it gone for good. This is a genuine when-to-use / when-not-to-use rule, not an inference.
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 tool update
- Changed
export_leads1 field changed- added
Input schema / properties / batch_sizeAdded value: +{ + "description": "Fewer leads per call than the destination allows (it only ever lowers the limit): for an export that ran out of time, as its error says. Continue with cursor as usual.", + "minimum": 1, + "type": "integer" +}
1 tool update
- Changed
create_automation2 fields changed- changed
Input schema / properties / keyword / descriptionPrevious value: -"The niche to search, e.g. 'roofing contractor'."New value: +"The niche to search, e.g. 'roofing contractor' — up to 100 characters." - added
Input schema / properties / keyword / maxLengthAdded value: +100
2 tool updates
- Changed
get_advanced_search1 field changed- changed
Output schema / properties / running_now / descriptionPrevious value: -"The newest batch running now: { keyword, places, status, verified, of }."New value: +"The newest batch running now: { keyword, places, status, verified, of } — places is the batch's place names."
- Changed
run_advanced_search1 field changed- changed
Output schema / properties / running_now / descriptionPrevious value: -"The newest batch running now: { keyword, places, status, verified, of }."New value: +"The newest batch running now: { keyword, places, status, verified, of } — places is the batch's place names."
1 tool update
- Changed
export_leads2 fields changed- changed
Output schema / properties / next_cursor / descriptionPrevious value: -"Present when the per-call limit or this call's time limit left matching leads unsent: pass it as cursor, with the same destination, search_id/all and filters, to send them. It does not offer again a lead the destination refused (counted as failed in outcome)."New value: +"Present when the per-call limit or this call's time limit left matching leads unsent: pass it as cursor, with the same destination (for google_sheets, plus the spreadsheet_id this response returned), search_id/all and filters, to send them. It does not offer again a lead the destination refused (counted as failed in outcome)." - added
Output schema / properties / spreadsheet_idAdded value: +{ + "description": "Google Sheets only: pass it as spreadsheet_id to send the next batch into this same spreadsheet. Absent once the spreadsheet holds 50,000 leads.", + "type": "string" +}
1 tool update
- Changed
export_leads2 fields changed- added
Input schema / properties / sheet_titleAdded value: +{ + "description": "google_sheets without spreadsheet_id: the new spreadsheet's title (up to 100 characters).", + "type": "string" +} - added
Input schema / properties / update_existingAdded value: +{ + "description": "close, and google_sheets with spreadsheet_id: true (default) refreshes leads already there. false: Close sends only leads it hasn't had yet (the rest are skipped, not duplicated); a sheet appends every lead as a new row.", + "type": "boolean" +}
1 tool update
- Changed
export_leads1 field changed- added
Output schema / properties / spreadsheet_urlAdded value: +{ + "description": "Google Sheets only: the spreadsheet the leads went to (it does not expire).", + "type": "string" +}
9 tool updates
- Added
control_advanced_search - Added
estimate_advanced_search - Changed
export_leads1 field changed- added
Input schema / properties / campaign_idAdded value: +{ + "description": "Only this advanced search's leads (an id from run_advanced_search or list_advanced_searches). Not with search_id.", + "type": "string" +}
- Added
find_places - Added
get_advanced_search - Added
list_advanced_searches - Changed
query_leads1 field changed- added
Input schema / properties / campaign_idAdded value: +{ + "description": "Only this advanced search's leads (an id from run_advanced_search or list_advanced_searches). Not with search_id.", + "type": "string" +}
- Added
run_advanced_search - Changed
search_leads3 fields changed- added
Input schema / properties / countryAdded value: +{ + "description": "'US' (the default), or a US territory's code ('PR', 'GU', 'VI', 'AS', 'MP') with a place from find_places.", + "type": "string" +} - added
Input schema / properties / exact_categoryAdded value: +{ + "description": "Only businesses whose MAIN Google category is the query's: true (the query must be a Google category, e.g. 'Plumber'), or the category's id. Runs in the background — results arrive through get_search_results.", + "type": [ + "boolean", + "string" + ] +} - added
Input schema / properties / max_leadsAdded value: +{ + "description": "Stop after this many leads: a whole number from 100 to 1,000,000.", + "type": "number" +}
3 tool updates
- Changed
get_search_results2 fields changed- added
Output schema / properties / results / items / properties / countryAdded value: +{ + "description": "ISO 3166 alpha-2 (\"US\", \"GB\").", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / results / items / properties / postal_codeAdded value: +{ + "type": [ + "string", + "null" + ] +}
- Changed
query_leads3 fields changed- changed
Input schema / properties / filters / descriptionPrevious value: -"Conditions, each {field, operator, value, conj}; omit to match every lead. text fields [operators: contains, not_contains, is, is_not, is_empty, is_not_empty]: name, category, city, state, address, website, primary_email (or email_1), email_2, email_3, primary_phone (or phone_1), phone_carrier (or phone_1_carrier), phone_2, phone_2_carrier, phone_3, phone_3_carrier, owner_name, social_facebook, social_instagram, social_linkedin, social_x, social_youtube, social_tiktok, social_yelp, gbp_url, google_cid, logo_url, main_image_url. number fields [operators: eq, neq, gt, gte, lt, lte, is_empty, is_not_empty]: rank, rating, reviews. yes/no fields [operators: is_true, is_false, is_empty, is_not_empty]: claimed. choice fields [operators: is, is_not, is_empty, is_not_empty]: email_status (or email_1_status), email_2_status, email_3_status take safe, risky, invalid, unknown; phone_line_type (or phone_1_type), phone_2_type, phone_3_type take mobile, fixed_line (Landline), fixed_line_or_mobile (Landline or mobile), voip, non_fixed_voip, toll_free (Toll-free), premium_rate, shared_cost, personal_number (Personal), pager, uan, voicemail, unknown. value is one string (a number as text, e.g. '4.5'); is_empty, is_not_empty, is_true and is_false take none. Text matching ignores case. Phone fields compare digits, so '(512) 555' finds +15125550100; website is / is_not compare domains when given a domain ('acme.com', or 'https://www.acme.com/'), and whole addresses when given a path, a query or a fragment ('acme.com/locations/austin'), either way ignoring http(s)://, www. and a closing slash. conj ('and' or 'or') joins a condition to the one before it, and 'and' binds tighter: A and B or C means (A and B) or C. To match any of several values, send one condition per value joined with conj 'or', repeating the other conditions in each group."New value: +"Conditions, each {field, operator, value, conj}; omit to match every lead. text fields [operators: contains, not_contains, is, is_not, is_empty, is_not_empty]: name, category, city, state, country, postal_code, address, website, primary_email (or email_1), email_2, email_3, primary_phone (or phone_1), phone_carrier (or phone_1_carrier), phone_2, phone_2_carrier, phone_3, phone_3_carrier, owner_name, contact_name, contact_title, social_facebook, social_instagram, social_linkedin, social_x, social_youtube, social_tiktok, social_yelp, gbp_url, google_cid, logo_url, main_image_url. number fields [operators: eq, neq, gt, gte, lt, lte, is_empty, is_not_empty]: rank, rating, reviews, people. yes/no fields [operators: is_true, is_false, is_empty, is_not_empty]: claimed. choice fields [operators: is, is_not, is_empty, is_not_empty]: website_status take none (No website), live, unreachable, blocked (Blocked our crawler), unknown, pending; email_status (or email_1_status), email_2_status, email_3_status take safe, risky, invalid, unknown; phone_line_type (or phone_1_type), phone_2_type, phone_3_type take mobile, fixed_line (Landline), fixed_line_or_mobile (Landline or mobile), voip, non_fixed_voip, toll_free (Toll-free), premium_rate, shared_cost, personal_number (Personal), pager, uan, voicemail, unknown. value is one string (a number as text, e.g. '4.5'); is_empty, is_not_empty, is_true and is_false take none. Text matching ignores case. Phone fields compare digits, so '(512) 555' finds +15125550100; website is / is_not compare domains when given a domain ('acme.com', or 'https://www.acme.com/'), and whole addresses when given a path, a query or a fragment ('acme.com/locations/austin'), either way ignoring http(s)://, www. and a closing slash. conj ('and' or 'or') joins a condition to the one before it, and 'and' binds tighter: A and B or C means (A and B) or C. To match any of several values, send one condition per value joined with conj 'or', repeating the other conditions in each group." - added
Output schema / properties / results / items / properties / countryAdded value: +{ + "description": "ISO 3166 alpha-2 (\"US\", \"GB\").", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / results / items / properties / postal_codeAdded value: +{ + "type": [ + "string", + "null" + ] +}
- Changed
search_leads3 fields changed- changed
Input schema / properties / location_code / descriptionPrevious value: -"Optional exact location code. When given, it is what is searched, whatever location says. Sent with location, the search is named after the code's own place (or after location when the code's own name cannot be looked up); sent alone, the search is unnamed and location comes back null."New value: +"Optional exact location code. When given, it is what is searched, whatever location says. Sent with location, the search is named after the code's own place (or after location when the code's own name cannot be looked up); sent alone, the search is unnamed and location comes back null. A code for a place outside the US is refused, as is a location ending in another country ('London, UK')." - added
Output schema / properties / results / items / properties / countryAdded value: +{ + "description": "ISO 3166 alpha-2 (\"US\", \"GB\").", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / results / items / properties / postal_codeAdded value: +{ + "type": [ + "string", + "null" + ] +}
3 tool updates
- Changed
get_search_results3 fields changed- added
Output schema / properties / results / items / properties / contact_nameAdded value: +{ + "description": "The person the business's own website names as running part of it (a manager, a practice's doctor) when it names no owner.", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / results / items / properties / contact_titleAdded value: +{ + "description": "That person's role, as the website gives it.", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / results / items / properties / peopleAdded value: +{ + "description": "Everyone the business's own website names as working there, each { name, title, kind } (kind: owner, manager, practitioner, staff).", + "items": { + "type": "object" + }, + "type": [ + "array", + "null" + ] +}
- Changed
query_leads3 fields changed- added
Output schema / properties / results / items / properties / contact_nameAdded value: +{ + "description": "The person the business's own website names as running part of it (a manager, a practice's doctor) when it names no owner.", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / results / items / properties / contact_titleAdded value: +{ + "description": "That person's role, as the website gives it.", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / results / items / properties / peopleAdded value: +{ + "description": "Everyone the business's own website names as working there, each { name, title, kind } (kind: owner, manager, practitioner, staff).", + "items": { + "type": "object" + }, + "type": [ + "array", + "null" + ] +}
- Changed
search_leads3 fields changed- added
Output schema / properties / results / items / properties / contact_nameAdded value: +{ + "description": "The person the business's own website names as running part of it (a manager, a practice's doctor) when it names no owner.", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / results / items / properties / contact_titleAdded value: +{ + "description": "That person's role, as the website gives it.", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / results / items / properties / peopleAdded value: +{ + "description": "Everyone the business's own website names as working there, each { name, title, kind } (kind: owner, manager, practitioner, staff).", + "items": { + "type": "object" + }, + "type": [ + "array", + "null" + ] +}
7 tool updates
- Changed
create_automation1 field changed- added
Output schema / properties / data_sourcesAdded value: +{ + "description": "Where the sources, licences and notices are for emails and owner names that may come from open datasets and public records. Pass it on with any of this data you share.", + "type": "string" +}
- Changed
export_leads1 field changed- added
Output schema / properties / data_sourcesAdded value: +{ + "description": "Where the sources, licences and notices are for emails and owner names that may come from open datasets and public records. Pass it on with any of this data you share.", + "type": "string" +}
- Changed
get_search_results1 field changed- added
Output schema / properties / data_sourcesAdded value: +{ + "description": "Where the sources, licences and notices are for emails and owner names that may come from open datasets and public records. Pass it on with any of this data you share.", + "type": "string" +}
- Changed
list_automations1 field changed- added
Output schema / properties / data_sourcesAdded value: +{ + "description": "Where the sources, licences and notices are for emails and owner names that may come from open datasets and public records. Pass it on with any of this data you share.", + "type": "string" +}
- Changed
query_leads1 field changed- added
Output schema / properties / data_sourcesAdded value: +{ + "description": "Where the sources, licences and notices are for emails and owner names that may come from open datasets and public records. Pass it on with any of this data you share.", + "type": "string" +}
- Changed
search_leads1 field changed- added
Output schema / properties / data_sourcesAdded value: +{ + "description": "Where the sources, licences and notices are for emails and owner names that may come from open datasets and public records. Pass it on with any of this data you share.", + "type": "string" +}
- Changed
update_automation1 field changed- added
Output schema / properties / data_sourcesAdded value: +{ + "description": "Where the sources, licences and notices are for emails and owner names that may come from open datasets and public records. Pass it on with any of this data you share.", + "type": "string" +}
6 tool updates
- Changed
create_automation2 fields changed- changed
Input schema / properties / spreadsheet_id / descriptionPrevious value: -"google_sheets only: append to this existing LeadMarina-created sheet."New value: +"google_sheets only: add each run to this existing LeadMarina-created sheet, updating rows already in it." - added
Output schema / properties / destination / descriptionAdded value: +"The destination as saved — what each run will actually use."
- Changed
enrich_domains1 field changed- added
Output schema / properties / noteAdded value: +{ + "description": "Present when a delivered domain was listed more than once, or when the balance left some domains out (named, not charged).", + "type": "string" +}
- Changed
export_leads5 fields changed- added
Input schema / properties / cursorAdded value: +{ + "description": "Continue an export: the next_cursor a previous export_leads call returned. Pass it with the same search_id/all and filters.", + "type": "string" +} - changed
Input schema / properties / filters / descriptionPrevious value: -"With all=true: narrow the library using query_leads-style filter rows."New value: +"Optional query_leads-style filter rows: within the search when search_id is given, across the library with all=true." - added
Output schema / properties / next_cursorAdded value: +{ + "description": "Present when the per-call limit or this call's time limit left matching leads unsent: pass it as cursor, with the same destination, search_id/all and filters, to send them. It does not offer again a lead the destination refused (counted as failed in outcome).", + "type": "string" +} - added
Output schema / properties / not_sentAdded value: +{ + "description": "Leads of this batch the destination's time limit did not reach.", + "type": "number" +} - changed
Output schema / properties / warning / descriptionPrevious value: -"Present when truncated: what happened and how to get the rest."New value: +"Present when the per-call limit or this call's time limit left leads unsent: what happened and how to send them. Leads the destination refused are not covered here — outcome counts them as failed."
- Changed
get_search_results9 fields changed- added
Output schema / properties / results / items / properties / addressAdded value: +{ + "description": "Street address from the Google listing.", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / results / items / properties / claimedAdded value: +{ + "description": "Whether the owner has claimed the Google listing.", + "type": [ + "boolean", + "null" + ] +} - added
Output schema / properties / results / items / properties / email_statusAdded value: +{ + "description": "Email 1's SMTP verdict: safe | risky | invalid | unknown.", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / results / items / properties / google_cidAdded value: +{ + "description": "Google listing id (the query_leads google_cid field).", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / results / items / properties / maps_urlAdded value: +{ + "description": "The Google Maps link for the listing.", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / results / items / properties / phoneAdded value: +{ + "description": "The Google Maps number.", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / results / items / properties / phone_line_typeAdded value: +{ + "description": "Phone 1's line type: mobile, fixed_line, voip or toll_free usually; also unknown, fixed_line_or_mobile and the other values query_leads lists.", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / results / items / properties / primary_emailAdded value: +{ + "description": "Email 1: the first address in emails_data, the one email_status describes. Before emails are verified, the lead's primary address.", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / results / items / properties / primary_phoneAdded value: +{ + "description": "Phone 1: the first number in phones_data, the one phone_line_type describes. Before phones are verified, the lead's primary number, or its Google Maps number.", + "type": [ + "string", + "null" + ] +}
- Changed
query_leads16 fields changed- changed
Input schema / properties / cursor / descriptionPrevious value: -"Opaque pagination cursor from a previous call."New value: +"next_cursor from the previous call, for the next page. It carries that call's filters and sort: send it alone, or with the same filters and sort — different ones are refused. Leave it out to start a new query." - changed
Input schema / properties / filters / descriptionPrevious value: -"Filter conditions (optional — omit for everything, newest data first)."New value: +"Conditions, each {field, operator, value, conj}; omit to match every lead. text fields [operators: contains, not_contains, is, is_not, is_empty, is_not_empty]: name, category, city, state, address, website, primary_email (or email_1), email_2, email_3, primary_phone (or phone_1), phone_carrier (or phone_1_carrier), phone_2, phone_2_carrier, phone_3, phone_3_carrier, owner_name, social_facebook, social_instagram, social_linkedin, social_x, social_youtube, social_tiktok, social_yelp, gbp_url, google_cid, logo_url, main_image_url. number fields [operators: eq, neq, gt, gte, lt, lte, is_empty, is_not_empty]: rank, rating, reviews. yes/no fields [operators: is_true, is_false, is_empty, is_not_empty]: claimed. choice fields [operators: is, is_not, is_empty, is_not_empty]: email_status (or email_1_status), email_2_status, email_3_status take safe, risky, invalid, unknown; phone_line_type (or phone_1_type), phone_2_type, phone_3_type take mobile, fixed_line (Landline), fixed_line_or_mobile (Landline or mobile), voip, non_fixed_voip, toll_free (Toll-free), premium_rate, shared_cost, personal_number (Personal), pager, uan, voicemail, unknown. value is one string (a number as text, e.g. '4.5'); is_empty, is_not_empty, is_true and is_false take none. Text matching ignores case. Phone fields compare digits, so '(512) 555' finds +15125550100; website is / is_not compare domains when given a domain ('acme.com', or 'https://www.acme.com/'), and whole addresses when given a path, a query or a fragment ('acme.com/locations/austin'), either way ignoring http(s)://, www. and a closing slash. conj ('and' or 'or') joins a condition to the one before it, and 'and' binds tighter: A and B or C means (A and B) or C. To match any of several values, send one condition per value joined with conj 'or', repeating the other conditions in each group." - changed
Input schema / properties / limit / descriptionPrevious value: -"Max leads to return (default 25, max 1000)."New value: +"Max leads to return (default 25, max 1,000)." - added
Input schema / properties / search_idAdded value: +{ + "description": "Only this search's leads (a search_id from search_leads or list_searches) — e.g. to narrow one search before export_leads with the same search_id and filters. Omit to query the whole library.", + "type": "string" +} - changed
Input schema / properties / sort / descriptionPrevious value: -"Sort keys, e.g. [{id:'reviews',dir:-1}]. Optional."New value: +"Sort keys in priority order, e.g. [{id:'reviews',dir:-1}] for most-reviewed first. id is any filter field id (the column ids email_1, email_1_status, phone_1, phone_1_type and phone_1_carrier work too); dir is 1 ascending (the default) or -1 descending. A lead with no value for a key (null) sorts after the leads that have one, in either direction — except social_facebook, social_instagram, social_linkedin, social_x, social_youtube, social_tiktok, social_yelp, gbp_url, logo_url, main_image_url, which sort by whether a lead has one, not by the link: ascending puts the leads WITHOUT one first, so use dir -1 to put the leads that have one first. Without a sort the order is arbitrary but stable." - changed
Output schema / properties / next_cursor / descriptionPrevious value: -"Pass back as 'cursor' for the next page."New value: +"Pass back as 'cursor' for the next page (it carries the filters and sort); null on the last page." - added
Output schema / properties / results / items / properties / addressAdded value: +{ + "description": "Street address from the Google listing.", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / results / items / properties / claimedAdded value: +{ + "description": "Whether the owner has claimed the Google listing.", + "type": [ + "boolean", + "null" + ] +} - added
Output schema / properties / results / items / properties / email_statusAdded value: +{ + "description": "Email 1's SMTP verdict: safe | risky | invalid | unknown.", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / results / items / properties / google_cidAdded value: +{ + "description": "Google listing id (the query_leads google_cid field).", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / results / items / properties / maps_urlAdded value: +{ + "description": "The Google Maps link for the listing.", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / results / items / properties / phoneAdded value: +{ + "description": "The Google Maps number.", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / results / items / properties / phone_line_typeAdded value: +{ + "description": "Phone 1's line type: mobile, fixed_line, voip or toll_free usually; also unknown, fixed_line_or_mobile and the other values query_leads lists.", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / results / items / properties / primary_emailAdded value: +{ + "description": "Email 1: the first address in emails_data, the one email_status describes. Before emails are verified, the lead's primary address.", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / results / items / properties / primary_phoneAdded value: +{ + "description": "Phone 1: the first number in phones_data, the one phone_line_type describes. Before phones are verified, the lead's primary number, or its Google Maps number.", + "type": [ + "string", + "null" + ] +} - changed
Output schema / properties / total_matching / descriptionPrevious value: -"Exact match count (first page only; absent on later pages)."New value: +"Exact match count — on the first page only; null on later pages."
- Changed
search_leads8 fields changed- changed
Input schema / properties / location / descriptionPrevious value: -"City, e.g. 'Austin, TX'. Ignored if location_code is given."New value: +"City, e.g. 'Austin, TX'. Not needed with location_code, which is always what is searched." - changed
Input schema / properties / location_code / descriptionPrevious value: -"Optional exact location code (skips the city lookup)."New value: +"Optional exact location code. When given, it is what is searched, whatever location says. Sent with location, the search is named after the code's own place (or after location when the code's own name cannot be looked up); sent alone, the search is unnamed and location comes back null." - added
Output schema / properties / cappedAdded value: +{ + "description": "True when the lead balance covered fewer leads than were found — relay this to the user.", + "type": "boolean" +} - added
Output schema / properties / discoveryAdded value: +{ + "description": "'complete', or 'in_progress' when the search was queued whole.", + "type": "string" +} - changed
Output schema / properties / enrichment / descriptionPrevious value: -"'pending' until background verification finishes."New value: +"'pending' until background verification finishes; 'complete' at once when nothing was found." - added
Output schema / properties / foundAdded value: +{ + "description": "Listings found in the first batch, before the balance capped delivery.", + "type": "number" +} - added
Output schema / properties / location / descriptionAdded value: +"The place searched, as the location list names it (the location sent, when a code's own name could not be looked up); null for a location_code sent alone." - added
Output schema / properties / resultsAdded value: +{ + "description": "The first batch, as delivered — contacts are verified in the background (get_search_results).", + "items": { + "properties": { + "category": { + "type": [ + "string", + "null" + ] + }, + "city": { + "type": [ + "string", + "null" + ] + }, + "emails_data": { + "description": "Verified emails with SMTP status." + }, + "enrichment_status": { + "type": [ + "string", + "null" + ] + }, + "name": { + "type": [ + "string", + "null" + ] + }, + "owner_name": { + "type": [ + "string", + "null" + ] + }, + "phones_data": { + "description": "Verified phones with line type + carrier." + }, + "rating": { + "type": [ + "number", + "null" + ] + }, + "reviews": { + "type": [ + "number", + "null" + ] + }, + "socials": { + "description": "Social profile links keyed by platform." + }, + "state": { + "type": [ + "string", + "null" + ] + }, + "website": { + "type": [ + "string", + "null" + ] + } + }, + "type": "object" + }, + "type": "array" +}
2 tool updates
- Changed
get_search_results2 fields changed- added
Output schema / properties / leads_remaining / descriptionAdded value: +"Leads spendable now. On a plan with no monthly quota this is what is left in the current 7-day period, not a monthly balance." - added
Output schema / properties / periodAdded value: +{ + "description": "On a rate-limited plan: { limit, used, resets_at }. Null on a metered plan.", + "type": [ + "object", + "null" + ] +}
- Changed
search_leads1 field changed- added
Output schema / properties / leads_remaining / descriptionAdded value: +"Leads spendable now. On a plan with no monthly quota this is what is left in the current 7-day period."
1 tool update
- Changed
get_balance3 fields changed- added
Output schema / properties / period_limitAdded value: +{ + "type": "number" +} - added
Output schema / properties / period_resets_atAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / period_usedAdded value: +{ + "type": "number" +}
1 tool update
- Changed
get_search_results1 field changed- added
Output schema / properties / next_offsetAdded value: +{ + "description": "Pass as offset to fetch the next page; null on the last page.", + "type": [ + "number", + "null" + ] +}
1 tool update
- Changed
get_search_results3 fields changed- added
Output schema / properties / progressAdded value: +{ + "description": "{ done, total } rows enriched so far.", + "type": [ + "object", + "null" + ] +} - added
Output schema / properties / queue_positionAdded value: +{ + "description": "For queued searches, the place in this account's own queue (1 = next).", + "type": [ + "number", + "null" + ] +} - added
Output schema / properties / stageAdded value: +{ + "description": "queued | discovering | enriching | verifying | complete | failed | cancelled. 'verifying' means every row is delivered and contacts are being verified — often the longest phase, not a stall.", + "type": "string" +}
7 tool updates
- Added
create_automation - Added
delete_automation - Changed
export_leads4 fields changed- changed
Input schema / properties / all / descriptionPrevious value: -"Export the whole library instead. Exports write a file, so there is no row cap."New value: +"Export the whole library instead of one search." - added
Output schema / properties / limitAdded value: +{ + "description": "The per-call limit that applied, when truncated.", + "type": "number" +} - added
Output schema / properties / truncatedAdded value: +{ + "description": "True when more leads matched than this destination's limit — the export was PARTIAL.", + "type": "boolean" +} - added
Output schema / properties / warningAdded value: +{ + "description": "Present when truncated: what happened and how to get the rest.", + "type": "string" +}
- Added
list_automations - Added
list_integrations - Added
list_views - Added
update_automation
Related MCP Connectors
Finds, filters, and verifies local-business leads; every email carries a verification receipt.
Find local businesses, enrich them with emails and socials, and run lead pipelines from your AI.
Local business lead extraction with email + phone enrichment from Google Maps.
Find local businesses, companies and decision makers with verified emails for B2B outreach.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceDiscovers local businesses needing a website via OpenStreetMap and verifies their leads with checks like website existence, email deliverability, and site quality scoring.24 PyPIMIT

LocalPro MCP Serverofficial
AlicenseNot gradedqualityCmaintenanceProvides verified local trade and service business data (e.g., radon mitigation, foundation repair) to AI agents via tools like search_providers and list_niches.1MIT- AlicenseNot gradedqualityDmaintenanceFinds, filters, and verifies local-business leads on demand; every returned email carries a verification receipt (verifier, verdict, timestamp). Credit-based with per-key spend budgets; 25 free validated leads at signup.MIT
- FlicenseNot gradedqualityBmaintenanceRetrieves vetted Local Services Ads businesses (Google Guaranteed or Screened) as clean JSON for any service and US city, enabling lead generation, local SEO monitoring, and competitor tracking.-
Glama MCP Gateway
Add one secure layer between your agents and this server.