# Add business checking recommendations to your treasury or cash-management agent

> How treasury and cash-management agents use the Bancadia MCP server to recommend operating accounts that match a business's balances, payment rails and account structure.

Canonical: https://bancadia.com/agent-integrations/treasury-cash-management

Treasury agents decide where cash should sit: how much stays liquid for operations, how much earns yield, and how it moves between accounts. The operating account is the base of that structure. When it earns nothing, can't separate funds or moves money slowly, a treasury agent can recommend an account that fits the business's balances and payment patterns instead of a generic "consider a high-yield option."

## When to call Bancadia

- Idle operating cash sits well above the business's monthly burn and earns little or nothing.
- The business needs separate buckets for payroll, reserves and taxes, and its current account can't create sub-accounts.
- Vendors or payroll need same-day settlement, so real-time payment rails (RTP, FedNow) are a requirement.
- Wire volume is high enough that wire fees are a line item worth reducing.
- Balances exceed deposit insurance coverage at one institution ($250,000 per depositor, per insured bank, per ownership category), so the business wants a second operating account.

### Signals you likely already have

Each maps to an argument on `query_business_checking`. All arguments are optional and combine with AND semantics, except `target_industries` and `target_business_profiles`, which reorder results without excluding any.

| Signal | Argument |
| --- | --- |
| Average daily balance and monthly burn | `interest_bearing: true`, `apy_min`. There's no balance argument, so compare yields against the balance locally. |
| Needs segregated buckets | `sub_accounts_supported: true` |
| Same-day payment requirements | `rtp_supported: true`, or `rtp_network`: `"fednow"`, `"rtp_network"` or `"both"` |
| Monthly payment and transfer volume | `free_transactions_min` |
| Deposit insurance requirement | `insurance_type: "fdic"` |
| Entity type and operating states | `entity_types_accepted`, `available_states` |
| Funding stage | `target_business_profiles`, e.g. `["vc_backed", "high_growth"]` |

## Quickstart: connect the MCP server

