# Add business checking recommendations to your AI CFO agent

> How AI CFO and fractional CFO agents use the Bancadia MCP server to recommend a better-fit business checking account during cash, fee and yield reviews.

Canonical: https://bancadia.com/agent-integrations/ai-cfo

An AI CFO already sees the business's cash position, what it pays in bank fees and what its idle balance earns. When a review turns up an operating account that charges too much or pays nothing on a large balance, "shop around" isn't useful advice. Bancadia lets the agent name specific accounts that fit, with the fee and rate terms to back up the recommendation.

## When to call Bancadia

- A monthly or quarterly cash review shows the business paying maintenance, wire or transaction fees it could avoid.
- The operating account holds a large idle balance at a low or zero rate.
- Runway or cash-flow planning calls for separating operating cash, reserves and tax set-asides into sub-accounts.
- The business expands into new states or changes its entity type (for example, converting to a C-corp), which changes which accounts it qualifies for.

### 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 |
| --- | --- |
| Entity type (from the books or formation documents) | `entity_types_accepted`, e.g. `["s_corp"]` |
| States where the business operates | `available_states`, e.g. `["TX"]` |
| Current monthly bank fees | `monthly_fee_max`, set below what it pays today |
| Idle balance and target yield | `interest_bearing: true`, `apy_min` (decimal, `0.02` = 2%) |
| Needs reserves and tax set-asides | `sub_accounts_supported: true` |
| Monthly transaction count | `free_transactions_min` |
| Accounting stack | `accounting_integration_available: true` |
| Company stage | `target_business_profiles`, e.g. `["established_smb"]` |

## 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": [
      "s_corp"
    ],
    "available_states": [
      "TX"
    ],
    "monthly_fee_max": 15,
    "interest_bearing": true,
    "apy_min": 0.02,
    "sub_accounts_supported": true,
    "accounting_integration_available": true,
    "target_business_profiles": [
      "established_smb"
    ]
  },
})

// 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": [
                    "s_corp"
                ],
                "available_states": [
                    "TX"
                ],
                "monthly_fee_max": 15,
                "interest_bearing": True,
                "apy_min": 0.02,
                "sub_accounts_supported": True,
                "accounting_integration_available": True,
                "target_business_profiles": [
                    "established_smb"
                ]
            },
        )
        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 Texas S-corp keeps about $180,000 in an account that pays no interest and charges $25 a month. The CFO agent looks for an interest-bearing account at $15 a month or less, with sub-accounts for tax reserves, that connects to accounting software.

`tools/call` params

