> ## Documentation Index
> Fetch the complete documentation index at: https://breadbox-mintlify-21ca817c.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# MCP tools for querying financial data

> A human-readable walkthrough of the MCP tools an agent is most likely to use against Breadbox — so you know exactly what surface area you're granting an AI client. See the MCP Reference tab for the full enumeration.

This page is for **you** — the person deciding what to hand an agent. Agents receive these tool schemas at inference time and don't need to read this page; they see the parameters, descriptions, and JSON schemas directly through the MCP protocol. Use this reference to understand the surface area a connected AI client can touch, so you can pick the right API-key scope and know what will show up in your audit log.

<Note>
  **Looking for the full tool list?** This page walks through the handful of tools you're most likely to care about as a human. For the complete enumeration of every MCP tool with full parameters, examples, and scope labels, see the [MCP Reference](/mcp/reference/overview) tab.
</Note>

<Note>
  **Amount convention:** Amounts follow Plaid's convention. Positive values are debits (money leaving an account). Negative values are credits (money entering). If an agent talks about "total spend," it's summing positive amounts only.
</Note>

## What a typical agent session looks like

An agent connected to Breadbox usually opens a session by orienting itself before it starts querying. First it calls `list_users` and `list_accounts` to see who's in the household and which accounts exist — this gives it the IDs it needs to filter anything downstream. Then, before pulling rows, it calls `count_transactions` with its intended filters so it knows whether to expect fifty results or five thousand. Only then does it call `query_transactions`, paginating with the returned cursor if `has_more` is `true`.

That pattern — orient, size, query — keeps token usage predictable and matches how Breadbox's tools are designed. You don't need to enforce it from the outside; the tool descriptions nudge the agent toward it.

***

## `list_accounts`

Lists all connected bank accounts with their current balances. An agent typically calls this early in a session to learn what accounts exist and get their IDs.

**Scope:** Read

**Input parameters**

| Parameter | Type   | Required | Description                                                                    |
| --------- | ------ | -------- | ------------------------------------------------------------------------------ |
| `user_id` | string | No       | Return only accounts owned by this family member. Omit to return all accounts. |

**Example input**

```json theme={null}
{ "user_id": "usr_abc123" }
```

**Example output**

```json theme={null}
{
  "accounts": [
    {
      "id": "acc_xyz789",
      "name": "Chase Checking",
      "type": "depository",
      "subtype": "checking",
      "mask": "4321",
      "balance_current": 2450.18,
      "balance_available": 2380.00,
      "balance_limit": null,
      "iso_currency_code": "USD",
      "institution_name": "Chase",
      "user_id": "usr_abc123"
    },
    {
      "id": "acc_def456",
      "name": "Amex Gold",
      "type": "credit",
      "subtype": "credit card",
      "mask": "1008",
      "balance_current": -541.20,
      "balance_available": null,
      "balance_limit": 10000.00,
      "iso_currency_code": "USD",
      "institution_name": "American Express",
      "user_id": "usr_abc123"
    }
  ]
}
```

<Note>
  For credit accounts, `balance_current` represents the amount owed, not available funds. Amounts across different `iso_currency_code` values should not be summed.
</Note>

***

## `query_transactions`

Searches transactions using a combination of filters. Results are cursor-paginated with a default page size of 50 and a maximum of 500. This is the workhorse tool — almost every non-trivial agent session goes through it.

**Scope:** Read

**Input parameters**

| Parameter       | Type                | Required | Description                                                                                                                                              |
| --------------- | ------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `start_date`    | string (YYYY-MM-DD) | No       | Include transactions on or after this date (inclusive).                                                                                                  |
| `end_date`      | string (YYYY-MM-DD) | No       | Include transactions before this date (exclusive). To cover all of January, pass `2025-02-01`.                                                           |
| `account_id`    | string              | No       | Filter to a specific account.                                                                                                                            |
| `user_id`       | string              | No       | Filter to accounts owned by this family member.                                                                                                          |
| `category_slug` | string              | No       | Filter by category slug (e.g., `food_and_drink`). Parent slugs include all children. See [MCP: categories](/mcp/reference/categories) for the full list. |
| `min_amount`    | number              | No       | Minimum transaction amount in USD. Zero is a valid value.                                                                                                |
| `max_amount`    | number              | No       | Maximum transaction amount in USD. Zero is a valid value.                                                                                                |
| `pending`       | boolean             | No       | `true` returns only pending transactions; `false` returns only posted. Omit for both.                                                                    |
| `search`        | string              | No       | Full-text search over merchant name and description.                                                                                                     |
| `sort_by`       | string              | No       | Sort field: `date` (default), `amount`, or `provider_name`. Cursor pagination requires `date`.                                                           |
| `sort_order`    | string              | No       | Sort direction: `desc` (default) or `asc`.                                                                                                               |
| `limit`         | integer             | No       | Results per page. Default: 50. Maximum: 500.                                                                                                             |
| `cursor`        | string              | No       | Pagination cursor from the previous response. Omit for the first page.                                                                                   |

