leadmarina
Server Details
Verified local-business leads: search any niche + city, query your library, export to your CRM.
- Status
- Healthy
- Uptime
- 100.0% over 55 days
- Last Tested
- Transport
- Streamable HTTP · MCP 2025-06-18
- URL
TDQS
Scored across 13 tools
Most tools have clearly distinct purposes: search_leads runs a live paid search, query_leads searches the existing library without spending leads, and enrich_domains handles existing domains. However, query_leads can also retrieve a single search's leads via search_id, which overlaps with get_search_results and could cause occasional misselection.
Every tool follows a consistent snake_case verb_noun pattern (create_automation, delete_automation, list_searches, query_leads, export_leads, etc.). There are no mixed conventions or vague names, making the surface easy to parse.
With 13 tools, the set is well-scoped for a lead generation and export platform. Each tool covers a distinct operation (search, enrich, query, export, automate, account/integration checks) and none feels redundant or missing for the core workflow.
The lifecycle from discovery through enrichment, querying, exporting, and automation is largely covered, including full CRUD for automations and balance/integration checks. Minor gaps exist: update_automation only toggles active status rather than editing niche/cities/destination, and saved views can be listed but not created or modified through these tools.
Available Tools
13 toolscreate_automationSchedule a recurring searchInspect
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 also needs one manual export first to save its field mapping); '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.
| Name | Required | Description | Default |
|---|---|---|---|
| cities | Yes | Cities to search, e.g. ['Austin, TX'] (max 25). | |
| cadence | Yes | How often it repeats. | |
| keyword | Yes | The niche to search, e.g. 'roofing contractor'. | |
| start_at | No | ISO timestamp for the first run. Defaults to now (runs on the next tick, within 15 min). | |
| destination | No | Where each run's leads go. 'none' just saves them to the library. | |
| spreadsheet_id | No | google_sheets only: add each run to this existing LeadMarina-created sheet, updating rows already in it. |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | |
| note | No | |
| cities | No | |
| cadence | No | |
| keyword | No | |
| destination | No | The destination as saved — what each run will actually use. |
| next_run_at | No | |
| data_sources | No | Where the sources, licences and notices are for emails and owner names that may come from open datasets and public records. Pass it on with any of this data you share. |
delete_automationDelete an automationADestructiveIdempotentInspect
Permanently delete an automation. This cannot be undone — confirm with the user first, and prefer update_automation with active=false if they only want it to stop for now. Leads already collected by past runs are kept; only the schedule is removed.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | The automation id from list_automations. |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | |
| note | No | |
| deleted | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare destructiveHint=true and readOnlyHint=false, but the description adds substantial context: the deletion is irreversible, leads already collected are retained, and only the schedule is removed. This goes well beyond the annotations and fully discloses the operational impact.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tightly written sentences, each earning its place: the first states the action, the second adds critical safety guidance, and the third clarifies behavioral consequences. No filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter destructive mutation, the description fully covers prerequisites (confirmation), alternatives (disable instead of delete), effects (schedule removed, leads kept), and irreversibility. An output schema exists, so return-value details are not required. The description is self-sufficient.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already provides 100% coverage for the single required parameter, id, and explicitly states it comes from list_automations. The description does not add parameter-specific details, but with complete schema coverage the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Permanently delete an automation,' using a specific verb and resource while clearly distinguishing this from the sibling update_automation. It also clarifies the destructive nature, leaving no ambiguity about the tool's purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when to use this tool and when not to, recommending update_automation with active=false as a less destructive alternative for temporary suspension. It also instructs the agent to confirm with the user first, providing direct guidance for safe invocation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
enrich_domainsEnrich business domainsAInspect
Already have businesses? Pass up to 10 website domains to run the full enrichment + verification pipeline on them (verified emails + phones, owner name, socials). Costs 1 lead per distinct domain — spellings of the same site (acme.com, www.acme.com, https://acme.com/contact) count once. Returns a search_id to poll with get_search_results.
| Name | Required | Description | Default |
|---|---|---|---|
| domains | Yes | Business domains, e.g. ['acme.com'] (max 10). |
Output Schema
| Name | Required | Description |
|---|---|---|
| note | No | Present when a delivered domain was listed more than once, or when the balance left some domains out (named, not charged). |
| enriching | Yes | Domains accepted (balance-capped). |
| next_step | No | |
| search_id | Yes | |
| enrichment | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations: it discloses the cost model (1 lead per distinct domain), the deduplication semantics (acme.com, www.acme.com, https://acme.com/contact count once), and the asynchronous contract (returns a search_id to poll). These are billing and lifecycle facts the annotations cannot express.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three dense sentences, front-loaded with the precondition and action, then cost, then the return/polling path. No filler and nothing that could be cut without losing operational meaning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists so return-value detail is unnecessary, yet the description still tells the agent the key next step (poll get_search_results with the returned search_id). Limits, cost, dedup behavior, and output shape are all covered for a single-parameter tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the schema already documents the domains array with a max-10 note, so the baseline is 3. The description adds real meaning the schema lacks: the normalization rule for counting distinct domains, which tells the agent how duplicate-looking inputs are billed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: run the full enrichment + verification pipeline on up to 10 website domains, listing the concrete outputs (verified emails + phones, owner name, socials). This is clearly distinct from sibling search tools like search_leads and query_leads because the agent supplies domains it already has rather than searching.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The opening 'Already have businesses?' frames the precondition for use and implicitly contrasts with discovery/search siblings, and it explicitly routes the agent to get_search_results for polling. It stops short of naming the alternative discovery tool to use when the agent does not already have domains.
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 destinationInspect
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, also emailed to the account owner when the file is small enough to attach). 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. 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; a file or a new sheet is a fresh copy every time — so do not repeat a call that succeeded.
| Name | Required | Description | Default |
|---|---|---|---|
| all | No | Export the whole library instead of one search. | |
| cursor | No | Continue an export: the next_cursor a previous export_leads call returned. Pass it with the same search_id/all and filters. | |
| filters | No | Optional query_leads-style filter rows: within the search when search_id is given, across the library with all=true. | |
| search_id | No | Export this search's leads. | |
| destination | Yes | Where the leads go. | |
| spreadsheet_id | No | google_sheets only: add to this existing LeadMarina-created sheet instead of a new one. |
Output Schema
| Name | Required | Description |
|---|---|---|
| file | No | File exports only: the file name. |
| note | No | |
| limit | No | The per-call limit that applied, when truncated. |
| outcome | Yes | Human-readable result, e.g. added/updated counts. |
| warning | No | Present when the per-call limit or this call's time limit left leads unsent: what happened and how to send them. Leads the destination refused are not covered here — outcome counts them as failed. |
| exported | Yes | Leads sent to the destination. |
| not_sent | No | Leads of this batch the destination's time limit did not reach. |
| truncated | No | True when more leads matched than this destination's limit — the export was PARTIAL. |
| next_cursor | No | Present when the per-call limit or this call's time limit left matching leads unsent: pass it as cursor, with the same destination, search_id/all and filters, to send them. It does not offer again a lead the destination refused (counted as failed in outcome). |
| data_sources | No | Where the sources, licences and notices are for emails and owner names that may come from open datasets and public records. Pass it on with any of this data you share. |
| download_url | No | File exports only: 7-day download link. |
get_balanceGet lead balanceARead-onlyInspect
What the account has left, and when it resets. On a plan with a rate limit (no monthly quota) this is the leads left in the current 7-day period; on a metered plan it is the monthly allotment remaining.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| note | No | |
| plan | Yes | |
| period_used | No | |
| period_limit | No | |
| leads_remaining | Yes | |
| period_resets_at | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint=true and destructiveHint=false. The description adds valuable context: it explains the reset behavior and how balance differs by plan type, going beyond the binary annotations. No contradiction; it enriches understanding of the tool's output.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tightly worded sentences, with the core purpose ('what the account has left, and when it resets') front-loaded. The second sentence clarifies plan-specific nuances without redundancy. No wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no parameters and an output schema available, the description fully covers what the tool does and how to interpret the result. It clarifies reset timing and plan distinctions, leaving no ambiguity about the return value's meaning.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so baseline is 4 per rubric. The description adds no parameter details because none exist, but it effectively explains what the returned value represents, which is more relevant than parameter semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: reporting remaining lead balance and reset timing. It distinguishes between rate-limited (7-day period) and metered (monthly) plans, providing specificity beyond the title. No sibling tool covers balance queries, so it stands apart.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage: check balance to know remaining leads before operations. It does not explicitly contrast with alternatives, but given the sibling list contains no similar tools, that omission is acceptable. It clearly explains when the value applies (current period) without needing exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_search_resultsGet search resultsRead-onlyInspect
Fetch a search's leads with verification filled in as enrichment progresses. Poll until enrichment is 'complete'. Each lead includes verified emails (SMTP status), verified phones (line type + carrier), owner name where identified, socials, and the business profile.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Max leads to return (default 25, max 1000). | |
| offset | No | Pagination offset (default 0). | |
| search_id | Yes | The search_id returned by search_leads or enrich_domains. |
Output Schema
| Name | Required | Description |
|---|---|---|
| query | No | |
| stage | No | queued | discovering | enriching | verifying | complete | failed | cancelled. 'verifying' means every row is delivered and contacts are being verified — often the longest phase, not a stall. |
| period | No | On a rate-limited plan: { limit, used, resets_at }. Null on a metered plan. |
| results | Yes | |
| showing | No | Range shown, e.g. '1–25'. |
| location | No | |
| progress | No | { done, total } rows enriched so far. |
| search_id | Yes | |
| enrichment | Yes | 'pending' or 'complete'. |
| next_offset | No | Pass as offset to fetch the next page; null on the last page. |
| total_leads | Yes | |
| data_sources | No | Where the sources, licences and notices are for emails and owner names that may come from open datasets and public records. Pass it on with any of this data you share. |
| queue_position | No | For queued searches, the place in this account's own queue (1 = next). |
| leads_remaining | No | Leads spendable now. On a plan with no monthly quota this is what is left in the current 7-day period, not a monthly balance. |
list_automationsList scheduled searchesRead-onlyInspect
The account's automations — saved searches that re-run on a schedule and export themselves. Shows each one's niche, cities, cadence, destination, whether it's active, when it next runs, and how the last run went.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| count | Yes | |
| automations | Yes | |
| data_sources | No | Where the sources, licences and notices are for emails and owner names that may come from open datasets and public records. Pass it on with any of this data you share. |
list_integrationsList connected integrationsARead-onlyInspect
Which export destinations this account has connected (Close, GoHighLevel, Google Sheets) and whether each is ready to receive leads. Check this BEFORE export_leads or create_automation with a CRM destination — those fail if the integration isn't connected, and Close additionally needs one manual export first to save its field mapping. File destinations (csv/xlsx/json) always work and need nothing connected.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| integrations | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, but the description adds valuable context: that export_leads/create_automation fail without integration and that Close requires a manual export first. This goes beyond the structured annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, information-dense sentence that front-loads the purpose and then provides essential usage guidance. Every clause contributes value without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With zero parameters and an output schema present, the description fully covers purpose, usage timing, and edge cases (Close's manual export requirement, file destinations always working). No gaps remain.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Tool has 0 parameters, so baseline is 4. The description uses this freedom to explain the meaning of 'connected' and 'ready', adding semantic context even though no parameters need clarification.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool lists connected export destinations (Close, GoHighLevel, Google Sheets) and their readiness for receiving leads. It uses specific resource names and distinguishes itself from sibling export/automation tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly instructs to check this tool before export_leads or create_automation with CRM destinations, noting these fail without a connected integration. Also states file destinations always work, providing clear when-to-use and alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_searchesList recent searchesARead-onlyInspect
The account's recent searches (id, niche, location, result count, when) — use a search_id with get_search_results or export_leads.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Max searches (default 10, max 25). |
Output Schema
| Name | Required | Description |
|---|---|---|
| searches | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, covering the safety profile. The description adds value beyond this by clarifying account scoping ('the account's recent searches'), listing the return fields, and indicating how the results should be used downstream, which are behaviors not captured by the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence that front-loads the main purpose and returned fields, followed by a concise usage clause. Every word contributes useful information with no redundancy or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity (one optional parameter, existing output schema, read-only annotations), the description provides all essential context: what it returns, account scope, and how the results connect to sibling tools. This is fully complete for the tool's complexity level.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema provides 100% coverage for the single 'limit' parameter, including its default (10) and max (25) values. The description does not repeat or extend the parameter semantics, so it adds no extra meaning beyond what the schema already offers.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('List recent searches') and the resource ('account's recent searches'), and enumerates the returned fields (id, niche, location, result count, when). It differentiates from sibling tools by explicitly mentioning that search_ids from this tool are used with get_search_results or export_leads, making its role distinct.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the usage context by explaining that the search_id obtained from this tool is used with get_search_results or export_leads, which positions list_searches as the entry point for those operations. It does not provide explicit exclusions or alternative scenarios, but the guidance is clear and helpful for an agent deciding when to call it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_viewsList saved viewsARead-onlyInspect
The account's saved views from the leads table — each a named set of filters the user already built (e.g. 'Roofers with a mobile number'). Returns each view's filter conditions in the exact shape query_leads and export_leads accept, so "export my Hot Leads view to Close" works without rebuilding the filters by hand.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| count | Yes | |
| views | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is well covered. The description adds valuable behavioral context by stating the output format is compatible with query_leads and export_leads, and clarifies that views are user-defined named filters. This goes beyond the annotations and helps the agent understand the data and its reuse. No contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise, consisting of two sentences. It front-loads the purpose, provides an example, and explains the key integration point without unnecessary elaboration. Every sentence contributes meaning and earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no parameters, an existing output schema, and read-only annotations, the description covers all essential aspects: what is listed, the format compatibility, and the practical use case. It does not discuss pagination or limits, but these are likely in the output schema. Overall, it is complete for a simple list tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so the description correctly focuses on output rather than inputs. Schema description coverage is 100% by default, and the description adds no parameter details because none are needed. The baseline of 4 is appropriate for tools with no parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states that the tool lists the account's saved views from the leads table, each being a named set of filters, with a concrete example ('Roofers with a mobile number'). This distinguishes it from sibling tools like list_searches by specifying 'saved views' as the resource. The verb 'list' is unambiguous and directly matches the title.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains that the returned filter conditions are in the exact shape query_leads and export_leads accept, implying this tool is used to retrieve saved views before querying or exporting them. It does not explicitly state when not to use it or compare it to alternatives, but the context makes the primary use case clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
query_leadsQuery the lead libraryRead-onlyInspect
Search ALL leads the account has ever collected (across every search) with filters and sorting — no new search is run and no leads are spent. A Google listing found more than once appears once, with its most recent data. Up to 1,000 leads per call (default 25). When next_cursor is set, call again with cursor = next_cursor for the next page: the cursor carries its filters and sort, so it can be sent alone. Pass search_id to query one search's leads instead of the whole library. Example — plumbers in Austin rated 4.5 or higher with a safe email, most-reviewed first: filters=[{field:'category',operator:'contains',value:'plumb'},{field:'city',operator:'is',value:'Austin',conj:'and'},{field:'rating',operator:'gte',value:'4.5',conj:'and'},{field:'email_status',operator:'is',value:'safe',conj:'and'}], sort=[{id:'reviews',dir:-1}]. A field, operator or value the tool cannot use comes back as an error that names it and lists what works.
| Name | Required | Description | Default |
|---|---|---|---|
| sort | No | Sort keys in priority order, e.g. [{id:'reviews',dir:-1}] for most-reviewed first. id is any filter field id (the column ids email_1, email_1_status, phone_1, phone_1_type and phone_1_carrier work too); dir is 1 ascending (the default) or -1 descending. A lead with no value for a key (null) sorts after the leads that have one, in either direction — except social_facebook, social_instagram, social_linkedin, social_x, social_youtube, social_tiktok, social_yelp, gbp_url, logo_url, main_image_url, which sort by whether a lead has one, not by the link: ascending puts the leads WITHOUT one first, so use dir -1 to put the leads that have one first. Without a sort the order is arbitrary but stable. | |
| limit | No | Max leads to return (default 25, max 1,000). | |
| cursor | No | next_cursor from the previous call, for the next page. It carries that call's filters and sort: send it alone, or with the same filters and sort — different ones are refused. Leave it out to start a new query. | |
| filters | No | Conditions, each {field, operator, value, conj}; omit to match every lead. text fields [operators: contains, not_contains, is, is_not, is_empty, is_not_empty]: name, category, city, state, 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. | |
| search_id | No | Only this search's leads (a search_id from search_leads or list_searches) — e.g. to narrow one search before export_leads with the same search_id and filters. Omit to query the whole library. |
Output Schema
| Name | Required | Description |
|---|---|---|
| results | Yes | |
| returned | Yes | |
| next_cursor | No | Pass back as 'cursor' for the next page (it carries the filters and sort); null on the last page. |
| data_sources | No | Where the sources, licences and notices are for emails and owner names that may come from open datasets and public records. Pass it on with any of this data you share. |
| total_matching | No | Exact match count — on the first page only; null on later pages. |
search_leadsSearch local-business leadsInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | Business niche/category keyword, e.g. 'electrician'. | |
| location | No | City, e.g. 'Austin, TX'. Not needed with location_code, which is always what is searched. | |
| location_code | No | Optional exact location code. When given, it is what is searched, whatever location says. Sent with location, the search is named after the code's own place (or after location when the code's own name cannot be looked up); sent alone, the search is unnamed and location comes back null. |
Output Schema
| Name | Required | Description |
|---|---|---|
| found | No | Listings found in the first batch, before the balance capped delivery. |
| query | Yes | |
| capped | No | True when the lead balance covered fewer leads than were found — relay this to the user. |
| results | No | The first batch, as delivered — contacts are verified in the background (get_search_results). |
| location | No | The place searched, as the location list names it (the location sent, when a code's own name could not be looked up); null for a location_code sent alone. |
| discovery | No | 'complete', or 'in_progress' when the search was queued whole. |
| next_step | No | |
| search_id | Yes | |
| enrichment | Yes | 'pending' until background verification finishes; 'complete' at once when nothing was found. |
| data_sources | No | Where the sources, licences and notices are for emails and owner names that may come from open datasets and public records. Pass it on with any of this data you share. |
| leads_remaining | No | Leads spendable now. On a plan with no monthly quota this is what is left in the current 7-day period. |
| delivered_so_far | Yes |
update_automationPause or resume an automationIdempotentInspect
Pause an automation (active=false) so it stops running and stops spending leads, or resume it (active=true). Pausing is the safe way to stop an automation you might want back — use delete_automation only when the user wants it gone for good.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | The automation id from list_automations. | |
| active | Yes | false to pause, true to resume. |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | |
| note | No | |
| active | Yes | |
| data_sources | No | Where the sources, licences and notices are for emails and owner names that may come from open datasets and public records. Pass it on with any of this data you share. |
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
3 tool updates
- Changed
get_search_results3 fields changed- added
Output schema / properties / results / items / properties / contact_nameAdded value: +{ + "description": "The person the business's own website names as running part of it (a manager, a practice's doctor) when it names no owner.", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / results / items / properties / contact_titleAdded value: +{ + "description": "That person's role, as the website gives it.", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / results / items / properties / peopleAdded value: +{ + "description": "Everyone the business's own website names as working there, each { name, title, kind } (kind: owner, manager, practitioner, staff).", + "items": { + "type": "object" + }, + "type": [ + "array", + "null" + ] +}
- Changed
query_leads3 fields changed- added
Output schema / properties / results / items / properties / contact_nameAdded value: +{ + "description": "The person the business's own website names as running part of it (a manager, a practice's doctor) when it names no owner.", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / results / items / properties / contact_titleAdded value: +{ + "description": "That person's role, as the website gives it.", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / results / items / properties / peopleAdded value: +{ + "description": "Everyone the business's own website names as working there, each { name, title, kind } (kind: owner, manager, practitioner, staff).", + "items": { + "type": "object" + }, + "type": [ + "array", + "null" + ] +}
- Changed
search_leads3 fields changed- added
Output schema / properties / results / items / properties / contact_nameAdded value: +{ + "description": "The person the business's own website names as running part of it (a manager, a practice's doctor) when it names no owner.", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / results / items / properties / contact_titleAdded value: +{ + "description": "That person's role, as the website gives it.", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / results / items / properties / peopleAdded value: +{ + "description": "Everyone the business's own website names as working there, each { name, title, kind } (kind: owner, manager, practitioner, staff).", + "items": { + "type": "object" + }, + "type": [ + "array", + "null" + ] +}
7 tool updates
- Changed
create_automation1 field changed- added
Output schema / properties / data_sourcesAdded value: +{ + "description": "Where the sources, licences and notices are for emails and owner names that may come from open datasets and public records. Pass it on with any of this data you share.", + "type": "string" +}
- Changed
export_leads1 field changed- added
Output schema / properties / data_sourcesAdded value: +{ + "description": "Where the sources, licences and notices are for emails and owner names that may come from open datasets and public records. Pass it on with any of this data you share.", + "type": "string" +}
- Changed
get_search_results1 field changed- added
Output schema / properties / data_sourcesAdded value: +{ + "description": "Where the sources, licences and notices are for emails and owner names that may come from open datasets and public records. Pass it on with any of this data you share.", + "type": "string" +}
- Changed
list_automations1 field changed- added
Output schema / properties / data_sourcesAdded value: +{ + "description": "Where the sources, licences and notices are for emails and owner names that may come from open datasets and public records. Pass it on with any of this data you share.", + "type": "string" +}
- Changed
query_leads1 field changed- added
Output schema / properties / data_sourcesAdded value: +{ + "description": "Where the sources, licences and notices are for emails and owner names that may come from open datasets and public records. Pass it on with any of this data you share.", + "type": "string" +}
- Changed
search_leads1 field changed- added
Output schema / properties / data_sourcesAdded value: +{ + "description": "Where the sources, licences and notices are for emails and owner names that may come from open datasets and public records. Pass it on with any of this data you share.", + "type": "string" +}
- Changed
update_automation1 field changed- added
Output schema / properties / data_sourcesAdded value: +{ + "description": "Where the sources, licences and notices are for emails and owner names that may come from open datasets and public records. Pass it on with any of this data you share.", + "type": "string" +}
6 tool updates
- Changed
create_automation2 fields changed- changed
Input schema / properties / spreadsheet_id / descriptionPrevious value: -"google_sheets only: append to this existing LeadMarina-created sheet."New value: +"google_sheets only: add each run to this existing LeadMarina-created sheet, updating rows already in it." - added
Output schema / properties / destination / descriptionAdded value: +"The destination as saved — what each run will actually use."
- Changed
enrich_domains1 field changed- added
Output schema / properties / noteAdded value: +{ + "description": "Present when a delivered domain was listed more than once, or when the balance left some domains out (named, not charged).", + "type": "string" +}
- Changed
export_leads5 fields changed- added
Input schema / properties / cursorAdded value: +{ + "description": "Continue an export: the next_cursor a previous export_leads call returned. Pass it with the same search_id/all and filters.", + "type": "string" +} - changed
Input schema / properties / filters / descriptionPrevious value: -"With all=true: narrow the library using query_leads-style filter rows."New value: +"Optional query_leads-style filter rows: within the search when search_id is given, across the library with all=true." - added
Output schema / properties / next_cursorAdded value: +{ + "description": "Present when the per-call limit or this call's time limit left matching leads unsent: pass it as cursor, with the same destination, search_id/all and filters, to send them. It does not offer again a lead the destination refused (counted as failed in outcome).", + "type": "string" +} - added
Output schema / properties / not_sentAdded value: +{ + "description": "Leads of this batch the destination's time limit did not reach.", + "type": "number" +} - changed
Output schema / properties / warning / descriptionPrevious value: -"Present when truncated: what happened and how to get the rest."New value: +"Present when the per-call limit or this call's time limit left leads unsent: what happened and how to send them. Leads the destination refused are not covered here — outcome counts them as failed."
- Changed
get_search_results9 fields changed- added
Output schema / properties / results / items / properties / addressAdded value: +{ + "description": "Street address from the Google listing.", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / results / items / properties / claimedAdded value: +{ + "description": "Whether the owner has claimed the Google listing.", + "type": [ + "boolean", + "null" + ] +} - added
Output schema / properties / results / items / properties / email_statusAdded value: +{ + "description": "Email 1's SMTP verdict: safe | risky | invalid | unknown.", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / results / items / properties / google_cidAdded value: +{ + "description": "Google listing id (the query_leads google_cid field).", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / results / items / properties / maps_urlAdded value: +{ + "description": "The Google Maps link for the listing.", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / results / items / properties / phoneAdded value: +{ + "description": "The Google Maps number.", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / results / items / properties / phone_line_typeAdded value: +{ + "description": "Phone 1's line type: mobile, fixed_line, voip or toll_free usually; also unknown, fixed_line_or_mobile and the other values query_leads lists.", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / results / items / properties / primary_emailAdded value: +{ + "description": "Email 1: the first address in emails_data, the one email_status describes. Before emails are verified, the lead's primary address.", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / results / items / properties / primary_phoneAdded value: +{ + "description": "Phone 1: the first number in phones_data, the one phone_line_type describes. Before phones are verified, the lead's primary number, or its Google Maps number.", + "type": [ + "string", + "null" + ] +}
- Changed
query_leads16 fields changed- changed
Input schema / properties / cursor / descriptionPrevious value: -"Opaque pagination cursor from a previous call."New value: +"next_cursor from the previous call, for the next page. It carries that call's filters and sort: send it alone, or with the same filters and sort — different ones are refused. Leave it out to start a new query." - changed
Input schema / properties / filters / descriptionPrevious value: -"Filter conditions (optional — omit for everything, newest data first)."New value: +"Conditions, each {field, operator, value, conj}; omit to match every lead. text fields [operators: contains, not_contains, is, is_not, is_empty, is_not_empty]: name, category, city, state, address, website, primary_email (or email_1), email_2, email_3, primary_phone (or phone_1), phone_carrier (or phone_1_carrier), phone_2, phone_2_carrier, phone_3, phone_3_carrier, owner_name, social_facebook, social_instagram, social_linkedin, social_x, social_youtube, social_tiktok, social_yelp, gbp_url, google_cid, logo_url, main_image_url. number fields [operators: eq, neq, gt, gte, lt, lte, is_empty, is_not_empty]: rank, rating, reviews. yes/no fields [operators: is_true, is_false, is_empty, is_not_empty]: claimed. choice fields [operators: is, is_not, is_empty, is_not_empty]: email_status (or email_1_status), email_2_status, email_3_status take safe, risky, invalid, unknown; phone_line_type (or phone_1_type), phone_2_type, phone_3_type take mobile, fixed_line (Landline), fixed_line_or_mobile (Landline or mobile), voip, non_fixed_voip, toll_free (Toll-free), premium_rate, shared_cost, personal_number (Personal), pager, uan, voicemail, unknown. value is one string (a number as text, e.g. '4.5'); is_empty, is_not_empty, is_true and is_false take none. Text matching ignores case. Phone fields compare digits, so '(512) 555' finds +15125550100; website is / is_not compare domains when given a domain ('acme.com', or 'https://www.acme.com/'), and whole addresses when given a path, a query or a fragment ('acme.com/locations/austin'), either way ignoring http(s)://, www. and a closing slash. conj ('and' or 'or') joins a condition to the one before it, and 'and' binds tighter: A and B or C means (A and B) or C. To match any of several values, send one condition per value joined with conj 'or', repeating the other conditions in each group." - changed
Input schema / properties / limit / descriptionPrevious value: -"Max leads to return (default 25, max 1000)."New value: +"Max leads to return (default 25, max 1,000)." - added
Input schema / properties / search_idAdded value: +{ + "description": "Only this search's leads (a search_id from search_leads or list_searches) — e.g. to narrow one search before export_leads with the same search_id and filters. Omit to query the whole library.", + "type": "string" +} - changed
Input schema / properties / sort / descriptionPrevious value: -"Sort keys, e.g. [{id:'reviews',dir:-1}]. Optional."New value: +"Sort keys in priority order, e.g. [{id:'reviews',dir:-1}] for most-reviewed first. id is any filter field id (the column ids email_1, email_1_status, phone_1, phone_1_type and phone_1_carrier work too); dir is 1 ascending (the default) or -1 descending. A lead with no value for a key (null) sorts after the leads that have one, in either direction — except social_facebook, social_instagram, social_linkedin, social_x, social_youtube, social_tiktok, social_yelp, gbp_url, logo_url, main_image_url, which sort by whether a lead has one, not by the link: ascending puts the leads WITHOUT one first, so use dir -1 to put the leads that have one first. Without a sort the order is arbitrary but stable." - changed
Output schema / properties / next_cursor / descriptionPrevious value: -"Pass back as 'cursor' for the next page."New value: +"Pass back as 'cursor' for the next page (it carries the filters and sort); null on the last page." - added
Output schema / properties / results / items / properties / addressAdded value: +{ + "description": "Street address from the Google listing.", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / results / items / properties / claimedAdded value: +{ + "description": "Whether the owner has claimed the Google listing.", + "type": [ + "boolean", + "null" + ] +} - added
Output schema / properties / results / items / properties / email_statusAdded value: +{ + "description": "Email 1's SMTP verdict: safe | risky | invalid | unknown.", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / results / items / properties / google_cidAdded value: +{ + "description": "Google listing id (the query_leads google_cid field).", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / results / items / properties / maps_urlAdded value: +{ + "description": "The Google Maps link for the listing.", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / results / items / properties / phoneAdded value: +{ + "description": "The Google Maps number.", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / results / items / properties / phone_line_typeAdded value: +{ + "description": "Phone 1's line type: mobile, fixed_line, voip or toll_free usually; also unknown, fixed_line_or_mobile and the other values query_leads lists.", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / results / items / properties / primary_emailAdded value: +{ + "description": "Email 1: the first address in emails_data, the one email_status describes. Before emails are verified, the lead's primary address.", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / results / items / properties / primary_phoneAdded value: +{ + "description": "Phone 1: the first number in phones_data, the one phone_line_type describes. Before phones are verified, the lead's primary number, or its Google Maps number.", + "type": [ + "string", + "null" + ] +} - changed
Output schema / properties / total_matching / descriptionPrevious value: -"Exact match count (first page only; absent on later pages)."New value: +"Exact match count — on the first page only; null on later pages."
- Changed
search_leads8 fields changed- changed
Input schema / properties / location / descriptionPrevious value: -"City, e.g. 'Austin, TX'. Ignored if location_code is given."New value: +"City, e.g. 'Austin, TX'. Not needed with location_code, which is always what is searched." - changed
Input schema / properties / location_code / descriptionPrevious value: -"Optional exact location code (skips the city lookup)."New value: +"Optional exact location code. When given, it is what is searched, whatever location says. Sent with location, the search is named after the code's own place (or after location when the code's own name cannot be looked up); sent alone, the search is unnamed and location comes back null." - added
Output schema / properties / cappedAdded value: +{ + "description": "True when the lead balance covered fewer leads than were found — relay this to the user.", + "type": "boolean" +} - added
Output schema / properties / discoveryAdded value: +{ + "description": "'complete', or 'in_progress' when the search was queued whole.", + "type": "string" +} - changed
Output schema / properties / enrichment / descriptionPrevious value: -"'pending' until background verification finishes."New value: +"'pending' until background verification finishes; 'complete' at once when nothing was found." - added
Output schema / properties / foundAdded value: +{ + "description": "Listings found in the first batch, before the balance capped delivery.", + "type": "number" +} - added
Output schema / properties / location / descriptionAdded value: +"The place searched, as the location list names it (the location sent, when a code's own name could not be looked up); null for a location_code sent alone." - added
Output schema / properties / resultsAdded value: +{ + "description": "The first batch, as delivered — contacts are verified in the background (get_search_results).", + "items": { + "properties": { + "category": { + "type": [ + "string", + "null" + ] + }, + "city": { + "type": [ + "string", + "null" + ] + }, + "emails_data": { + "description": "Verified emails with SMTP status." + }, + "enrichment_status": { + "type": [ + "string", + "null" + ] + }, + "name": { + "type": [ + "string", + "null" + ] + }, + "owner_name": { + "type": [ + "string", + "null" + ] + }, + "phones_data": { + "description": "Verified phones with line type + carrier." + }, + "rating": { + "type": [ + "number", + "null" + ] + }, + "reviews": { + "type": [ + "number", + "null" + ] + }, + "socials": { + "description": "Social profile links keyed by platform." + }, + "state": { + "type": [ + "string", + "null" + ] + }, + "website": { + "type": [ + "string", + "null" + ] + } + }, + "type": "object" + }, + "type": "array" +}
2 tool updates
- Changed
get_search_results2 fields changed- added
Output schema / properties / leads_remaining / descriptionAdded value: +"Leads spendable now. On a plan with no monthly quota this is what is left in the current 7-day period, not a monthly balance." - added
Output schema / properties / periodAdded value: +{ + "description": "On a rate-limited plan: { limit, used, resets_at }. Null on a metered plan.", + "type": [ + "object", + "null" + ] +}
- Changed
search_leads1 field changed- added
Output schema / properties / leads_remaining / descriptionAdded value: +"Leads spendable now. On a plan with no monthly quota this is what is left in the current 7-day period."
1 tool update
- Changed
get_balance3 fields changed- added
Output schema / properties / period_limitAdded value: +{ + "type": "number" +} - added
Output schema / properties / period_resets_atAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / period_usedAdded value: +{ + "type": "number" +}
1 tool update
- Changed
get_search_results1 field changed- added
Output schema / properties / next_offsetAdded value: +{ + "description": "Pass as offset to fetch the next page; null on the last page.", + "type": [ + "number", + "null" + ] +}
1 tool update
- Changed
get_search_results3 fields changed- added
Output schema / properties / progressAdded value: +{ + "description": "{ done, total } rows enriched so far.", + "type": [ + "object", + "null" + ] +} - added
Output schema / properties / queue_positionAdded value: +{ + "description": "For queued searches, the place in this account's own queue (1 = next).", + "type": [ + "number", + "null" + ] +} - added
Output schema / properties / stageAdded value: +{ + "description": "queued | discovering | enriching | verifying | complete | failed | cancelled. 'verifying' means every row is delivered and contacts are being verified — often the longest phase, not a stall.", + "type": "string" +}
7 tool updates
- Added
create_automation - Added
delete_automation - Changed
export_leads4 fields changed- changed
Input schema / properties / all / descriptionPrevious value: -"Export the whole library instead. Exports write a file, so there is no row cap."New value: +"Export the whole library instead of one search." - added
Output schema / properties / limitAdded value: +{ + "description": "The per-call limit that applied, when truncated.", + "type": "number" +} - added
Output schema / properties / truncatedAdded value: +{ + "description": "True when more leads matched than this destination's limit — the export was PARTIAL.", + "type": "boolean" +} - added
Output schema / properties / warningAdded value: +{ + "description": "Present when truncated: what happened and how to get the rest.", + "type": "string" +}
- Added
list_automations - Added
list_integrations - Added
list_views - Added
update_automation
3 tool updates
- Changed
export_leads1 field changed- changed
Input schema / properties / all / descriptionPrevious 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."
- Changed
get_search_results1 field changed- changed
Input schema / properties / limit / descriptionPrevious value: -"Max leads to return (default 25, max 100)."New value: +"Max leads to return (default 25, max 1000)."
- Changed
query_leads1 field changed- changed
Input schema / properties / limit / descriptionPrevious value: -"Max leads to return (default 25, max 100)."New value: +"Max leads to return (default 25, max 1000)."
7 tool updates
- First observed
enrich_domains - First observed
export_leads - First observed
get_balance - First observed
get_search_results - First observed
list_searches - First observed
query_leads - First observed
search_leads
Related MCP Connectors
Finds, filters, and verifies local-business leads; every email carries a verification receipt.
Find local businesses, companies and decision makers with verified emails for B2B outreach.
Find local businesses, enrich them with emails and socials, and run lead pipelines from your AI.
Local business lead extraction with email + phone enrichment from Google Maps.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceFinds, 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
- AlicenseNot gradedqualityFmaintenanceEnables searching 12M+ verified businesses across 10 countries and 19 directories, with tools for lead generation, competitive analysis, and market research.13 PyPIMIT
- AlicenseNot gradedqualityCmaintenanceDiscovers local businesses needing a website via OpenStreetMap and verifies their leads with checks like website existence, email deliverability, and site quality scoring.25 PyPIMIT

LocalPro MCP Serverofficial
AlicenseNot gradedqualityBmaintenanceProvides verified local trade and service business data (e.g., radon mitigation, foundation repair) to AI agents via tools like search_providers and list_niches.1MIT
Glama MCP Gateway
Add one secure layer between your agents and this server.