Skip to main content
Glama

LeadMarina

Server Details

Verified local-business leads: search by niche and US city, export to Close, GoHighLevel or Sheets.

Ownership verified
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

A3.9/5.0

Scored across 19 tools

Disambiguation4/5

Most tools target clearly distinct objects and actions: live search (search_leads), batch search (run_advanced_search), enrichment (enrich_domains), library query (query_leads), and export (export_leads) are well separated by descriptions. The main soft overlaps are get_search_results vs query_leads with a search_id, and the several list_* tools, but the descriptions make the intended use of each clear enough.

Naming Consistency5/5

Every tool follows a consistent snake_case verb_noun pattern (search_leads, run_advanced_search, create_automation, export_leads, list_integrations, get_balance). Verbs are used meaningfully and predictably across search, automation, listing, and retrieval families.

Tool Count4/5

19 tools is slightly heavy but each maps to a real operation: discovery, advanced-search lifecycle, automations CRUD-lite, querying, export, balance, integrations, views, and place lookup. Nothing looks redundant or filler, though a few could plausibly be consolidated.

Completeness4/5

The surface covers the full lead lifecycle — find places, search, enrich, poll results, query, export, automate, and check balance/integrations. Minor gaps exist: no get_automation for a single record, update_automation only toggles active rather than editing fields, and there is no way to cancel or delete a regular search.

Available Tools

19 tools
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.

NameRequiredDescriptionDefault
citiesYesCities to search, e.g. ['Austin, TX'] (max 25).
cadenceYesHow often it repeats.
keywordYesThe niche to search, e.g. 'roofing contractor' — up to 100 characters.
start_atNoISO timestamp for the first run. Defaults to now (runs on the next tick, within 15 min).
destinationNoWhere each run's leads go. 'none' just saves them to the library.
spreadsheet_idNogoogle_sheets only: add each run to this existing LeadMarina-created sheet, updating rows already in it.

Output Schema

NameRequiredDescription
idYes
noteNo
citiesNo
cadenceNo
keywordNo
destinationNoThe destination as saved — what each run will actually use.
next_run_atNo
data_sourcesNoWhere 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

A4.6/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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

The description opens with a specific verb+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.

Usage Guidelines4/5

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 automationA
DestructiveIdempotent
Inspect

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.

NameRequiredDescriptionDefault
idYesThe automation id from list_automations.

Output Schema

NameRequiredDescription
idYes
noteNo
deletedYes

TDQS

A4.7/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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.

NameRequiredDescriptionDefault
domainsYesBusiness domains, e.g. ['acme.com'] (max 10).

Output Schema

NameRequiredDescription
noteNoPresent when a delivered domain was listed more than once, or when the balance left some domains out (named, not charged).
enrichingYesDomains accepted (balance-capped).
next_stepNo
search_idYes
enrichmentYes

TDQS

A4.7/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

export_leadsExport leads to a destinationA
Destructive
Inspect

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.

NameRequiredDescriptionDefault
allNoExport the whole library instead of one search.
cursorNoContinue an export: the next_cursor a previous export_leads call returned. Pass it with the same search_id/all and filters.
filtersNoOptional query_leads-style filter rows: within the search when search_id is given, across the library with all=true.
search_idNoExport this search's leads.
campaign_idNoOnly this advanced search's leads (an id from run_advanced_search or list_advanced_searches). Not with search_id.
destinationYesWhere the leads go.
sheet_titleNogoogle_sheets without spreadsheet_id: the new spreadsheet's title (up to 100 characters).
spreadsheet_idNogoogle_sheets only: add to this existing LeadMarina-created sheet instead of a new one.
update_existingNoclose, 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

NameRequiredDescription
fileNoFile exports only: the file name.
noteNo
limitNoThe per-call limit that applied, when truncated.
outcomeYesHuman-readable result, e.g. added/updated counts.
warningNoPresent 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.
exportedYesLeads sent to the destination.
not_sentNoLeads of this batch the destination's time limit did not reach.
truncatedNoTrue when more leads matched than this destination's limit — the export was PARTIAL.
next_cursorNoPresent 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_sourcesNoWhere 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_urlNoFile exports only: 7-day download link.
spreadsheet_idNoGoogle 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_urlNoGoogle Sheets only: the spreadsheet the leads went to (it does not expire).