**Example input**

```json theme={null}
{
  "start_date": "2025-01-01",
  "end_date": "2025-02-01",
  "category_slug": "food_and_drink",
  "limit": 50
}
```

**Example output**

```json theme={null}
{
  "transactions": [
    {
      "id": "txn_111222333",
      "account_id": "acc_xyz789",
      "account_name": "Chase Checking",
      "user_name": "Alice",
      "amount": 14.50,
      "iso_currency_code": "USD",
      "date": "2025-01-15",
      "authorized_date": "2025-01-14",
      "merchant_name": "Blue Bottle Coffee",
      "name": "BLUE BOTTLE COFFEE #12",
      "category_primary": "FOOD_AND_DRINK",
      "category_detailed": "FOOD_AND_DRINK_COFFEE",
      "payment_channel": "in store",
      "pending": false
    }
  ],
  "next_cursor": "dHhuXzExMTIyMzM0",
  "has_more": true,
  "limit": 50
}
```

When there are no more pages, the response includes `"has_more": false` and `"next_cursor": null`.

<Note>
  Each transaction object is roughly 50 tokens. At the default page size of 50, one call returns approximately 2,500 tokens of content. At the maximum of 500, a single call can reach 25,000 tokens. If your agent pulls large result sets unfiltered, your context budget will disappear fast.
</Note>

**Page size guidance**

| Use case                  | Recommended `limit` |
| ------------------------- | ------------------- |
| Sampling or spot-checking | 25                  |
| Single-month analysis     | 50 (default)        |
| Full dataset processing   | 200–500             |
| Maximum allowed           | 500                 |

***

## `count_transactions`

Counts matching transactions without returning any transaction data. Accepts the same filters as `query_transactions` (excluding `cursor`, `limit`, `sort_by`, and `sort_order`). It's the cheap pre-flight an agent uses to decide whether to narrow filters or brace for pagination.

**Scope:** Read

**Input parameters**

| Parameter       | Type                | Required | Description                                                                                  |
| --------------- | ------------------- | -------- | -------------------------------------------------------------------------------------------- |
| `start_date`    | string (YYYY-MM-DD) | No       | Count transactions on or after this date (inclusive).                                        |
| `end_date`      | string (YYYY-MM-DD) | No       | Count transactions before this date (exclusive). To cover all of January, pass `2025-02-01`. |
| `account_id`    | string              | No       | Filter to a specific account.                                                                |
| `user_id`       | string              | No       | Filter to accounts owned by this family member.                                              |
| `category_slug` | string              | No       | Filter by category slug. Parent slugs include all children.                                  |
| `min_amount`    | number              | No       | Minimum transaction amount.                                                                  |
| `max_amount`    | number              | No       | Maximum transaction amount.                                                                  |
| `pending`       | boolean             | No       | Filter by pending status.                                                                    |
| `search`        | string              | No       | Full-text search over merchant name and description.                                         |

**Example input**

```json theme={null}
{
  "start_date": "2025-01-01",
  "end_date": "2025-02-01"
}
```

**Example output**

```json theme={null}
{ "count": 347 }
```

***

## `list_categories`

Returns the Breadbox category taxonomy as a flat list. Each category has a stable `slug` — the handle agents pass to `query_transactions` and `count_transactions` to filter by category, and to rule actions to set a category.

**Scope:** Read

**Input parameters**

None. Pass an empty object.

**Example input**

```json theme={null}
{}
```

**Example output**

```json theme={null}
{
  "categories": [
    {
      "id": "cat_abc123",
      "slug": "food_and_drink",
      "display_name": "Food & Drink",
      "parent_id": null,
      "icon": "utensils",
      "color": "#f97316",
      "is_system": true
    },
    {
      "id": "cat_def456",
      "slug": "food_and_drink_groceries",
      "display_name": "Groceries",
      "parent_id": "cat_abc123",
      "parent_slug": "food_and_drink",
      "icon": "shopping-cart",
      "color": "#f97316",
      "is_system": true
    }
  ]
}
```

Pass a category `slug` as the `category_slug` parameter in `query_transactions` and `count_transactions` to filter by category. Parent slugs (e.g., `food_and_drink`) include all child categories automatically.

***

## `list_users`

Lists all family members tracked in Breadbox. Users are labels for account ownership — they are not login accounts. Returned IDs are what an agent uses to filter accounts and transactions by person.

**Scope:** Read

**Input parameters**

None. Pass an empty object.

**Example input**

