fdic_search_demographics
Search quarterly demographic data for FDIC-insured banks to analyze office locations, geographic classifications, and market structure using filters like certificate numbers, report dates, and metro areas.
Instructions
Search BankFind demographics data for FDIC-insured institutions.
Returns quarterly demographic and market-structure attributes such as office counts, territory assignments, metro classification, county/country codes, and selected geographic reference data.
Common filter examples:
Demographics for a specific bank: CERT:3511
By report date: REPDTE:20251231
Institutions in metro areas: METRO:1
Institutions with out-of-state offices: OFFSTATE:[1 TO *]
Minority status date present: MNRTYDTE:[19000101 TO 99991231]
Key returned fields:
CERT: FDIC Certificate Number
REPDTE: Report Date — the last day of the quarterly reporting period (YYYYMMDD)
QTRNO: Quarter number
OFFTOT: Total offices
OFFSTATE: Offices in other states
OFFNDOM: Offices in non-domestic territories
OFFOTH: Other offices
OFFSOD: Offices included in Summary of Deposits
METRO, MICRO: Metro/micro area flags
CBSANAME, CSA: Core-based statistical area data
FDICTERR, RISKTERR: FDIC and risk territory assignments
SIMS_LAT, SIMS_LONG: Geographic coordinates
Args:
cert (number, optional): Filter by institution CERT number
repdte (string, optional): Report Date in YYYYMMDD format (quarter-end dates: 0331, 0630, 0930, 1231)
filters (string, optional): Additional ElasticSearch query filters
fields (string, optional): Comma-separated field names
limit (number): Records to return (default: 20)
offset (number): Pagination offset (default: 0)
sort_by (string, optional): Field to sort by
sort_order ('ASC'|'DESC'): Sort direction (default: 'ASC')
Prefer concise human-readable summaries or tables when answering users. Structured fields are available for totals, pagination, and demographic records.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| filters | No | FDIC API filter using ElasticSearch query string syntax. Combine conditions with AND/OR, use quotes for multi-word values, and [min TO max] for ranges (* = unbounded). Common fields: NAME (institution name), STNAME (state name), STALP (two-letter state code), CERT (certificate number), ASSET (total assets in $thousands), ACTIVE (1=active, 0=inactive). Examples: STNAME:"California", ACTIVE:1 AND ASSET:[1000000 TO *], NAME:"Chase" | |
| fields | No | Comma-separated list of FDIC field names to return. Leave empty to return all fields. Field names are ALL_CAPS (e.g., NAME, CERT, ASSET, DEP, STALP). Example: NAME,CERT,ASSET,DEP,STALP | |
| limit | No | Maximum number of records to return (1-10000, default: 20) | |
| offset | No | Number of records to skip for pagination (default: 0) | |
| sort_by | No | Field name to sort results by. Example: ASSET, NAME, FAILDATE | |
| sort_order | No | Sort direction: ASC (ascending) or DESC (descending) | ASC |
| cert | No | Filter by FDIC Certificate Number | |
| repdte | No | Filter by Report Date (REPDTE) in YYYYMMDD format. FDIC data is published quarterly on: March 31, June 30, September 30, and December 31. Example: 20251231 for Q4 2025. If omitted, returns all available dates. |
Implementation Reference
- src/tools/demographics.ts:30-118 (registration)Registration of the fdic_search_demographics tool using the McpServer instance.
export function registerDemographicsTools(server: McpServer): void { server.registerTool( "fdic_search_demographics", { title: "Search Institution Demographics Data", description: `Search BankFind demographics data for FDIC-insured institutions. Returns quarterly demographic and market-structure attributes such as office counts, territory assignments, metro classification, county/country codes, and selected geographic reference data. Common filter examples: - Demographics for a specific bank: CERT:3511 - By report date: REPDTE:20251231 - Institutions in metro areas: METRO:1 - Institutions with out-of-state offices: OFFSTATE:[1 TO *] - Minority status date present: MNRTYDTE:[19000101 TO 99991231] Key returned fields: - CERT: FDIC Certificate Number - REPDTE: Report Date — the last day of the quarterly reporting period (YYYYMMDD) - QTRNO: Quarter number - OFFTOT: Total offices - OFFSTATE: Offices in other states - OFFNDOM: Offices in non-domestic territories - OFFOTH: Other offices - OFFSOD: Offices included in Summary of Deposits - METRO, MICRO: Metro/micro area flags - CBSANAME, CSA: Core-based statistical area data - FDICTERR, RISKTERR: FDIC and risk territory assignments - SIMS_LAT, SIMS_LONG: Geographic coordinates Args: - cert (number, optional): Filter by institution CERT number - repdte (string, optional): Report Date in YYYYMMDD format (quarter-end dates: 0331, 0630, 0930, 1231) - filters (string, optional): Additional ElasticSearch query filters - fields (string, optional): Comma-separated field names - limit (number): Records to return (default: 20) - offset (number): Pagination offset (default: 0) - sort_by (string, optional): Field to sort by - sort_order ('ASC'|'DESC'): Sort direction (default: 'ASC') Prefer concise human-readable summaries or tables when answering users. Structured fields are available for totals, pagination, and demographic records.`, inputSchema: DemographicsQuerySchema, annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true, }, }, async ({ cert, repdte, ...params }) => { try { const response = await queryEndpoint(ENDPOINTS.DEMOGRAPHICS, { ...params, filters: buildFilterString({ cert, dateField: "REPDTE", dateValue: repdte, rawFilters: params.filters, }), }); const records = extractRecords(response); const pagination = buildPaginationInfo( response.meta.total, params.offset ?? 0, records.length, ); const output = { ...pagination, demographics: records }; const text = truncateIfNeeded( formatSearchResultText("demographic records", records, pagination, [ "CERT", "REPDTE", "OFFTOT", "OFFSTATE", "METRO", "CBSANAME", ]), CHARACTER_LIMIT, "Request fewer fields, narrow your filters, or paginate with limit/offset.", ); return { content: [{ type: "text", text }], structuredContent: output, }; } catch (err) { return formatToolError(err); } }, ); } - src/tools/demographics.ts:79-116 (handler)The handler function for fdic_search_demographics, which calls the fdicClient to query demographic data.
async ({ cert, repdte, ...params }) => { try { const response = await queryEndpoint(ENDPOINTS.DEMOGRAPHICS, { ...params, filters: buildFilterString({ cert, dateField: "REPDTE", dateValue: repdte, rawFilters: params.filters, }), }); const records = extractRecords(response); const pagination = buildPaginationInfo( response.meta.total, params.offset ?? 0, records.length, ); const output = { ...pagination, demographics: records }; const text = truncateIfNeeded( formatSearchResultText("demographic records", records, pagination, [ "CERT", "REPDTE", "OFFTOT", "OFFSTATE", "METRO", "CBSANAME", ]), CHARACTER_LIMIT, "Request fewer fields, narrow your filters, or paginate with limit/offset.", ); return { content: [{ type: "text", text }], structuredContent: output, }; } catch (err) { return formatToolError(err); } }, - src/tools/demographics.ts:15-28 (schema)Input schema (DemographicsQuerySchema) for fdic_search_demographics, validating cert and repdte parameters.
const DemographicsQuerySchema = CommonQuerySchema.extend({ cert: z .number() .int() .positive() .optional() .describe("Filter by FDIC Certificate Number"), repdte: z .string() .optional() .describe( "Filter by Report Date (REPDTE) in YYYYMMDD format. FDIC data is published quarterly on: March 31, June 30, September 30, and December 31. Example: 20251231 for Q4 2025. If omitted, returns all available dates.", ), });