> ## Documentation Index
> Fetch the complete documentation index at: https://breadbox-mintlify-7401d007.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 `query_transactions` with `count_only: true` and its intended filters so it knows whether to expect fifty results or five thousand. Only then does it call `query_transactions` for real, 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                 |

***

## Counting without paginating: `query_transactions(count_only=true)`

There's no separate `count_transactions` tool. To get just a count for a given set of filters, call `query_transactions` with `count_only: true` and the same filters you'd otherwise use. The response is `{"count": N}` with no rows, no pagination, and no cursor — `cursor`, `limit`, `sort_by`, `sort_order`, and `fields` are ignored. It's the cheap pre-flight an agent uses to decide whether to narrow filters or brace for pagination.

**Example input**

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

**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` 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` 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 groups recurring charges into [series](/guides/tracking-subscriptions). A series is a thin surrogate identity (id, name, type) — its membership is maintained by `assign_series` rules in the rule engine, not by a built-in detector. These tools are the agent-facing side of the **Recurring** page; an agent uses them to mint or rename a series and to one-off-link or unlink specific charges.

| Tool                         | Scope | What it does                                                                                                                                                                                                                                                                                                                                                                                                                              |
| ---------------------------- | ----- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `list_series`                | Read  | List recurring series. Lean by default (`name`, `type`); pass `fields=all` for the full row. Use `query_transactions` with a `series_id` filter to enumerate a series' charges.                                                                                                                                                                                                                                                           |
| `get_series`                 | Read  | Fetch one series by short ID or UUID.                                                                                                                                                                                                                                                                                                                                                                                                     |
| `assign_series`              | Write | Link transactions to a series, creating it if needed. Provide `series_id` to assign to an existing series, or `series_name` + `create_if_missing: true` to mint one (surrogate-first — the same name always resolves the same series). Optional `type` (`subscription`, `bill`, `loan`, `other`) for a minted series. `transaction_ids` (≤50) back-link members; an `assign_series` call never steals a charge already in another series. |
| `update_series`              | Write | Edit a series' `name` and/or `type`. Both optional; omit to leave unchanged. Renaming onto another live series' name is rejected — the name is the series' unique mint key.                                                                                                                                                                                                                                                               |
| `unlink_series_transactions` | Write | Detach transactions (≤50) from a series — the inverse of `assign_series`. Each listed transaction must currently belong to the series; the call errors out otherwise so it can't silently touch the wrong rows.                                                                                                                                                                                                                           |

<Note>
  When you want every future charge from a merchant to land in a series automatically, encode that as an `assign_series` rule via `create_transaction_rule` instead of calling `assign_series` for each new transaction.
</Note>
