> ## Documentation Index
> Fetch the complete documentation index at: https://docs.spherescout.io/llms.txt
> Use this file to discover all available pages before exploring further.

# MCP tool reference

> Inputs, outputs, classification, side effects and errors of every tool on the SphereScout MCP server.

The [SphereScout MCP server](https://docs.spherescout.io/mcp/overview.md) has 12 tools. Ten only read data. Two start exports, which spend credits.

## Classification

| Tool | Classification | Scope | Cost |
| - | - | - | - |
| [`find_category`](#find_category) | Read | `leads:read` | Free |
| [`list_countries`](#list_countries) | Read | `leads:read` | Free |
| [`find_location`](#find_location) | Read | `leads:read` | Free |
| [`list_locations`](#list_locations) | Read | `leads:read` | Free |
| [`preview_businesses`](#preview_businesses) | Read | `leads:read` | Free |
| [`get_account`](#get_account) | Read | `leads:read` | Free |
| [`start_export`](#start_export) | Sensitive write | `leads:export` | 1 credit per business |
| [`get_export`](#get_export) | Read | `leads:read` | Free |
| [`read_export_rows`](#read_export_rows) | Read | `leads:read` | Free |
| [`list_exports`](#list_exports) | Read | `leads:read` | Free |
| [`check_export_updates`](#check_export_updates) | Read | `leads:read` | Free |
| [`start_update_export`](#start_update_export) | Sensitive write | `leads:export` | 1 credit per business |

* **Read** tools return data and change nothing in the account. Their MCP annotations are `readOnlyHint: true`, `destructiveHint: false`, `idempotentHint: true`.
* **Sensitive write** tools spend credits, which can't be undone, and save a file to the account. They need the user's approval every time. Their annotations are `readOnlyHint: false`, `destructiveHint: true`, `idempotentHint: false`.
* Every tool works only on SphereScout's own database and the signed-in account: `openWorldHint: false`.

> [!NOTE]
>
> The export tools only charge what the user approved. Pass the count the user saw (`export_quote_id` or `expected_credits`): if the search grew, the export is refused or fails without charging, and the answer gives the new cost to approve.

## Search

### find\_category

Finds the category for a kind of business. Categories are named in English.

| Input | Type | Description |
| - | - | - |
| `query` | string, required | English term, such as `plumber` or `dentist`. |
| `limit` | integer, 1–50 | Number of results. Default 20. |

**Returns** `categories`, each with `category_id`, `name`, `match_rank` (0 is an exact match), `matched_field`, `matched_value` and `substring_only` (true when the term only appears inside another word).

**Errors** `invalid_argument`.

### list\_countries

Lists the countries SphereScout covers. No inputs.

**Returns** `countries`, each with `country` (ISO alpha-2 code) and `name`.

### find\_location

Finds a city, county or region by name. Places are stored under their local-language names (München, Lisboa).

| Input | Type | Description |
| - | - | - |
| `query` | string, required | Place name. `Austin, Texas` also narrows to the state. |
| `country` | string, required | ISO alpha-2 code. |
| `within_state_id` | integer | Search only inside this state or region. |
| `within_county_id` | integer | Search only inside this county. |

**Returns** `locations`, each with `location_ref` (`level` and `id`, used in `filters.locations`), `name`, `kind` (state/region, county/department or city/commune), its `state` and `county`, and `exact_name`. The answer can add:

* `needs_clarification`, `clarify_on` and `clarification_hint` when the name is ambiguous;
* `namesakes` when several places share the name and level;
* `city_zones` when a city is stored as several zones, with all of them;
* `big_city` when a big city's neighborhoods are stored under their own names, with those places.

**Errors** `invalid_argument`, `invalid_country`, `country_not_covered`.

### list\_locations

Lists every place of one level: all states, all counties in a state, or all cities in a county.

| Input | Type | Description |
| - | - | - |
| `country` | string, required | ISO alpha-2 code. |
| `level` | integer, required | `1` state or region, `2` county, `3` city. |
| `parent_id` | integer | State id for level 2, county id for level 3. |

**Returns** `kind`, `count` and `locations`, each with `location_ref` and `name`.

**Errors** `invalid_argument`, `invalid_country`, `country_not_covered`.

### preview\_businesses

Counts businesses by category and place, and gives what an export of them would cost.

| Input | Type | Description |
| - | - | - |
| `filters` | object, required | Who to find. See below. |
| `include_sample` | boolean | Add 10 example businesses, with emails and phones hidden. |
| `page` | integer | Browse the matches 50 at a time. |
| `include_contact_coverage` | boolean | Count emails and phones on searches above 20,000 matches too (slower). |

`filters` takes:

| Filter | Type | Description |
| - | - | - |
| `country` | string, required | ISO alpha-2 code. |
| `category_id` or `category_ids` | integer, or up to 20 integers | From `find_category`. A business tagged with any of the categories counts once. |
| `locations` | array of `location_ref` | From `find_location` or `list_locations`, all of one level. |
| `has_email`, `has_phone`, `has_email_or_phone`, `has_mobile_phone`, `has_website`, `has_facebook`, `has_instagram`, `has_linkedin`, `has_x`, `has_delivery` | boolean | `true` keeps businesses that have it, `false` those without. Omit for either. |
| `main_activity_only` | boolean | Only businesses whose main activity is the category. |
| `personal_email_only` | boolean | Only named email addresses (no info@ or contact@). Not included in every plan. |
| `closed_businesses` | string | `exclude` (default), `include` or `only`. |

**Returns**

* `count` and `credit_cost` (the same number: one credit per business);
* `search`, the search in words, and `country_data_updated`;
* `contact_coverage`: how many have an email, a phone, both, either or neither (up to 20,000 matches, or on request);
* `sample` or the requested `page`;
* for accounts that can export, an `export` block with an `export_quote_id` valid for 15 minutes, a `confirm_with` sentence for the user's approval, and cheaper `alternatives` (only businesses with an email, a phone, or either), each with its own quote;
* for accounts that can't, `export.available: false` and a `plans_url`.

**Side effects** None. The quote is kept for 15 minutes so `start_export` can use it.

**Errors** `invalid_argument`, `invalid_country`, `country_not_covered`, `personal_email_filter_requires_plan`.

### get\_account

Shows the signed-in account's plan and credits. No inputs.

**Returns** `email`, `plan`, `subscription_status`, `access` (`full` or `free`), `can_export`, `can_filter_personal_emails`, `export_credits_available`, and `plans_url` for free accounts.

## Export

### start\_export

> [!WARNING]
>
> Sensitive write: spends credits. Ask the user to approve the `confirm_with` sentence from `preview_businesses` before every call.

Exports businesses with their contacts to a file in the signed-in account.

| Input | Type | Description |
| - | - | - |
| `destination` | string, required | Must be `connected_spherescout_account`. |
| `export_quote_id` | string | From `preview_businesses`. Exports exactly that preview. |
| `filters` | object | Only without `export_quote_id`. Same as `preview_businesses`. |
| `expected_credits` | integer | With `filters`: the count the user approved. |
| `max_rows` | integer, up to 500,000 | Export only this many businesses, for that many credits. |
| `include_additional_fields` | boolean | Add coordinates, rating, review count, claimed status, opening hours and business status columns. Same price. |
| `export_format` | string | `csv` (default) or `excel`. |

**Side effects**

* Spends 1 credit per exported business, never more than the approved count.
* Saves the file to the account's export history.
* Emails the account owner when the file is ready or if the export fails. Both emails can be turned off under **Email notifications** on the plans page of the dashboard.
* Calling again with the same arguments within 15 minutes returns the same export with `already_started: true` and no new charge.

**Returns** `search_id`, `status`, `credits_charged` and `destination` (the account and its export history). A small export comes back `completed` with the fields of [`get_export`](#get_export); otherwise poll `get_export` after `poll_after_seconds`.

**Errors** `invalid_argument`, `quote_invalid`, `quote_expired`, `credit_cost_changed`, `insufficient_credits`, `no_leads_found`, `export_in_progress`, `personal_email_filter_requires_plan`, `api_subscription_required`, `insufficient_scope`.

### get\_export

Returns an export's status and, once it's ready, its file.

| Input | Type | Description |
| - | - | - |
| `search_id` | integer, required | From `start_export`, `start_update_export` or `list_exports`. |

**Returns** `search_id`, `status` and `row_count`. Then, depending on the [status](https://docs.spherescout.io/mcp/overview.md#export-statuses):

* `pending` or `processing`: `poll_after_seconds`;
* `completed`: `credits_charged`, `download_url` (no sign-in needed), `download_expires_at` (7 days after the file was made), `file_size_mb`, `filename`, `search` and `columns`;
* `failed`: `failure`, `user_message` and `credits_refunded`. An update export that grew beyond its approved credits fails with `credit_limit_exceeded` and gives `required_credits`; one with nothing new fails with `no_fresh_data`. Neither is charged.

**Errors** `search_not_found`, `download_expired`.

### read\_export\_rows

Returns the rows of a finished export, with their contacts. The export is already paid for, so reading it is free.

| Input | Type | Description |
| - | - | - |
| `search_id` | integer, required | A completed export of the account. |
| `page` | integer | Default 1. |
| `page_size` | integer, 1–200 | Default 50. |
| `columns` | array of strings | Columns to return, from `get_export`. Default: all. |

**Returns** `total_rows`, `page`, `pages`, `columns` and `rows`. Empty cells are left out of each row.

**Errors** `invalid_argument`, `search_not_found`, `download_expired`.

## Export history

### list\_exports

Lists the account's past exports, newest first.

| Input | Type | Description |
| - | - | - |
| `limit` | integer, 1–50 | Default 10. |
| `page` | integer | Default 1. |

**Returns** `exports`, each with `search_id`, `title` (category · place), `created_at`, `status`, `rows`, `credits_charged`, `format`, `file_available`, `download_expires_at`, and the `updates` made from it.

### check\_export\_updates

Counts what changed in a past export's list since it was last exported, and what exporting only those businesses would cost.

| Input | Type | Description |
| - | - | - |
| `search_id` | integer, required | Any export of the list, from `list_exports`. |

**Returns** `has_updates`, `credit_cost`, `changes` (new businesses, businesses with their first email, new emails, new phones), `since` and `checked_at`. With a plan that includes update exports, an `update_export` block gives `expected_credits` and a `confirm_with` sentence; otherwise `update_export.available: false` and a `plans_url`.

**Side effects** None. A list is checked at most once a day; a later call returns the latest check and `next_check_at`.

**Errors** `search_not_found`.

### start\_update\_export

> [!WARNING]
>
> Sensitive write: spends credits. Ask the user to approve the `confirm_with` sentence from `check_export_updates` before every call.

Exports only the businesses that changed since a past export, to a file in the signed-in account.

| Input | Type | Description |
| - | - | - |
| `search_id` | integer, required | Any export of the list. |
| `expected_credits` | integer, required | The cost the user approved, from `check_export_updates`. |
| `destination` | string, required | Must be `connected_spherescout_account`. |
| `export_format` | string | `csv` or `excel`. Default: the format of the original export. |

**Side effects**

* Spends 1 credit per exported business, at most `expected_credits`. If the update grew beyond it, nothing is charged and `get_export` gives the new cost.
* Saves the file to the account's export history.
* Emails the account owner when the file is ready or if the export fails. Both emails can be turned off under **Email notifications** on the plans page of the dashboard.
* Calling again with the same arguments within 15 minutes returns the same export.

**Returns** `search_id`, `status`, `credit_limit` and `destination`. Poll [`get_export`](#get_export) for the file.

**Errors** `invalid_argument`, `search_not_found`, `insufficient_credits`, `fresh_export_subscription_required`, `api_subscription_required`, `insufficient_scope`.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.