```json theme={null}
{}
```

**Example output**

```json theme={null}
{
  "users": [
    {
      "id": "usr_abc123",
      "name": "Alice",
      "email": "alice@example.com"
    },
    {
      "id": "usr_def456",
      "name": "Bob",
      "email": "bob@example.com"
    }
  ]
}
```

***

## `get_sync_status`

Returns the health status of all bank connections: whether they are syncing successfully, when they last synced, and whether any connection needs re-authentication. This is how an agent answers "why don't I see yesterday's transactions?" without guessing.

**Scope:** Read

**Input parameters**

None. Pass an empty object.

**Example input**

```json theme={null}
{}
```

**Example output**

```json theme={null}
{
  "connections": [
    {
      "id": "conn_aaa111",
      "institution_name": "Chase",
      "provider": "plaid",
      "status": "active",
      "last_synced_at": "2025-01-20T14:32:00Z",
      "error_message": null,
      "accounts_count": 3
    },
    {
      "id": "conn_bbb222",
      "institution_name": "Bank of America",
      "provider": "plaid",
      "status": "error",
      "last_synced_at": "2025-01-18T09:15:00Z",
      "error_message": "ITEM_LOGIN_REQUIRED: User must re-authenticate via Plaid Link.",
      "accounts_count": 2
    }
  ]
}
```

**Status values**

| Status           | Meaning                                                                |
| ---------------- | ---------------------------------------------------------------------- |
| `active`         | Connection is healthy and syncing normally.                            |
| `error`          | Last sync failed. Check `error_message` for details.                   |
| `pending_reauth` | Connection requires user re-authentication (e.g., bank login changed). |
| `disconnected`   | Connection has been disconnected or removed.                           |

<Tip>
  To trigger a manual sync from outside an agent session, use `POST /api/v1/sync` (REST) or `breadbox sync trigger` (CLI). Breadbox does not expose a `trigger_sync` MCP tool — syncs run on the configured cron, and agents are expected to call `get_sync_status` to check freshness rather than kick off their own syncs.
</Tip>

***

## Series (subscriptions)

Breadbox detects recurring charges and groups them into [series](/guides/tracking-subscriptions). These tools are the agent-facing side of the **Recurring** page — they let a scheduled reviewer adjudicate what the detector proposed and fill in anything it missed. (The tool *names* stay `*_series` for API stability even though the surface is now called Recurring.)

| Tool                                   | Scope | What it does                                                                                                                                                                                                                                    |
| -------------------------------------- | ----- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `list_series`                          | Read  | List detected series. Filter by `status` (`active`, `candidate`, `paused`, `cancelled`); `candidate` surfaces the ones awaiting a verdict. Each row carries cadence, expected amount + currency, next expected date, and the detection signals. |
| `get_series`                           | Read  | Fetch one series by ID, including the full evidence the detector used.                                                                                                                                                                          |
| `explain_series_candidates`            | Read  | Answer "why isn't *X* recurring?" — lists recurring-looking merchants the precision-first detector skipped, with the reason (too few occurrences, irregular cadence, unstable amount, …).                                                       |
| `review_series`                        | Write | Apply a verdict: `confirm`, `reject` (sticky — never re-proposed at that amount band), `pause`, or `cancel`. A user's prior confirmation outranks a later agent verdict.                                                                        |
| `update_series`                        | Write | Edit a series' user-owned attributes: name, expected amount, cadence, expected day, category, or owner. Every field is optional; omit to leave unchanged. Edits survive future detection runs (the detector won't revert them).                 |
| `set_series_type`                      | Write | Set the series type: `subscription`, `bill`, `loan`, or `other`. Overrides the type the detector inferred from the charges' category; the override is sticky.                                                                                   |
| `assign_series`                        | Write | Create a series the detector missed, or back-link transactions to an existing one. Never steals a charge already in another series.                                                                                                             |
| `unlink_series_transactions`           | Write | Detach transactions from a series (inverse of `assign_series`). Clears the series link and strips inherited tags from the affected charges only.                                                                                                |
| `rekey_series`                         | Write | Fix a series grouped under a wrong or fallback merchant key (e.g. `payment` → `spotify`), repointing it and its charges.                                                                                                                        |
| `split_series`                         | Write | Break an over-grouped series in two — move stray charges into a new series (e.g. a $4.99 add-on swept into a $139/yr renewal).                                                                                                                  |
| `add_series_tag` / `remove_series_tag` | Write | Tag a series; every linked transaction inherits the tag automatically. Removing strips only the inherited copies.                                                                                                                               |

<Note>
  A typical reviewer agent calls `list_series(status="candidate")`, inspects each with `get_series`, and resolves it with `review_series` — the same confirm/reject loop a person runs on the Recurring page.
</Note>
