@cyanheads/fdic-banks-mcp-server
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@@cyanheads/fdic-banks-mcp-serverWhat are the latest quarterly financials for JPMorgan Chase?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Public Hosted Server: https://fdic-banks.caseyjhand.com/mcp
Overview
Every FDIC-insured bank and savings institution, open, merged, or failed, from the FDIC BankFind Suite API. Read quarterly Call Report financials back to 1984, rank a bank against peers, screen many at once, search failures since 1934, and map branch deposits and market share. Credit unions are NCUA-insured and not included. No API key required.
Tools
Tool | Description |
| Find institutions by name, CERT, location, size, charter class, or holding company; returns the CERT every other tool takes |
| One institution's quarterly Call Report history, most recent first, with its profile |
| One institution against a peer group for one quarter: peer median, quartiles, range, percentile, and rank per metric |
| Multi-bank, multi-quarter Call Report panel filtered by CERTs, state, asset range, and metric thresholds |
| Bank failures and assistance transactions since 1934, with totals, per-method subtotals, and optional grouping |
| Summary of Deposits: an institution's branches and state market share, or a market ranked by deposits with HHI |
| Metric catalog, charter classes, failure methods, insurance funds, peer asset bands, and dataset coverage |
| List staged dataframes, or describe one by name: provenance, columns, and units |
| Run one read-only DuckDB |
| Drop a staged dataframe before its TTL; off unless |
Dataframe workflow
fdic_query_financialsandfdic_get_depositsreturn an inline preview. When the full result is larger thanlimit, they also stage it as adf_XXXXX_XXXXXtable and name it in thedatasetfield.Pass that name to
fdic_dataframe_describefor the table's columns, units, and basis.Query it with
fdic_dataframe_query: joins, aggregates, window functions, and CTEs across every staged table.register_assaves a result as a new table.Tables expire after
FDIC_DATASET_TTL_SECONDS(default 24 hours). The live tables hold 1,000,000 rows together, and the oldest are dropped past that.
Staging runs on DuckDB and is on by default; CANVAS_PROVIDER_TYPE=none turns it off. The Claude Desktop .mcpb bundle ships without DuckDB's native binding, so there the dataframe tools report an install hint and every other tool works normally.
Related MCP server: @cyanheads/openfec-mcp-server
Capability reference
fdic_search_institutions tool
Filters:
name(up to 100 characters; every word must match a current, former, or trade name),certs(first 50 unique),state,city,bank_classes,min_assets/max_assets(thousands of US dollars),holding_company_rssdstatusisactive,inactive, orany; it defaults toanywhennameorcertsis given andactiveotherwise, andstatus_filterreports the value appliedUp to 100 per page (default 20), paged with
offset/next_offset. Records carryactive,successor_certfor merged or failed banks,holding_company.rssd, andmatched_on; CERTs with no record land inmissing_certs
fdic_get_institution_financials tool
certrequired; up to 25metrics(default: a 15-metric health set);quartersaccepts 1–10,000 and queries at most 200 (default 8), bounded byfrom_date/to_dateas2025-03-31,20250331, or2025Q1Rows run most recent first, each a
valuesmap of metric → number,nullwhen not reported;metric_definitionsgives each metric's FDIC field, unit, and basisquarters_availablecounts the quarters in the window; an unknown CERT fails ascert_not_found
fdic_compare_peers tool
certrequired;report_datedefaults to the latest published quarter (report_date_defaulted); up to 20metricsPeer group:
peer_asset_band(sameby default,any,under_100m,100m_1b,1b_10b,10b_250b,over_250b) plus an optionalpeer_state, orpeer_certs(first 200 unique);peer_certscan't be combined with the band or state (conflicting_peer_filters)Each comparison returns
value,peer_median,peer_p25/peer_p75,peer_min/peer_max,percentile, andrankofrank_of, over thepeer_count_with_valuepeers that reported the metric;peer_cohort_incompletemarks a peer group only partly processed
fdic_query_financials tool
Filters: up to 100
certs,state,min_assets/max_assets, up to 5metric_filters(metricwithminand/ormax), and up to 30metrics;from_date/to_datedefault to the latest published quarterInline
limitdefaults to 50, ordered bysort_by/sort_order; a larger panel is staged whole as a dataframeThe panel is capped at
FDIC_PANEL_MAX_ROWS(default 50,000), keeping the newest quarters;total_matching,rows_fetched, andpanel_truncatedreport what was left out
fdic_search_failures tool
Filters:
name,certs(first 50 unique; events before 1977 carry none),state,from_date/to_date(YYYY-MM-DD),methods,min_assets;resolutionisfailureby default, orassistanceorallsummarytotals every matching event with aby_methodbreakdown;group_by(year,state,method,insurance_fund) addsgroupstotal_assets_missing_count,total_deposits_missing_count, andestimated_loss_missing_countcount unreported amounts, and a total isnullwhen no match has a recorded amount.sortby date, loss, or assets; up to 200 per page (default 25)
fdic_get_deposits tool
certalone returns the institution's branches and deposit share in each state (mode: "institution"); a geography (state,county,city,zip,msa_code) ranks every institution in that market withhhi(market); both together giveinstitution_in_market.countyandcityrequirestateyearfrom 1994 on, defaulting to the latest survey (year_defaulted); deposits are domestic branch deposits as of June 30, in thousands of US dollarsInline
limitdefaults to 25; a larger set is staged as a dataframe, andtotal_rowsgives the full count
fdic_list_reference tool
One
topicper call:metrics,bank_classes,failure_methods,insurance_funds,peer_asset_bands, orcoveragemetricslists all 49 metric names with FDIC field, unit, basis, caveat, andin_default_set; served from built-in tables with no request to FDIC
fdic_dataframe_describe tool
name(adf_XXXXX_XXXXXfrom adatasetfield) returns that table's source tool, parameters, row count, expiry,column_schema, andcolumn_unitsWithout
name, lists live tables newest first, 50 per page, paged withoffset/next_offset; over HTTP withMCP_AUTH_MODE=nonelisting is off and fails aslisting_unavailableFails as
canvas_unavailablewhen dataframe staging is off
fdic_dataframe_query tool
One
SELECTper call, up to 20,000 characters; writes, DDL, file-reading functions, and system catalogs are rejected with typed reasons (non_select_statement,denied_function,system_catalog_access, and others)row_limitaccepts 1–1,000,000 (default 1,000) and executes at most 10,000;row_count_cappedreports when more rows matched.previewsets the inline row countregister_assaves the result as a new dataframe, or fails asregister_as_too_largepast 1,000,000 rows;BIGINTresults such asCOUNT(*)come back as strings
fdic_dataframe_drop tool
nameof a staged dataframe; returnsdropped: true, ordropped: falsewhen nothing by that name was stagedDisabled unless
FDIC_DATAFRAME_DROP_ENABLED=true; otherwise tables expire on their TTL
Features
Built on @cyanheads/mcp-ts-core: stdio and Streamable HTTP transports, pluggable auth (none / jwt / oauth), swappable storage (in-memory, filesystem, Supabase, Cloudflare KV/R2/D1), structured logging with optional OpenTelemetry tracing.
FDIC-specific:
Reads four BankFind datasets: institutions (every insured charter, active and inactive), quarterly Call Report financials from 1984, failures and assistance transactions from 1934, and the annual Summary of Deposits from 1994
Paced requests (
FDIC_RATE_LIMIT_RPS, at most four in flight) with a response cache and a cooldown after an FDIC 429; each call has a 45-second budget (55 seconds for a panel)A curated catalog of 49 Call Report metrics with FDIC field code, unit, and basis;
_ytdmetrics accumulate from January 1, and unsuffixed income and return metrics cover a single quarterHandles BankFind's quirks: case-sensitive code values, string-typed report dates, absence sentinels, and ratios reported as
0when a bank did not report themArray inputs are deduplicated in order and capped at 1,000 items; empty
certs,peer_certs,bank_classes, andmethodsare rejected
Agent-friendly output:
Every data response carries
data_as_of,metric_definitions, andreport_date_defaulted/year_defaultedwhen the server picked the periodUnreported metrics come back
null; nothing is filled inTyped errors with recovery text that names the next call (
cert_not_found,conflicting_peer_filters,no_report_for_period); rate-limit errors (pacer_shed,upstream_rate_limited) carryretryAfterprocessed_certs/deferred_certsandprocessed_metrics/deferred_metricsseparate what was queried from what to pass in a new call
Getting started
Public Hosted Instance
A public instance is available at https://fdic-banks.caseyjhand.com/mcp — no installation required. Point any MCP client at it via Streamable HTTP:
{
"mcpServers": {
"fdic-banks-mcp-server": {
"type": "streamable-http",
"url": "https://fdic-banks.caseyjhand.com/mcp"
}
}
}Every caller of the hosted instance shares one FDIC request pacer and one dataframe workspace, so fdic_dataframe_describe takes a table's exact name there; listing is off.
Self-Hosted / Local
Add the following to your MCP client configuration file. No API key is needed.
{
"mcpServers": {
"fdic-banks-mcp-server": {
"type": "stdio",
"command": "bunx",
"args": ["@cyanheads/fdic-banks-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}Or with npx (no Bun required):
{
"mcpServers": {
"fdic-banks-mcp-server": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@cyanheads/fdic-banks-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}Or with Docker:
{
"mcpServers": {
"fdic-banks-mcp-server": {
"type": "stdio",
"command": "docker",
"args": ["run", "-i", "--rm", "-e", "MCP_TRANSPORT_TYPE=stdio", "ghcr.io/cyanheads/fdic-banks-mcp-server:latest"]
}
}
}For Streamable HTTP, set the transport and start the server:
MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 bun run start:http
# Server listens at http://localhost:3010/mcpPrerequisites
Bun v1.4.0 or higher (or Node.js v24+).
No account or API key: the FDIC BankFind Suite API is public.
Installation
Clone the repository:
git clone https://github.com/cyanheads/fdic-banks-mcp-server.gitNavigate into the directory:
cd fdic-banks-mcp-serverInstall dependencies:
bun installConfigure environment:
cp .env.example .env
# every variable is optional; edit .env to override a defaultConfiguration
Variable | Description | Default |
| Maximum request starts per second to |
|
| Lifetime of the in-process FDIC response cache, in seconds; |
|
| Row cap for one |
|
| Lifetime of each staged dataframe, in seconds (minimum 60). |
|
| Set |
|
| Dataframe engine: |
|
| Transport: |
|
| HTTP server port. |
|
| HTTP session mode: |
|
| Authentication: |
|
| Log level ( |
|
| Directory for log files (Node.js only). |
|
| Storage backend: |
|
| Enable OpenTelemetry. |
|
See .env.example for the full list of optional overrides.
Running the server
Local development
Build and run the production version:
# One-time build bun run rebuild # Run the built server bun run start:http # or bun run start:stdioRun checks and tests:
bun run devcheck # Lints, formats, type-checks, and more bun run test # Runs the test suite
Project structure
Directory | Purpose |
|
|
| Server-specific environment variable parsing and validation with Zod. |
| Tool definitions ( |
| FDIC BankFind client (request pacer, response cache, query builder, normalization), the metric catalog, and the reference tables. |
| Adapter to the framework's DataCanvas: |
| Unit and integration tests, mirroring the |
Development guide
See CLAUDE.md for development guidelines and architectural rules. The short version:
Handlers throw, framework catches — no
try/catchin tool logicUse
ctx.logfor logging,ctx.statefor storageRegister new tools in
buildToolDefinitions()insrc/mcp-server/tools/definitions/index.tsWrap external API calls: validate raw → normalize to domain type → return output schema; never fabricate missing fields
Contributing
Issues are welcome. Run checks and tests before submitting:
bun run devcheck
bun run testLicense
This project is licensed under the Apache 2.0 License. See the LICENSE file for details.
This server cannot be deployed
Maintenance
Related MCP Connectors
Query SEC EDGAR filings, XBRL financials, and company data via MCP. STDIO or Streamable HTTP.
Bank financials, branch locations, deposit data, and failure history from FDIC
FDIC MCP — FDIC BankFind Suite API (free, no auth)
Query FDA data on drugs, food, devices, and recalls via openFDA. STDIO or Streamable HTTP.
Related MCP Servers
- AlicenseAqualityCmaintenanceProvides programmatic access to the FDIC BankFind Suite API, enabling users to query public data on FDIC-insured financial institutions, bank failures, and branch locations. It supports advanced filtering for financial reports, demographics, and institutional history without requiring an API key.2925 npmMIT
- AlicenseNot gradedqualityAmaintenanceAccess FEC campaign finance data through MCP. Query data about candidates, money trails, and election filings. STDIO & Streamable HTTP.147 npm2Apache 2.0
- AlicenseNot gradedqualityAmaintenanceQuery US Treasury national debt, interest rates, exchange rates, and fiscal datasets via MCP with STDIO or Streamable HTTP.76 npm2Apache 2.0
- AlicenseNot gradedqualityAmaintenanceQuery FEMA disaster declarations, public assistance grants, housing aid, and NFIP flood insurance claims via MCP. Supports STDIO and Streamable HTTP.357 npm1Apache 2.0