TDQS

A4.7/5.0
Behavior5/5

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

Goes well past the annotations: it discloses per-destination limits, truncation signals (truncated=true, next_cursor, not_sent), update-in-place semantics matched by Google CID that never touch the user's own CRM notes/columns, and the race condition when an all=true export spans calls. This is exactly the mutation/idempotency context that destructiveHint=true and idempotentHint=false cannot convey on their own.

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

Conciseness3/5

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

Front-loaded with the destination list, which is good, but the body is a dense single block where cursor/next_cursor rules are restated two or three times (truncated, not_sent, and the consistency note all circle the same mechanic). Everything earns its place content-wise, but the wall-of-text structure makes it harder to scan than it needs to be.

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

Completeness5/5

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

Despite an output schema existing, the description correctly explains the response signals an agent must relay to the user (truncated, next_cursor, not_sent, spreadsheet_id). Combined with the limit table and consistency caveat, nothing needed to call this correctly — or to recover from a partial export — is missing.

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

Parameters4/5

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

Schema coverage is already 100%, so the baseline is 3; the description still adds real meaning — that filters follow query_leads style and apply within the search when search_id is set, and that google_sheets must be passed the returned spreadsheet_id for the next batch or it starts a new sheet. It stops short of describing every parameter (e.g. sheet_title length is left to the schema), so not a 5.

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

Purpose5/5

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

Opens with a specific verb+resource ('Push leads into a connected destination') and enumerates every destination with concrete semantics (close/ghl/google_sheets/csv/xlsx/json). It also distinguishes scope: one search via search_id, one advanced search via campaign_id, or the whole library via all=true — an agent can pick it apart from query_leads/search_leads immediately.

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

Usage Guidelines5/5

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

Explicit alternatives and conditions: 'For a big library going to a CRM, export csv and import the file instead', single-call export recommended while no search is running for a consistent copy, and 'do not repeat a call that succeeded'. It also explains exactly how to continue a truncated export with cursor.

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 placesA
Read-onlyIdempotent
Inspect

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.

NameRequiredDescriptionDefault
qNoPart of a place's name, at least 2 characters.
countryNo'US', or a US territory's code ('PR', 'GU', 'VI', 'AS', 'MP').

Output Schema

NameRequiredDescription
placesNoWith country 'US' alone: how many places it has. With q: the matches, each { code, name, region } (up to 50).
regionNoWith country 'US' alone: what its regions are called (state).
countryNo
regionsNoWith country 'US' alone: each state, { code, name, places }.
countriesNoWith no arguments: the US and its territories, each { code, name, region, places }.
total_matchingNoWith q: every match, of which up to 50 are listed.

TDQS

A4.2/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness4/5

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

With an output schema present, 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.

Parameters4/5

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

Schema coverage is 100%, so the baseline is 3, but the description 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.

Purpose4/5

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.

Usage Guidelines5/5

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_balanceGet lead balanceA
Read-only
Inspect

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.

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription
noteNo
planYes
period_usedNo
period_limitNo
leads_remainingYes
period_resets_atNo

TDQS

A4.7/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 resultsA
Read-only
Inspect

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.

NameRequiredDescriptionDefault
limitNoMax leads to return (default 25, max 1000).
offsetNoPagination offset (default 0).
search_idYesThe search_id returned by search_leads or enrich_domains.

Output Schema

NameRequiredDescription
queryNo
stageNoqueued | discovering | enriching | verifying | complete | failed | cancelled. 'verifying' means every row is delivered and contacts are being verified — often the longest phase, not a stall.
periodNoOn a rate-limited plan: { limit, used, resets_at }. Null on a metered plan.
resultsYes
showingNoRange shown, e.g. '1–25'.
locationNo
progressNo{ done, total } rows enriched so far.
search_idYes
enrichmentYes'pending' or 'complete'.
next_offsetNoPass as offset to fetch the next page; null on the last page.
total_leadsYes
data_sourcesNoWhere 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_positionNoFor queued searches, the place in this account's own queue (1 = next).
leads_remainingNoLeads 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

A3.7/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness4/5

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

With an output schema present, 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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines3/5

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 searchesB
Read-onlyIdempotent
Inspect

This account's advanced searches, newest first: status, leads so far, searches done of total.

