MCP Reference
This page is a complete reference for the Bancadia MCP server — every JSON-RPC method it accepts, the one tool it currently routes, and every error it can return. It's written to be equally useful to a human integrating by hand and to an AI agent parsing this page to decide how to call the server.
In short: everything happens through a single endpoint — https://mcp.bancadia.com/. Most calls are a POST whose JSON-RPC method field determines behavior; the same endpoint also accepts GET (a standalone server-push stream) and DELETE (session termination) — see Session management below.
Transport
Every JSON-RPC interaction is sent as POST to https://mcp.bancadia.com/ (root path, trailing slash) with Content-Type: application/json and Accept: application/json, text/event-stream. The server may respond with either a plain application/json body (the common case, and the only mode documented in detail below) or a text/event-stream response carrying the same JSON-RPC object as a single SSE event — spec-compliant clients may request the latter by default, but no tool here emits intermediate progress events, so the two modes are equivalent in practice.
method | Auth required | Session required | Description |
|---|---|---|---|
| initialize | No | No — this call creates the session | MCP lifecycle handshake — protocol/capability negotiation. Must be called first; every other method depends on the session it issues. |
| tools/list | No | Yes | Returns the manifest of callable tools with their JSON Schema. |
| tools/call | Yes (Bearer) | Yes | Invokes a tool by name with arguments. |
| notifications/* | n/a | Yes | Client→server notifications (e.g. notifications/initialized). Any request that omits id entirely is treated as a notification. |
Any other method value, or an unrecognized tool name passed to tools/call, returns a JSON-RPC error with HTTP status 404 and code -32601.
Calling initializefirst is now required. It's the only method that doesn't need an Mcp-Session-Id header — every other method (including notifications) does, since initialize is what issues that session ID in the first place. A request that skips straight to tools/list or tools/call without ever calling initialize fails with 400. See Session management below for the full lifecycle.
Session management
A session is created only by a successful initialize call, returned via the Mcp-Session-Id response header. Every subsequent request on the MCP endpoint — tools/list, tools/call, notifications, GET, DELETE — must echo that same value back as an Mcp-Session-Id request header:
Mcp-Session-Id: 7e93bc81-b832-4c8b-9834-1bac55106e22
Sessions idle-expire after ~30 minutes of inactivity by default (a sliding window — every valid request resets the clock). This is a housekeeping window, not a held-open connection: each call is an ordinary independent HTTP request, and nothing stays open for 30 minutes.
A request missing the Mcp-Session-Id header (on any method other than initialize) gets 400. A request whose session has expired, or was never valid, gets 404 — call initialize again to get a new session. This is the expected, normal way a long-idle client resumes, not an error state to alarm on. See Errors below for the exact status/code combinations.
A client that wants to end its session immediately (e.g. explicit logout) rather than waiting for idle expiry can send DELETE — see below.
Authentication
tools/call requires a bearer token in the Authorization header. Tokens are obtained by registering at bancadia.com/developer/signup.
Authorization: Bearer bcd_YOUR_TOKEN_HERE
A missing header, a header without the Bearer prefix, or an unknown/revoked token all return HTTP 401 with JSON-RPC error code -32001:
{
"jsonrpc": "2.0",
"id": 1,
"error": {
"code": -32001,
"message": "Unauthorized. Register at bancadia.com/developer/signup to obtain an API token."
}
}initialize and tools/list do not require a token.
Rate limiting
Successful tools/call requests are subject to a per-token sliding-window rate limit (100 requests / 60s by default). Rate-limit headers are present on every tools/call response, success or 429 — never on initialize, tools/list, /health, or /.well-known/mcp, since only tools/call is rate-limited.
| Header | Description |
|---|---|
| X-RateLimit-Limit | Max requests allowed in the current window |
| X-RateLimit-Remaining | Requests remaining in the current window |
| X-RateLimit-Reset | Unix timestamp (seconds) when the window resets |
Exceeding the limit returns HTTP 429 with JSON-RPC error code -32029:
{
"jsonrpc": "2.0",
"id": 1,
"error": { "code": -32029, "message": "Rate limit exceeded." }
}initialize
The standard MCP lifecycle handshake, and now the mandatory first call — no auth required, but every other method depends on the Mcp-Session-Id it issues. See Session management above.
Request
{
"jsonrpc": "2.0",
"id": 0,
"method": "initialize",
"params": {
"protocolVersion": "2025-06-18",
"capabilities": {},
"clientInfo": { "name": "example-client", "version": "1.0.0" }
}
}Response
{
"jsonrpc": "2.0",
"id": 0,
"result": {
"protocolVersion": "2025-06-18",
"capabilities": { "tools": {} },
"serverInfo": { "name": "Bancadia MCP", "version": "2.0.0" }
}
}The HTTP response also carries an Mcp-Session-Id header — save it, you must send it back on every subsequent request:
Mcp-Session-Id: 7e93bc81-b832-4c8b-9834-1bac55106e22
protocolVersionin the response is the client's requested version if this server supports it (currently 2025-06-18, 2025-03-26, or 2024-11-05), otherwise it falls back to the latest version this server supports rather than rejecting the request. capabilities only ever advertises tools — no resources, prompts, logging, or sampling, and the tool set is static per deployment (no tools.listChanged notifications).
MCP clients typically follow a successful initialize with a notifications/initialized notification — see below.
tools/list
Returns the manifest of callable tools, each with a JSON Schema inputSchema describing its arguments. No bearer token required, but the Mcp-Session-Id from your last initialize call is. Currently returns exactly one tool.
Request
POST https://mcp.bancadia.com/
Content-Type: application/json
Mcp-Session-Id: 7e93bc81-b832-4c8b-9834-1bac55106e22
{ "jsonrpc": "2.0", "id": 1, "method": "tools/list" }Response
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"tools": [
{
"name": "query_business_checking",
"description": "Query the Bancadia registry for business checking account products using compound filter criteria. Returns active, verified listings from financial institutions.",
"inputSchema": {
"type": "object",
"properties": {
"monthly_fee_max": { "type": "number", "description": "Maximum monthly fee" },
"minimum_opening_deposit_max": { "type": "number", "description": "Maximum minimum opening deposit" },
"entity_types_accepted": { "type": "array", "items": { "type": "string" }, "description": "Returns listings accepting all specified entity types (e.g. llc, s_corp)" },
"available_states": { "type": "array", "items": { "type": "string" }, "description": "Returns listings available in all specified states" },
"insurance_type": { "type": "string", "enum": ["fdic", "ncua", "uninsured"], "description": "Deposit insurance type" },
"cash_deposit_available": { "type": "boolean", "description": "Whether cash deposits are supported" },
"sub_accounts_supported": { "type": "boolean", "description": "Whether sub-accounts are supported" },
"free_transactions_min": { "type": "number", "description": "Minimum free transactions per month" },
"rtp_supported": { "type": "boolean", "description": "Whether real-time payments (any rail) are supported at all" },
"rtp_network": { "type": "string", "enum": ["fednow", "rtp_network", "both", "none"], "description": "Which real-time payment rail is supported" },
"accounting_integration_available": { "type": "boolean", "description": "Whether the account connects to any accounting software (e.g. QuickBooks, Xero)" },
"tax_integration_available": { "type": "boolean", "description": "Whether the account connects to any tax-prep or tax-filing software/service" },
"expense_integration_available": { "type": "boolean", "description": "Whether the account connects to any expense/spend-management software" },
"interest_bearing": { "type": "boolean", "description": "Whether the account earns interest" },
"apy_min": { "type": "number", "description": "Minimum APY (inclusive), for interest-bearing accounts" }
},
"additionalProperties": false
}
}
]
}
}A handful of other tool names — query_hysa, query_personal_savings, query_personal_checking, query_personal_cd, query_business_savings, query_business_cd — existed historically and may still be referenced in older material, but they are not currently routed. They don't appear in tools/list or /.well-known/mcp, and calling any of them returns the -32601 Unknown tool error described below. query_business_checking is the only tool available today.
notifications/initialized and other notifications
Per JSON-RPC 2.0, a request that omits id entirely is a notification and never receives a response body — the server acknowledges it with an empty HTTP 202. This applies to any id-less request, not just notifications/initialized (e.g. notifications/cancelled is handled identically). If your client sends this after a successful initialize, expect a bare 202 with no JSON body — don't try to parse one.
Like every method except initialize, notifications must also include the Mcp-Session-Id header from your last initialize call — omitting it returns 400 instead of 202.
// Request (no "id" field, session header required)
POST https://mcp.bancadia.com/
Content-Type: application/json
Mcp-Session-Id: 7e93bc81-b832-4c8b-9834-1bac55106e22
{ "jsonrpc": "2.0", "method": "notifications/initialized" }
// Response: HTTP 202, empty bodytools/call — query_business_checking
Queries active, verified business checking account listings using compound filter criteria. Requires a bearer token and a valid Mcp-Session-Id header from your last initialize call.
Arguments
All filters are optional and combine with AND semantics — every filter you supply must match for a listing to be returned. Array filters (entity_types_accepted, available_states) require every requested value to be present on a listing (i.e. "all of", not "any of"). Unrecognized argument names are rejected (additionalProperties: false).
| Parameter | Type | Description |
|---|---|---|
| monthly_fee_max | number | Maximum monthly fee. |
| minimum_opening_deposit_max | number | Maximum minimum opening deposit. |
| entity_types_accepted | string[] | Returns listings accepting all specified entity types. Valid values: llc, s_corp, c_corp, sole_prop, partnership, nonprofit. Not enforced server-side — unrecognized values simply never match. |
| available_states | string[] | Returns listings available in all specified states (two-letter codes). A listing whose available_states includes the literal value ALL always matches, regardless of which states are requested. |
| insurance_type | string | Deposit insurance type. One of fdic, ncua, uninsured. |
| cash_deposit_available | boolean | Whether cash deposits are supported. |
| sub_accounts_supported | boolean | Whether sub-accounts are supported. |
| free_transactions_min | number | Minimum free transactions per month. |
| rtp_supported | boolean | Whether real-time payments (any rail) are supported at all. |
| rtp_network | string | Which real-time payment rail is supported. One of fednow, rtp_network, both, none. |
| accounting_integration_available | boolean | Whether the account connects to any accounting software (e.g. QuickBooks, Xero). Category-level only — specific products aren’t filterable. |
| tax_integration_available | boolean | Whether the account connects to any tax-prep or tax-filing software/service. |
| expense_integration_available | boolean | Whether the account connects to any expense/spend-management software. |
| interest_bearing | boolean | Whether the account earns interest. |
| apy_min | number | Minimum APY (inclusive), for interest-bearing accounts. |
Request
POST https://mcp.bancadia.com/
Authorization: Bearer bcd_YOUR_TOKEN_HERE
Content-Type: application/json
Mcp-Session-Id: 7e93bc81-b832-4c8b-9834-1bac55106e22
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "query_business_checking",
"arguments": {
"monthly_fee_max": 0,
"rtp_supported": true,
"rtp_network": "both",
"accounting_integration_available": true,
"entity_types_accepted": ["llc", "s_corp"],
"available_states": ["CA", "NY"]
}
}
}Response
Per the MCP spec, results are wrapped in a content: [{ type: "text", text: "<json-string>" }] block rather than returned as native JSON. text is a JSON-encoded string — your client must JSON.parse(text) to get the actual array of results.
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "[{\"institution_name\":\"Example Bank\",\"product_name\":\"Business Checking Pro\",\"monthly_fee\":0,\"monthly_fee_waiver_condition\":null,\"minimum_opening_deposit\":0,\"entity_types_accepted\":[\"llc\",\"s_corp\"],\"available_states\":[\"ALL\"],\"insurance_type\":\"fdic\",\"free_transactions_per_month\":100,\"cash_deposit_available\":true,\"sub_accounts_supported\":true,\"rtp_supported\":true,\"rtp_network\":\"both\",\"accounting_integration_available\":true,\"tax_integration_available\":false,\"expense_integration_available\":true,\"interest_bearing\":true,\"apy\":1.25,\"apy_tiers\":null,\"outgoing_domestic_wire_fee\":15,\"plan_tiers\":[{\"plan_name\":\"Standard\",\"monthly_fee\":0,\"monthly_fee_waiver_condition\":null,\"apy\":1.25,\"apy_max_balance_eligible\":null,\"apy_condition\":null,\"is_default\":true,\"sort_order\":0}],\"promotions\":[{\"bonus_amount\":300,\"condition_description\":\"Deposit $2,500 within 30 days\",\"minimum_deposit\":2500,\"expiry_date\":null,\"promo_url\":\"https://example.com/promo\"}],\"application_url\":\"https://example.com/apply\",\"last_modified\":\"2026-01-01T00:00:00Z\",\"is_verified\":true}]"
}
]
}
}JSON.parse(text) yields an array of results (empty array if nothing matched, or if the underlying query errored — errors are not surfaced to the caller). Each result object has this shape:
| Parameter | Type | Description |
|---|---|---|
| institution_name | string | null | Name of the financial institution. |
| product_name | string | Name of the product. |
| monthly_fee | number | Base monthly fee in USD. |
| monthly_fee_waiver_condition | string | null | Condition to waive the monthly fee, if any. |
| minimum_opening_deposit | number | Minimum deposit required to open. |
| entity_types_accepted | string[] | Enum values from entity_type_enum (llc, s_corp, c_corp, sole_prop, partnership, nonprofit). |
| available_states | string[] | ["ALL"] indicates nationwide availability. |
| insurance_type | string | One of fdic, ncua, uninsured. |
| free_transactions_per_month | integer | null | Free transactions included per month. |
| cash_deposit_available | boolean | null | Whether cash deposits are supported. |
| sub_accounts_supported | boolean | null | Whether sub-accounts are supported. |
| rtp_supported | boolean | null | Whether real-time payments (any rail) are supported. |
| rtp_network | string | null | One of fednow, rtp_network, both, none; null when rtp_supported is false. |
| accounting_integration_available | boolean | null | Connects to accounting software. |
| tax_integration_available | boolean | null | Connects to tax-prep/filing software. |
| expense_integration_available | boolean | null | Connects to expense/spend-management software. |
| interest_bearing | boolean | null | Whether the account earns interest. |
| apy | number | null | Best available APY for indexing — mirrors the highest APY across plan_tiers if the product has multiple. |
| apy_tiers | object | null | Balance-tiered rate schema; null for flat-rate or non-interest accounts. |
| outgoing_domestic_wire_fee | number | null | Fee for outgoing domestic wires. |
| plan_tiers | array | One row per paid subscription plan (e.g. Standard/Plus/Premier). Empty array if the product has a single flat pricing tier. |
| promotions | array | Welcome/bonus offers. Empty array if none. |
| application_url | string (uri) | Where to apply for this product. |
| last_modified | string (date-time) | When the listing was last updated. |
| is_verified | boolean | Whether this listing has been verified by Bancadia. |
GET — standalone SSE stream
GET https://mcp.bancadia.com/ with Accept: text/event-stream and a valid Mcp-Session-Id header opens a stream for messages the server initiates outside of a specific tools/call response (e.g. a future progress or sampling push). No tool currently sends anything on it — the stream exists so that MCP client libraries which open it unconditionally after initialize don't fail.
The server sends periodic keep-alive pingevents and closes the stream itself after roughly a minute; well-behaved clients reconnect automatically. This is handled by spec-compliant client libraries, if at all — if you're integrating by hand (Option B in the Quickstart), you never need to call this.
GET without an Accept: text/event-stream header returns 405 with no body.
DELETE — session termination
A client that's done with a session (e.g. the user closes a chat or tab) can end it immediately rather than waiting for idle expiry:
DELETE https://mcp.bancadia.com/ Mcp-Session-Id: 7e93bc81-b832-4c8b-9834-1bac55106e22
Returns 204 No Content with an empty body. This is a courtesy, not something a caller must remember to do — an unterminated session simply idle-expires (see Session management above).
Errors
| HTTP status | JSON-RPC code | Meaning |
|---|---|---|
| 400 | -32600 | Missing Mcp-Session-Id header on any request other than initialize, or an MCP-Protocol-Versionheader value this server doesn't support. No JSON-RPC body if the request was a notification (no id). |
| 401 | -32001 | Unauthorized — missing, malformed, or unknown/revoked bearer token on tools/call. |
| 403 | — | The Originrequest header is present but not on the server's allowlist. No JSON-RPC body — a plain text/empty response. Only relevant to browser-based callers; curl/SDK/CLI clients don't send Origin and are unaffected in practice. |
| 404 | -32601 | Unknown method (anything other than initialize, tools/list, tools/call) or unknown/unrouted tool name passed to tools/call. |
| 404 | -32600 | Different case, same status. The Mcp-Session-Id header doesn't match a known, unexpired session. Call initialize again to get a new one — this is the normal way a long-idle client resumes, not an error state to alarm on. |
| 405 | — | GET request whose Accept header doesn't include text/event-stream. No body. |
| 429 | -32029 | Per-token rate limit exceeded. |
The two 404 rows share an HTTP status but mean different things and need different fixes — fix the tool/method name for -32601, re-initialize for -32600. 403 and 405 are also worth noting specially: unlike every other error case here, they return no JSON-RPC body at all — just a bare HTTP status with a plain-text or empty body. A client that assumes every non-2xx response has a parseable error.code will break on these two.
Example — missing session header, and an unknown/expired session (both an id-bearing request would get):
// 400 — missing Mcp-Session-Id
{ "jsonrpc": "2.0", "id": 1, "error": { "code": -32600, "message": "Missing Mcp-Session-Id header." } }
// 404 — unknown/expired session
{ "jsonrpc": "2.0", "id": 1, "error": { "code": -32600, "message": "Session not found or expired. Re-initialize." } }Example — calling an unrouted or unknown tool name:
{
"jsonrpc": "2.0",
"id": 1,
"error": { "code": -32601, "message": "Unknown tool: query_hysa" }
}Discovery & health endpoints
Two unauthenticated GET endpoints exist alongside the JSON-RPC endpoint:
| Parameter | Type | Description |
|---|---|---|
| GET /health | — | Liveness check. Returns { "status": "ok" }. |
| GET /.well-known/mcp | — | Public discovery document — advertises the JSON-RPC endpoint URL and a summary (name + description, no inputSchema) of every currently-routed tool. Useful for agents that discover capabilities by URL convention rather than a JSON-RPC handshake. Bancadia's main site mirrors this at bancadia.com/.well-known/mcp. |