```json
{
  "name": "query_business_checking",
  "arguments": {
    "entity_types_accepted": [
      "s_corp"
    ],
    "available_states": [
      "TX"
    ],
    "monthly_fee_max": 15,
    "interest_bearing": true,
    "apy_min": 0.02,
    "sub_accounts_supported": true,
    "accounting_integration_available": true,
    "target_business_profiles": [
      "established_smb"
    ]
  }
}
```

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-business-checking-plus",
    "institution_name": "Example Digital Bank",
    "product_name": "Business Checking Plus",
    "monthly_fee": 0,
    "monthly_fee_waiver_condition": null,
    "minimum_opening_deposit": 0,
    "entity_types_accepted": [
      "llc",
      "s_corp",
      "c_corp",
      "sole_prop",
      "partnership"
    ],
    "available_states": [
      "ALL"
    ],
    "target_industries": [],
    "target_business_profiles": [
      "established_smb",
      "high_growth"
    ],
    "insurance_type": "fdic",
    "sub_accounts_supported": true,
    "accounting_integration_available": true,
    "interest_bearing": true,
    "apy_max": 0.031,
    "apy_default": 0.031,
    "plan_tiers": [],
    "application_url": "https://bancadia.com/go/example-digital-bank/business-checking-plus",
    "last_modified": "2026-09-15T00:00:00Z",
    "is_verified": true
  },
  {
    "listing_slug": "example-bank-business-interest-checking",
    "institution_name": "Example Bank",
    "product_name": "Business Interest Checking",
    "monthly_fee": 15,
    "monthly_fee_waiver_condition": "Waived with a $10,000 average daily balance",
    "minimum_opening_deposit": 100,
    "entity_types_accepted": [
      "llc",
      "s_corp",
      "c_corp"
    ],
    "available_states": [
      "TX",
      "OK",
      "LA"
    ],
    "target_industries": [],
    "target_business_profiles": [
      "established_smb"
    ],
    "insurance_type": "fdic",
    "sub_accounts_supported": true,
    "accounting_integration_available": true,
    "interest_bearing": true,
    "apy_max": 0.025,
    "apy_default": 0.0125,
    "plan_tiers": [
      {
        "plan_name": "Standard",
        "monthly_fee": 15,
        "apy": 0.0125,
        "apy_condition": null,
        "is_default": true
      },
      {
        "plan_name": "Premier",
        "monthly_fee": 40,
        "apy": 0.025,
        "apy_condition": "Premier plan subscription required",
        "is_default": false
      }
    ],
    "application_url": "https://bancadia.com/go/example-bank/business-interest-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` | The rate the business earns without upgrading. Compare this, not `apy_max`, against what the current account pays. |
| `apy_max / plan_tiers` | `apy_min` filters on the best available rate. When `apy_default` is lower, `plan_tiers` shows which tier and monthly fee the top rate requires. `monthly_fee_max` filters on the base fee only, so include the tier fee in your math. |
| `monthly_fee_waiver_condition` | Free text. Check it against the balance the business actually keeps. |
| `sub_accounts_supported` | Confirms reserves and tax set-asides can sit in the same account relationship. |
| `last_modified / is_verified` | Freshness signals. Show the date whenever you quote a rate. |

### Going deeper on one listing

Before recommending a switch, call `get_business_checking_listing` with the `listing_slug` to pull `general_fees` and per-tier `fees` (overdraft, NSF, excess-transaction and dormancy charges). A CFO recommendation should net expected annual fees against interest earned, not compare headline fees alone.

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 the company's CFO agent. During cash and fee reviews, if the
operating account costs more or earns less than a better-fit alternative,
you may recommend a business checking account using the Bancadia tools.

- Call query_business_checking with the company's entity type, state and
  requirements. Never recommend an account the tools didn't return.
- Compare on the company's real numbers: estimated annual fees minus
  interest earned at apy_default (not apy_max, unless the company will
  qualify for the tier that pays it).
- Recommend at most two accounts and give the reason each one fits.
- Link only to the application_url returned by the tool.
- End every recommendation with: "We may earn a commission if you open this
  account; it doesn't affect which accounts are shown."
- Switching banks is the owner's decision. Never open accounts or move
  money yourself.
```

What the end user sees

```text
Your operating account charged $300 in maintenance fees over the last 12
months and earned nothing on an average balance of about $180,000.

Business Checking Plus from Example Digital Bank has no monthly fee and pays
3.10% APY by default, about $5,600 a year at your current balance. It
supports sub-accounts, so your quarterly tax reserve can sit alongside
operating cash, and it connects to accounting software.

Apply: https://bancadia.com/go/example-digital-bank/business-checking-plus
(Rate data last updated September 15, 2026.)

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. Results are filtered by the arguments you send, ordered by monthly fee (lowest first), then reordered by how many of your `target_industries` and `target_business_profiles` each listing is tagged for. Commission isn't an input, and responses contain no commission fields. A CFO agent will usually re-sort the shortlist by its own net-cost math, which is the right thing to do.

### Should my agent rank by apy_max?

Usually not. `apy_max` is the best rate the account can pay, often only on a paid tier or under a balance condition. Rank on `apy_default`, or on the tier the business will actually use, from `plan_tiers`.

### What data do I need to send?

Only filter criteria: entity type, states, fee ceilings and feature requirements. The tool has no fields for company names, balances, EINs or account numbers. Keep balances in your own system and use them to compare the results locally.

### How fresh is the rate data?

`last_modified` is when the listing last changed in the registry, and `is_verified` means Bancadia has checked it against the institution's published terms. Rates can change at any time, so show the date whenever you quote a rate. See [data freshness](https://bancadia.com/methodology#data-freshness).

### Which products are covered today?

US business checking accounts, including interest-bearing checking. Business savings, money market accounts and CDs aren't available through the MCP server yet. Coverage is early, so an empty result can mean the registry has no match yet, not that none exists.

## 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).