NameRequiredDescriptionDefault
limitNoUp to 100; 25 by default.

Output Schema

NameRequiredDescription
advanced_searchesYes

TDQS

B3.2/5.0
Behavior3/5

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.

Conciseness4/5

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.

Completeness4/5

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

With an output schema present, 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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines2/5

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 searchesA
Read-only
Inspect

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.

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription
countYes
automationsYes
data_sourcesNoWhere 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

A3.7/5.0
Behavior3/5

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.

Conciseness4/5

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.

Completeness4/5

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

With an output schema present and 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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines2/5

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

There is no when-to-use guidance 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 integrationsA
Read-only
Inspect

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.

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription
integrationsYes

TDQS

A4.7/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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 searchesA
Read-only
Inspect

The account's recent searches (id, niche, location, result count, when) — use a search_id with get_search_results or export_leads.

NameRequiredDescriptionDefault
limitNoMax searches (default 10, max 25).

Output Schema

NameRequiredDescription
searchesYes

TDQS

A4.3/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 viewsA
Read-only
Inspect

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.

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription
countYes
viewsYes

TDQS

A4.5/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 libraryA
Read-only
Inspect

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.

NameRequiredDescriptionDefault
sortNoSort 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.
limitNoMax leads to return (default 25, max 1,000).
cursorNonext_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.
filtersNoConditions, 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_idNoOnly 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_idNoOnly this advanced search's leads (an id from run_advanced_search or list_advanced_searches). Not with search_id.

Output Schema

NameRequiredDescription
resultsYes
returnedYes
next_cursorNoPass back as 'cursor' for the next page (it carries the filters and sort); null on the last page.
data_sourcesNoWhere 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_matchingNoExact match count — on the first page only; null on later pages.

TDQS

A4.8/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters4/5

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

Schema coverage is 100%, so the baseline is 3; 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.

Purpose5/5

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.

Usage Guidelines5/5

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.

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.

NameRequiredDescriptionDefault
queryYesBusiness niche/category keyword, e.g. 'electrician'.
countryNo'US' (the default), or a US territory's code ('PR', 'GU', 'VI', 'AS', 'MP') with a place from find_places.
locationNoCity, e.g. 'Austin, TX'. Not needed with location_code, which is always what is searched.
max_leadsNoStop after this many leads: a whole number from 100 to 1,000,000.
location_codeNoOptional 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_categoryNoOnly 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

NameRequiredDescription
foundNoListings found in the first batch, before the balance capped delivery.
queryYes
cappedNoTrue when the lead balance covered fewer leads than were found — relay this to the user.
resultsNoThe first batch, as delivered — contacts are verified in the background (get_search_results).
locationNoThe 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.
discoveryNo'complete', or 'in_progress' when the search was queued whole.
next_stepNo
search_idYes
enrichmentYes'pending' until background verification finishes; 'complete' at once when nothing was found.
data_sourcesNoWhere 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_remainingNoLeads spendable now. On a plan with no monthly quota this is what is left in the current 7-day period.
delivered_so_farYes

TDQS

A4.8/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters4/5

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

Schema coverage is 100%, so the baseline is 3, but the description adds 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.

Purpose5/5

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.

Usage Guidelines5/5

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 automationA
Idempotent
Inspect

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.

NameRequiredDescriptionDefault
idYesThe automation id from list_automations.
activeYesfalse to pause, true to resume.

Output Schema

NameRequiredDescription
idYes
noteNo
activeYes
data_sourcesNoWhere 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

