@cyanheads/fdic-banks-mcp-server
Stages large FDIC query results as transient DuckDB tables, letting you list and describe staged dataframes and run read-only SELECT queries (joins, aggregates, window functions, CTEs) across them, optionally saving results as new tables.
This server has a remotely hosted endpoint. Open its connector listing for connection details, authentication requirements, and setup instructions:
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, trace a bank's mergers, renames, and charter changes, 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's structure-change events, newest first: mergers, failures, branch purchases, renames, relocations, and charter changes, with the other institution named |
| 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, structure-change codes, 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 one page of rows at a time (limit,offset); while rows remain,next_offsetnames the next page. Atoffset0, when the full result is larger thanlimit, they also stage it as adf_XXXXX_XXXXXtable and name it in thedatasetfield; later pages never stage.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 and sets CANVAS_PROVIDER_TYPE=none, so there the two producers return their rows a page at a time, continued with offset and next_offset, the dataframe tools report that dataframes are off, 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_get_institution_history tool
certrequired;event_types(omitted = every type butbranch) selects frommerger,failure_or_assistance,branch_purchase,name_change,relocation,charter_change,opening,closing,other, andbranch(branch-level openings, closings, sales, and relocations);from_date/to_date(YYYY-MM-DD, inclusive) bound the effective dateEvents run newest first. Each carries
effective_date,event_type,change_code,change_description, androle(subject,outgoing,survivor,buyer,seller), pluscounterparty(CERT and name of the other institution),changes(former and new values of name, address, city, state, class, chartering agency, regulator),branch(the office, on branch events), andtransaction_number(shared by the rows of one deal) where FDIC recorded them. A merger or failure appears once, whichever side the CERT was onlimit(default 50, no maximum) andoffsetpage the list;total,next_offset, andevent_types_filterreport the match;data_as_ofis the history index build time. Mergers start in 1969 and failures in 1970; 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 quarterlimit(default 50) rows per page, ordered bysort_by/sort_order, continued withoffset/next_offset; atoffset0 a larger panel is also 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; most 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 dollarslimit(default 25) rows per page, continued withoffset/next_offset; atoffset0 a larger set is also staged as a dataframe, andtotal_rowsgives the full count
fdic_list_reference tool
One
topicper call:metrics,bank_classes,failure_methods,change_codes,insurance_funds,peer_asset_bands, orcoveragemetricslists all 49 metric names with FDIC field, unit, basis, caveat, andin_default_set;change_codeslists the 41 FDIC structure-change codes with theirevent_typeandlevel(institution,branch, orboth); 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 five BankFind datasets: institutions (every insured charter, active and inactive), quarterly Call Report financials from 1984, failures and assistance transactions from 1934, structure-change history (mergers from 1969, failures from 1970), 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, retried honoringRetry-After; each call has a 45-second budget (55 seconds for a panel, or a history read that includesbranch)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,methods, andevent_typesare 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 callPublishes the
fdic-banks-guideagent skill (rootskills/: identifier chains, gates, multi-step workflows), served to MCP clients asskill://fdic-banks-guide/SKILL.mdand shipped in the npm package, Docker image, and.mcpbbundle
Getting started
Connect to the hosted instance, no install:
claude mcp add --transport http fdic-banks-mcp-server https://fdic-banks.caseyjhand.com/mcpEvery 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.
Or run it locally:
claude mcp add fdic-banks-mcp-server -- npx -y @cyanheads/fdic-banks-mcp-serverFor other clients, add this to the MCP config file:
{
"mcpServers": {
"fdic-banks-mcp-server": {
"command": "npx",
"args": ["-y", "@cyanheads/fdic-banks-mcp-server"]
}
}
}No API key or account is needed: the FDIC BankFind Suite API is public. For Docker or a source build, see Running the server.
Configuration
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
Requires Bun v1.4.0 or higher (or Node.js v24+).
Clone and install:
git clone https://github.com/cyanheads/fdic-banks-mcp-server.git cd fdic-banks-mcp-server && bun install cp .env.example .env # every variable is optional; edit to override a defaultBuild and run the production version:
# One-time build bun run rebuild # Run the built server bun run start:http # http://localhost:3010/mcp # or bun run start:stdioRun checks and tests:
bun run devcheck # Lints, formats, type-checks, and more bun run test # Runs the test suite
Docker
docker run --rm -p 3010:3010 ghcr.io/cyanheads/fdic-banks-mcp-server:latestThe image defaults to HTTP transport on port 3010, stateless session mode, and logs to /var/log/fdic-banks-mcp-server. To run it over stdio from an MCP client, use "command": "docker" with "args": ["run", "-i", "--rm", "-e", "MCP_TRANSPORT_TYPE=stdio", "ghcr.io/cyanheads/fdic-banks-mcp-server:latest"].
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
Query official FDIC BankFind institution financial health, assets, deposits, and CERT status.
FDIC MCP — FDIC BankFind Suite API (free, no auth)
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.29455 npmMIT
- AlicenseNot gradedqualityBmaintenanceAccess FEC campaign finance data through MCP. Query data about candidates, money trails, and election filings. STDIO & Streamable HTTP.830 npm2Apache 2.0
- AlicenseNot gradedqualityBmaintenanceQuery US Treasury national debt, interest rates, exchange rates, and fiscal datasets via MCP with STDIO or Streamable HTTP.632 npm3Apache 2.0
- AlicenseNot gradedqualityBmaintenanceEnables access to quarterly Call Report financials, bank health metrics, failed bank lists, branch maps, and supervisory designations for every US FDIC-insured bank, with no authentication required.520 npmMIT