@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.
Overview
US bank data from the FDIC BankFind Suite API, which is public and needs no API key. Find any FDIC-insured bank or savings institution, including closed, merged, and failed ones, then read its quarterly Call Report financials back to 1984, rank it against peers, screen many banks at once, search failures since 1934, and map branch deposits and market share. Runs as a stdio process or a local Streamable HTTP server.
Institutions are keyed by their FDIC certificate number (CERT), which survives renames and charter conversions. Credit unions are insured by the NCUA and are not in this data.
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 the response'sdatasetfield.Pass that name to
fdic_dataframe_describefor the table's columns and the unit and basis of each numeric column.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), and the live tables hold 1,000,000 rows together: past that, the oldest are dropped to make room. WithFDIC_DATAFRAME_DROP_ENABLED=true,fdic_dataframe_dropremoves one sooner.
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), up to 50certs,state,city,bank_classes,min_assets/max_assets(thousands of US dollars),holding_company_rssdstatusisactive,inactive, orany; it defaults toanywhennameorcertsis given andactiveotherwise, and the applied value comes back asstatus_filterUp to 100 per page (default 20), paged with
offset/next_offset; records carryactive,successor_certfor merged or failed banks,holding_company.rssd, andmatched_onwhen a former or trade name matched; requested CERTs with no record land inmissing_certs
fdic_get_institution_financials tool
certrequired; up to 25metrics(default: a 15-metric health set);quarters1–200 (default 8), optionally 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 before the cap; 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, or an explicitpeer_certslist of up to 200, which can't be combined with the band or state (conflicting_peer_filters)Each comparison returns the institution's
value,peer_median,peer_p25/peer_p75,peer_min/peer_max,percentile, andrankofrank_of, over thepeer_count_with_valuepeers that reported the metric
fdic_query_financials tool
Filters: up to 100
certs,state,min_assets/max_assets, and up to 5metric_filters(metricwithminand/ormaxin the metric's unit); up to 30metrics;from_date/to_date, defaulting to the latest published quarter onlyInline preview of up to 500 rows (default 50), ordered by
sort_by/sort_order; a panel larger than the preview is staged whole as a dataframeThe panel is capped at
FDIC_PANEL_MAX_ROWS(default 50,000) and keeps the newest quarters when it binds;total_matching,rows_fetched, andpanel_truncatedreport what was left out
fdic_search_failures tool
Filters:
name, up to 50certs(events before 1977 carry none),state,from_date/to_date(YYYY-MM-DD),methods,min_assets;resolutionisfailureby default, orassistanceorallsummarytotals every matching event, not just the page, with aby_methodbreakdown;group_by(year,state,method,insurance_fund) addsgroupsestimated_loss_missing_countcounts events without an FDIC loss estimate, and a loss total isnullwhen none has one;sortby date, loss, or assets, up to 200 per page (default 25)
fdic_get_deposits tool
certalone returns the institution's branches and its deposit share in each state (mode: "institution"); a geography (state,county,city,zip,msa_code) ranks every institution in that market withhhi(market); both give the institution'spositionin the market (institution_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 dollarsUp to 200 branches or ranked institutions inline (default 25); a larger set is staged as a dataframe, and
total_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 in full: source tool, the parameters it was called with, row count, expiry,column_schema, andcolumn_unitsWithout
name, lists the live tables newest first, 50 per page, paged withoffset/next_offset. Over HTTP withMCP_AUTH_MODE=none, where every caller shares one canvas, the listing is off and fails aslisting_unavailable; a table is reached by its nameFails 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_limit1–10,000 (default 1,000) caps rows materialized, withrow_count_cappedwhen it binds;previewlimits the rows returned inlineregister_assaves the result as a new dataframe with a fresh TTL, or fails asregister_as_too_largewhen the result alone passes 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
Shared request pacer: request starts capped at
FDIC_RATE_LIMIT_RPS, at most four in flight, a cooldown that holds every caller after an FDIC 429, and an in-process response cache; each call runs under one 45-second budget (55 seconds for a panel), so an error arrives inside a typical 60-second client timeoutA 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 themPeer statistics, deposit market share, and HHI are computed from every per-institution value, not from samples
Agent-friendly output:
Provenance on every data response:
data_as_of(the FDIC index build time),metric_definitionswith unit and basis, andreport_date_defaulted/year_defaultedflags when the server picked the periodNo fabricated values: unreported metrics come back
null, and failure loss totals report how many events lack an estimate instead of counting them as zeroTyped 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) carryretryAfterStaged dataframes keep their provenance and per-column units, so SQL results stay interpretable
Getting started
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 through MCP. STDIO & Streamable HTTP.
Bank financials, branch locations, deposit data, and failure history from FDIC
FDIC MCP — FDIC BankFind Suite API (free, no auth)
XBRL filings index MCP — wraps the filings.xbrl.org JSON:API index run by
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.29719 npmMIT
- AlicenseNot gradedqualityAmaintenanceAccess FEC campaign finance data through MCP. Query data about candidates, money trails, and election filings. STDIO & Streamable HTTP.552 npm2Apache 2.0
- AlicenseNot gradedqualityAmaintenanceQuery US Treasury national debt, interest rates, exchange rates, and fiscal datasets via MCP with STDIO or Streamable HTTP.74 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.535 npm1Apache 2.0