A4.5/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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. 1 tool update
    • Changedcreate_automation2 fields changed
      • changedInput schema / properties / keyword / description
        Previous value: -"The niche to search, e.g. 'roofing contractor'."New value: +"The niche to search, e.g. 'roofing contractor' — up to 100 characters."
      • addedInput schema / properties / keyword / maxLength
        Added value: +100
  2. 2 tool updates
    • Changedget_advanced_search1 field changed
      • changedOutput schema / properties / running_now / description
        Previous 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."
    • Changedrun_advanced_search1 field changed
      • changedOutput schema / properties / running_now / description
        Previous 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."
  3. 1 tool update
    • Changedexport_leads2 fields changed
      • changedOutput schema / properties / next_cursor / description
        Previous 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)."
      • addedOutput schema / properties / spreadsheet_id
        Added 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"
        +}
  4. 1 tool update
    • Changedexport_leads2 fields changed
      • addedInput schema / properties / sheet_title
        Added value: +{
        +  "description": "google_sheets without spreadsheet_id: the new spreadsheet's title (up to 100 characters).",
        +  "type": "string"
        +}
      • addedInput schema / properties / update_existing
        Added 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"
        +}
  5. 1 tool update
    • Changedexport_leads1 field changed
      • addedOutput schema / properties / spreadsheet_url
        Added value: +{
        +  "description": "Google Sheets only: the spreadsheet the leads went to (it does not expire).",
        +  "type": "string"
        +}
  6. 9 tool updates
    • Addedcontrol_advanced_search
    • Addedestimate_advanced_search
    • Changedexport_leads1 field changed
      • addedInput schema / properties / campaign_id
        Added value: +{
        +  "description": "Only this advanced search's leads (an id from run_advanced_search or list_advanced_searches). Not with search_id.",
        +  "type": "string"
        +}
    • Addedfind_places
    • Addedget_advanced_search
    • Addedlist_advanced_searches
    • Changedquery_leads1 field changed
      • addedInput schema / properties / campaign_id
        Added value: +{
        +  "description": "Only this advanced search's leads (an id from run_advanced_search or list_advanced_searches). Not with search_id.",
        +  "type": "string"
        +}
    • Addedrun_advanced_search
    • Changedsearch_leads3 fields changed
      • addedInput schema / properties / country
        Added value: +{
        +  "description": "'US' (the default), or a US territory's code ('PR', 'GU', 'VI', 'AS', 'MP') with a place from find_places.",
        +  "type": "string"
        +}
      • addedInput schema / properties / exact_category
        Added 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"
        +  ]
        +}
      • addedInput schema / properties / max_leads
        Added value: +{
        +  "description": "Stop after this many leads: a whole number from 100 to 1,000,000.",
        +  "type": "number"
        +}
  7. 3 tool updates
    • Changedget_search_results2 fields changed
      • addedOutput schema / properties / results / items / properties / country
        Added value: +{
        +  "description": "ISO 3166 alpha-2 (\"US\", \"GB\").",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / results / items / properties / postal_code
        Added value: +{
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
    • Changedquery_leads3 fields changed
      • changedInput schema / properties / filters / description
        Previous 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."
      • addedOutput schema / properties / results / items / properties / country
        Added value: +{
        +  "description": "ISO 3166 alpha-2 (\"US\", \"GB\").",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / results / items / properties / postal_code
        Added value: +{
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
    • Changedsearch_leads3 fields changed
      • changedInput schema / properties / location_code / description
        Previous 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')."
      • addedOutput schema / properties / results / items / properties / country
        Added value: +{
        +  "description": "ISO 3166 alpha-2 (\"US\", \"GB\").",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / results / items / properties / postal_code
        Added value: +{
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
  8. 3 tool updates
    • Changedget_search_results3 fields changed
      • addedOutput schema / properties / results / items / properties / contact_name
        Added 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"
        +  ]
        +}
      • addedOutput schema / properties / results / items / properties / contact_title
        Added value: +{
        +  "description": "That person's role, as the website gives it.",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / results / items / properties / people
        Added 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"
        +  ]
        +}
    • Changedquery_leads3 fields changed
      • addedOutput schema / properties / results / items / properties / contact_name
        Added 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"
        +  ]
        +}
      • addedOutput schema / properties / results / items / properties / contact_title
        Added value: +{
        +  "description": "That person's role, as the website gives it.",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / results / items / properties / people
        Added 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"
        +  ]
        +}
    • Changedsearch_leads3 fields changed
      • addedOutput schema / properties / results / items / properties / contact_name
        Added 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"
        +  ]
        +}
      • addedOutput schema / properties / results / items / properties / contact_title
        Added value: +{
        +  "description": "That person's role, as the website gives it.",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / results / items / properties / people
        Added 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"
        +  ]
        +}
  9. 7 tool updates
    • Changedcreate_automation1 field changed
      • addedOutput schema / properties / data_sources
        Added 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"
        +}
    • Changedexport_leads1 field changed
      • addedOutput schema / properties / data_sources
        Added 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"
        +}
    • Changedget_search_results1 field changed
      • addedOutput schema / properties / data_sources
        Added 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"
        +}
    • Changedlist_automations1 field changed
      • addedOutput schema / properties / data_sources
        Added 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"
        +}
    • Changedquery_leads1 field changed
      • addedOutput schema / properties / data_sources
        Added 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"
        +}
    • Changedsearch_leads1 field changed
      • addedOutput schema / properties / data_sources
        Added 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"
        +}
    • Changedupdate_automation1 field changed
      • addedOutput schema / properties / data_sources
        Added 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"
        +}
  10. 6 tool updates
    • Changedcreate_automation2 fields changed
      • changedInput schema / properties / spreadsheet_id / description
        Previous 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."
      • addedOutput schema / properties / destination / description
        Added value: +"The destination as saved — what each run will actually use."
    • Changedenrich_domains1 field changed
      • addedOutput schema / properties / note
        Added 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"
        +}
    • Changedexport_leads5 fields changed
      • addedInput schema / properties / cursor
        Added 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"
        +}
      • changedInput schema / properties / filters / description
        Previous 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."
      • addedOutput schema / properties / next_cursor
        Added 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"
        +}
      • addedOutput schema / properties / not_sent
        Added value: +{
        +  "description": "Leads of this batch the destination's time limit did not reach.",
        +  "type": "number"
        +}
      • changedOutput schema / properties / warning / description
        Previous 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."
    • Changedget_search_results9 fields changed
      • addedOutput schema / properties / results / items / properties / address
        Added value: +{
        +  "description": "Street address from the Google listing.",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / results / items / properties / claimed
        Added value: +{
        +  "description": "Whether the owner has claimed the Google listing.",
        +  "type": [
        +    "boolean",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / results / items / properties / email_status
        Added value: +{
        +  "description": "Email 1's SMTP verdict: safe | risky | invalid | unknown.",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / results / items / properties / google_cid
        Added value: +{
        +  "description": "Google listing id (the query_leads google_cid field).",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / results / items / properties / maps_url
        Added value: +{
        +  "description": "The Google Maps link for the listing.",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / results / items / properties / phone
        Added value: +{
        +  "description": "The Google Maps number.",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / results / items / properties / phone_line_type
        Added 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"
        +  ]
        +}
      • addedOutput schema / properties / results / items / properties / primary_email
        Added 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"
        +  ]
        +}
      • addedOutput schema / properties / results / items / properties / primary_phone
        Added 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"
        +  ]
        +}
    • Changedquery_leads16 fields changed
      • changedInput schema / properties / cursor / description
        Previous 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."
      • changedInput schema / properties / filters / description
        Previous 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."
      • changedInput schema / properties / limit / description
        Previous value: -"Max leads to return (default 25, max 1000)."New value: +"Max leads to return (default 25, max 1,000)."
      • addedInput schema / properties / search_id
        Added 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"
        +}
      • changedInput schema / properties / sort / description
        Previous 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."
      • changedOutput schema / properties / next_cursor / description
        Previous 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."
      • addedOutput schema / properties / results / items / properties / address
        Added value: +{
        +  "description": "Street address from the Google listing.",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / results / items / properties / claimed
        Added value: +{
        +  "description": "Whether the owner has claimed the Google listing.",
        +  "type": [
        +    "boolean",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / results / items / properties / email_status
        Added value: +{
        +  "description": "Email 1's SMTP verdict: safe | risky | invalid | unknown.",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / results / items / properties / google_cid
        Added value: +{
        +  "description": "Google listing id (the query_leads google_cid field).",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / results / items / properties / maps_url
        Added value: +{
        +  "description": "The Google Maps link for the listing.",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / results / items / properties / phone
        Added value: +{
        +  "description": "The Google Maps number.",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / results / items / properties / phone_line_type
        Added 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"
        +  ]
        +}
      • addedOutput schema / properties / results / items / properties / primary_email
        Added 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"
        +  ]
        +}
      • addedOutput schema / properties / results / items / properties / primary_phone
        Added 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"
        +  ]
        +}
      • changedOutput schema / properties / total_matching / description
        Previous 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."
    • Changedsearch_leads8 fields changed
      • changedInput schema / properties / location / description
        Previous 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."
      • changedInput schema / properties / location_code / description
        Previous 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."
      • addedOutput schema / properties / capped
        Added value: +{
        +  "description": "True when the lead balance covered fewer leads than were found — relay this to the user.",
        +  "type": "boolean"
        +}
      • addedOutput schema / properties / discovery
        Added value: +{
        +  "description": "'complete', or 'in_progress' when the search was queued whole.",
        +  "type": "string"
        +}
      • changedOutput schema / properties / enrichment / description
        Previous value: -"'pending' until background verification finishes."New value: +"'pending' until background verification finishes; 'complete' at once when nothing was found."
      • addedOutput schema / properties / found
        Added value: +{
        +  "description": "Listings found in the first batch, before the balance capped delivery.",
        +  "type": "number"
        +}
      • addedOutput schema / properties / location / description
        Added 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."
      • addedOutput schema / properties / results
        Added 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"
        +}
  11. 2 tool updates
    • Changedget_search_results2 fields changed
      • addedOutput schema / properties / leads_remaining / description
        Added 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."
      • addedOutput schema / properties / period
        Added value: +{
        +  "description": "On a rate-limited plan: { limit, used, resets_at }. Null on a metered plan.",
        +  "type": [
        +    "object",
        +    "null"
        +  ]
        +}
    • Changedsearch_leads1 field changed
      • addedOutput schema / properties / leads_remaining / description
        Added value: +"Leads spendable now. On a plan with no monthly quota this is what is left in the current 7-day period."
  12. 1 tool update
    • Changedget_balance3 fields changed
      • addedOutput schema / properties / period_limit
        Added value: +{
        +  "type": "number"
        +}
      • addedOutput schema / properties / period_resets_at
        Added value: +{
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / period_used
        Added value: +{
        +  "type": "number"
        +}
  13. 1 tool update
    • Changedget_search_results1 field changed
      • addedOutput schema / properties / next_offset
        Added value: +{
        +  "description": "Pass as offset to fetch the next page; null on the last page.",
        +  "type": [
        +    "number",
        +    "null"
        +  ]
        +}
  14. 1 tool update
    • Changedget_search_results3 fields changed
      • addedOutput schema / properties / progress
        Added value: +{
        +  "description": "{ done, total } rows enriched so far.",
        +  "type": [
        +    "object",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / queue_position
        Added value: +{
        +  "description": "For queued searches, the place in this account's own queue (1 = next).",
        +  "type": [
        +    "number",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / stage
        Added 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"
        +}
  15. 7 tool updates
    • Addedcreate_automation
    • Addeddelete_automation
    • Changedexport_leads4 fields changed
      • changedInput schema / properties / all / description
        Previous 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."
      • addedOutput schema / properties / limit
        Added value: +{
        +  "description": "The per-call limit that applied, when truncated.",
        +  "type": "number"
        +}
      • addedOutput schema / properties / truncated
        Added value: +{
        +  "description": "True when more leads matched than this destination's limit — the export was PARTIAL.",
        +  "type": "boolean"
        +}
      • addedOutput schema / properties / warning
        Added value: +{
        +  "description": "Present when truncated: what happened and how to get the rest.",
        +  "type": "string"
        +}
    • Addedlist_automations
    • Addedlist_integrations
    • Addedlist_views
    • Addedupdate_automation
  16. 3 tool updates
    • Changedexport_leads1 field changed
      • changedInput schema / properties / all / description
        Previous value: -"Export the whole library instead (max 1000 leads)."New value: +"Export the whole library instead. Exports write a file, so there is no row cap."
    • Changedget_search_results1 field changed
      • changedInput schema / properties / limit / description
        Previous value: -"Max leads to return (default 25, max 100)."New value: +"Max leads to return (default 25, max 1000)."
    • Changedquery_leads1 field changed
      • changedInput schema / properties / limit / description
        Previous value: -"Max leads to return (default 25, max 100)."New value: +"Max leads to return (default 25, max 1000)."

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    Discovers local businesses needing a website via OpenStreetMap and verifies their leads with checks like website existence, email deliverability, and site quality scoring.
    24 PyPI
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Provides verified local trade and service business data (e.g., radon mitigation, foundation repair) to AI agents via tools like search_providers and list_niches.
    1
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Finds, 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
  • F
    license
    Not graded
    quality
    B
    maintenance
    Retrieves 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.
    -
Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.