Bancadia is delivered as a remote MCP server over Streamable HTTP at `https://mcp.bancadia.com/`. `initialize` and `tools/list` need no credentials; `tools/call` needs a bearer token, which you can create for free at [bancadia.com/developer/signup](https://bancadia.com/developer/signup). The server exposes two tools: `query_business_checking` to search listings, and `get_business_checking_listing` for full fees and features on one listing.

### Claude Desktop

Add to `claude_desktop_config.json`. Claude Desktop runs local servers from this file, so the remote server is bridged with `mcp-remote`.

```json
{
  "mcpServers": {
    "bancadia": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote",
        "https://mcp.bancadia.com/",
        "--header",
        "Authorization:${BANCADIA_AUTH}"
      ],
      "env": {
        "BANCADIA_AUTH": "Bearer sk_bancadia_YOUR_TOKEN"
      }
    }
  }
}
```

### Claude Code

```bash
claude mcp add --transport http bancadia https://mcp.bancadia.com/ \
  --header "Authorization: Bearer sk_bancadia_YOUR_TOKEN"
```

### Any MCP client (TypeScript SDK)

Uses `@modelcontextprotocol/sdk`. The arguments match the example in the next section.

```ts
import { Client } from '@modelcontextprotocol/sdk/client/index.js'
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js'

const transport = new StreamableHTTPClientTransport(new URL('https://mcp.bancadia.com/'), {
  requestInit: {
    headers: { Authorization: `Bearer ${process.env.BANCADIA_MCP_API_TOKEN}` },
  },
})
const client = new Client({ name: 'your-agent', version: '1.0.0' })
await client.connect(transport) // runs initialize + session negotiation

const result = await client.callTool({
  name: 'query_business_checking',
  arguments: {
    "entity_types_accepted": [
      "c_corp"
    ],
    "available_states": [
      "CA"
    ],
    "insurance_type": "fdic",
    "interest_bearing": true,
    "sub_accounts_supported": true,
    "rtp_network": "both",
    "free_transactions_min": 250,
    "target_industries": [
      "saas_tech"
    ],
    "target_business_profiles": [
      "vc_backed",
      "high_growth"
    ]
  },
})

// content[0].text is a JSON-encoded array of listings
const listings = JSON.parse(result.content[0].text)
await client.close()
```

### Inside an agent framework

Vercel AI SDK: `@ai-sdk/mcp` turns the live `tools/list` manifest into model tools, so there is no hand-copied schema to drift.

```ts
import { createMCPClient } from '@ai-sdk/mcp'
import { generateText, stepCountIs } from 'ai'

const bancadia = await createMCPClient({
  transport: {
    type: 'http',
    url: 'https://mcp.bancadia.com/',
    headers: { Authorization: `Bearer ${process.env.BANCADIA_MCP_API_TOKEN}` },
  },
})

try {
  const { text } = await generateText({
    model: yourModel,
    system: SYSTEM_PROMPT, // see the system-prompt snippet below
    messages,
    tools: await bancadia.tools(), // query_business_checking, get_business_checking_listing
    stopWhen: stepCountIs(4),
  })
} finally {
  await bancadia.close()
}
```

Python: the official `mcp` SDK. The same session can be handed to any framework that accepts an MCP `ClientSession`.

```python
import json, os
from mcp import ClientSession
from mcp.client.streamable_http import streamablehttp_client

headers = {"Authorization": f"Bearer {os.environ['BANCADIA_MCP_API_TOKEN']}"}

async with streamablehttp_client("https://mcp.bancadia.com/", headers=headers) as (read, write, _):
    async with ClientSession(read, write) as session:
        await session.initialize()
        result = await session.call_tool(
            "query_business_checking",
            {
                "entity_types_accepted": [
                    "c_corp"
                ],
                "available_states": [
                    "CA"
                ],
                "insurance_type": "fdic",
                "interest_bearing": True,
                "sub_accounts_supported": True,
                "rtp_network": "both",
                "free_transactions_min": 250,
                "target_industries": [
                    "saas_tech"
                ],
                "target_business_profiles": [
                    "vc_backed",
                    "high_growth"
                ]
            },
        )
        listings = json.loads(result.content[0].text)
```

The full session lifecycle, response shape, rate limits and error codes are in the [MCP reference](https://bancadia.com/docs/mcp-reference).

## Example tool call and response

A venture-backed C-corp in California holds $2.4M after a raise, pays vendors by same-day transfer, and wants operating cash, payroll and a runway reserve kept separate. The treasury agent looks for an FDIC-insured, interest-bearing account with sub-accounts and both real-time rails.

`tools/call` params

```json
{
  "name": "query_business_checking",
  "arguments": {
    "entity_types_accepted": [
      "c_corp"
    ],
    "available_states": [
      "CA"
    ],
    "insurance_type": "fdic",
    "interest_bearing": true,
    "sub_accounts_supported": true,
    "rtp_network": "both",
    "free_transactions_min": 250,
    "target_industries": [
      "saas_tech"
    ],
    "target_business_profiles": [
      "vc_backed",
      "high_growth"
    ]
  }
}
```

Parsed `result.content[0].text`, trimmed to the fields this agent uses. Real listings carry about 50 fields each. Values and institution names here are placeholders, not live listings.

```json
[
  {
    "listing_slug": "example-digital-bank-startup-treasury-checking",
    "institution_name": "Example Digital Bank",
    "product_name": "Startup Treasury Checking",
    "monthly_fee": 0,
    "monthly_fee_waiver_condition": null,
    "minimum_opening_deposit": 0,
    "entity_types_accepted": [
      "llc",
      "s_corp",
      "c_corp"
    ],
    "available_states": [
      "ALL"
    ],
    "target_industries": [
      "saas_tech"
    ],
    "target_business_profiles": [
      "vc_backed",
      "high_growth",
      "early_stage_startup"
    ],
    "insurance_type": "fdic",
    "free_transactions_per_month": 500,
    "sub_accounts_supported": true,
    "rtp_supported": true,
    "rtp_network": "both",
    "interest_bearing": true,
    "apy_max": 0.035,
    "apy_default": 0.02,
    "outgoing_domestic_wire_fee": 0,
    "positive_pay_available": true,
    "ach_debit_block_available": true,
    "plan_tiers": [
      {
        "plan_name": "Standard",
        "monthly_fee": 0,
        "apy": 0.02,
        "apy_max_balance_eligible": null,
        "apy_condition": null,
        "is_default": true
      },
      {
        "plan_name": "Plus",
        "monthly_fee": 35,
        "apy": 0.035,
        "apy_max_balance_eligible": 1000000,
        "apy_condition": "Rate applies to balances up to $1,000,000",
        "is_default": false
      }
    ],
    "application_url": "https://bancadia.com/go/example-digital-bank/startup-treasury-checking",
    "last_modified": "2026-09-15T00:00:00Z",
    "is_verified": true
  },
  {
    "listing_slug": "example-bank-commercial-checking",
    "institution_name": "Example Bank",
    "product_name": "Commercial Checking",
    "monthly_fee": 20,
    "monthly_fee_waiver_condition": "Waived with a $25,000 average collected balance",
    "minimum_opening_deposit": 1000,
    "entity_types_accepted": [
      "llc",
      "s_corp",
      "c_corp",
      "partnership",
      "nonprofit"
    ],
    "available_states": [
      "CA",
      "OR",
      "WA"
    ],
    "target_industries": [],
    "target_business_profiles": [
      "established_smb"
    ],
    "insurance_type": "fdic",
    "free_transactions_per_month": 300,
    "sub_accounts_supported": true,
    "rtp_supported": true,
    "rtp_network": "both",
    "interest_bearing": true,
    "apy_max": 0.015,
    "apy_default": 0.015,
    "outgoing_domestic_wire_fee": 25,
    "positive_pay_available": true,
    "ach_debit_block_available": true,
    "plan_tiers": [],
    "application_url": "https://bancadia.com/go/example-bank/commercial-checking",
    "last_modified": "2026-09-15T00:00:00Z",
    "is_verified": true
  }
]
```

### What the fields mean for this agent

| Field | How to use it |
| --- | --- |
| `apy_default / plan_tiers[].apy` | The first listing pays 2.00% by default and 3.50% on its $35/month Plus tier. At $2.4M the tier pays for itself, but `apy_max_balance_eligible` caps the higher rate at $1,000,000. |
| `rtp_network` | `both` means the account supports RTP and FedNow. Filter on `rtp_supported: true` instead if either rail is acceptable. |
| `positive_pay_available / ach_debit_block_available` | Fraud controls that most treasury policies require at this balance. |
| `outgoing_domestic_wire_fee` | Multiply by the business's monthly wire count to compare real costs. |
| `insurance_type` | FDIC coverage is $250,000 per depositor, per insured bank, per ownership category. At seven figures, explain the limit rather than imply the full balance is insured. |

### Going deeper on one listing

Call `get_business_checking_listing` on the shortlist to read per-tier `fees` and `features`: wire, overdraft and excess-transaction fees, plus any feature notes on sweeps or payment rails. These often decide a treasury recommendation.

A `null` field means Bancadia doesn't have that data point for the listing yet. It doesn't mean "no". An empty array means nothing matched; loosen a filter rather than inventing a result.

## Present the recommendation

Your agent owns the conversation, so it decides when a recommendation is useful and how to phrase it. The snippet below is a starting point for your system prompt. Keep the disclosure line in whatever version you ship.

System-prompt snippet (`SYSTEM_PROMPT`)

```text
You are a treasury agent. When a review shows idle cash earning little, a
need for segregated sub-accounts, or payment rails the current account
lacks, you may recommend a business checking account using the Bancadia
tools.

- Query with hard requirements (entity type, state, insurance,
  sub-accounts, payment rails). Evaluate yield against the company's actual
  balance locally, using plan_tiers and apy_max_balance_eligible, not
  apy_max alone.
- State FDIC/NCUA coverage limits plainly when balances exceed them. Never
  imply a balance above the limit is fully insured.
- Recommend a structure (which account, which tier, which sub-accounts) and
  show the annual math. Only use accounts the tool returned.
- Link only to the application_url returned by the tool.
- Include: "We may earn a commission if you open this account; it doesn't
  affect which accounts are shown."
- Never move funds without explicit approval.
```

What the end user sees

```text
Your $2.4M sits in one account earning 0.10%. Here's a structure that puts
more of it to work:

1. Open Startup Treasury Checking from Example Digital Bank on its Plus
   tier ($35/month). It pays 3.50% APY on balances up to $1,000,000 and
   supports sub-accounts, so operating cash, payroll and your runway
   reserve can be kept separate. It also supports RTP and FedNow for
   same-day vendor payments.
2. Decide where the remaining $1.4M should sit. FDIC insurance covers
   $250,000 per depositor, per bank, per ownership category, so most of
   this balance isn't insured at any single bank today.

On the first $1,000,000, the Plus tier would earn about $35,000 a year,
compared with about $1,000 at today's rate. The tier costs $420 a year.

Apply: https://bancadia.com/go/example-digital-bank/startup-treasury-checking

We may earn a commission if you open this account; it doesn't affect which
accounts are shown.
```

> **Disclosure is required in every recommendation.** Bancadia responses contain no commission or payout fields, so nothing in the data can push the model toward a higher-paying account. Your disclosure tells the user that, too.

## Commission share

Bancadia runs a commission-share model. When a bank or affiliate program pays a commission on an account opened through an agent's recommendation, Bancadia is designed to pass a share of it to the agent that made the recommendation. Bancadia is paid only on conversion. It never charges for impressions, placement or position.

- **No commissions are live yet.** Bancadia has no live bank partnerships today and pays nothing to anyone. Access to the registry is free.
- **Terms aren't set.** We don't publish rates or payout promises. Terms will be agreed per integration as commissions become available.
- **Coverage grows as partners come online.** Product data and commission eligibility will expand together, starting with business checking.
- **Commission never affects ranking.** See the [methodology](https://bancadia.com/methodology) for how results are ordered.

### How attribution works

Every `application_url` Bancadia returns is a `bancadia.com/go/…` redirect that logs the click, and every `tools/call` is logged against the token that made it. Pass `application_url` to your user unmodified. Tying a specific application back to the integration that surfaced it, which commission sharing depends on, isn't live yet. We'll document the mechanism here when it ships.

## FAQ

### Is ranking affected by commission?

No. Hard filters decide eligibility, results are ordered by monthly fee, and the stage and industry arguments move matching listings ahead of the rest. Commission isn't an input and isn't in the response. A treasury agent should re-rank the shortlist on its own net-yield math.

### Can I filter by balance, or ask what an account pays at $2M?

Not directly. There's no balance argument today. Filter on `interest_bearing` and `apy_min`, then compute yield locally from `apy_default` and `plan_tiers` (`apy`, `apy_max_balance_eligible`, `apy_condition`).

### Does Bancadia cover sweep programs or extended deposit insurance?

Not as structured fields. `insurance_type` records FDIC, NCUA or uninsured. Where a listing's detail mentions a sweep or extended-coverage program, it appears in feature text from `get_business_checking_listing`, which your agent should read rather than assume.

### What data do I need to send?

Filter criteria only. Balances, burn and cash forecasts stay in your system; nothing in the schema accepts them. The arguments you send are logged with your token.

### How current is the rate data?

Each listing carries `last_modified` and `is_verified`. Deposit rates change often, so show the date next to any rate you quote and re-query before acting on a move. See [data freshness](https://bancadia.com/methodology#data-freshness).

## Get started

[Create a free developer token](https://bancadia.com/developer/signup), then follow the [quickstart](https://bancadia.com/docs/quickstart). Questions about a specific integration? Email Scott at [scott.macpherson@bancadia.com](mailto:scott.macpherson@bancadia.com).
