fdic-mcp-server 1.17.0 → 1.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -206,8 +206,16 @@ More examples are in [docs/usage-examples.md](./docs/usage-examples.md).
206
206
  | `fdic_compare_bank_snapshots` | Compare two reporting snapshots across banks and rank growth and profitability changes |
207
207
  | `fdic_peer_group_analysis` | Build a peer group and rank an institution against peers on financial metrics |
208
208
  | `fdic_analyze_bank_health` | Run a CAMELS-style health assessment for a single institution |
209
+ | `fdic_ubpr_analysis` | Run a UBPR-equivalent ratio analysis (ROA, ROE, NIM, efficiency, capital, liquidity, growth) |
209
210
  | `fdic_compare_peer_health` | Rank a group of institutions by CAMELS-style health scores |
210
211
  | `fdic_detect_risk_signals` | Scan institutions for early warning risk indicators |
212
+ | `fdic_analyze_credit_concentration` | Analyze loan portfolio composition and CRE/construction concentration relative to capital |
213
+ | `fdic_analyze_funding_profile` | Analyze deposit composition, wholesale funding reliance, and funding risk signals |
214
+ | `fdic_analyze_securities_portfolio` | Analyze securities portfolio size, MBS concentration, and interest rate exposure |
215
+ | `fdic_franchise_footprint` | Map branch and deposit distribution across MSA markets using SOD data |
216
+ | `fdic_market_share_analysis` | Rank institutions by deposit market share in an MSA or city market and compute HHI |
217
+ | `fdic_holding_company_profile` | Profile a holding company and its FDIC-insured subsidiaries with aggregated metrics |
218
+ | `fdic_regional_context` | Provide regional economic context (unemployment, interest rate environment) for a bank's market |
211
219
 
212
220
  Server-side analysis helpers:
213
221
 
@@ -215,6 +223,16 @@ Server-side analysis helpers:
215
223
  - `fdic_peer_group_analysis` builds a peer group from asset size, charter class, and geography criteria and then ranks an institution against peers
216
224
  - `fdic_analyze_bank_health` returns a full `public_camels_proxy_v1` proxy assessment; `fdic_compare_peer_health` returns per-institution summary scores with a full proxy for the subject; `fdic_detect_risk_signals` uses the proxy engine to generate per-institution risk signals — all are analytical proxies, not official regulatory CAMELS ratings
217
225
 
226
+ ## Claude Code Skills
227
+
228
+ This repository includes a [Claude Code](https://claude.ai/claude-code) slash command that chains multiple FDIC MCP tools into a structured analysis workflow.
229
+
230
+ | Skill | Command | Description |
231
+ |-------|---------|-------------|
232
+ | Bank Deep Dive | `/fdic-bank-deep-dive` | Comprehensive single-institution analysis report covering health assessment, financial performance, peer benchmarking, credit concentration, funding profile, securities portfolio, franchise footprint, and economic context. Accepts a bank name or CERT number with an optional report date. |
233
+
234
+ Skills are defined in `.claude/commands/` and are available to any Claude Code session with this MCP server configured. See [docs/usage-examples.md](./docs/usage-examples.md) for a usage example.
235
+
218
236
  ## Data Notes
219
237
 
220
238
  - Monetary values are generally reported in thousands of dollars.
package/dist/index.js CHANGED
@@ -32,7 +32,7 @@ var import_types = require("@modelcontextprotocol/sdk/types.js");
32
32
  var import_express2 = __toESM(require("express"));
33
33
 
34
34
  // src/constants.ts
35
- var VERSION = true ? "1.17.0" : process.env.npm_package_version ?? "0.0.0-dev";
35
+ var VERSION = true ? "1.18.0" : process.env.npm_package_version ?? "0.0.0-dev";
36
36
  var FDIC_API_BASE_URL = "https://banks.data.fdic.gov/api";
37
37
  var CHARACTER_LIMIT = 5e4;
38
38
  var DEFAULT_FDIC_MAX_RESPONSE_BYTES = 5 * 1024 * 1024;
@@ -37277,7 +37277,7 @@ NOTE: This is an analytical tool based on public financial data. AFS/HTM breakdo
37277
37277
  var import_zod15 = require("zod");
37278
37278
 
37279
37279
  // src/tools/shared/ubprRatios.ts
37280
- var UBPR_FIELDS = "CERT,REPDTE,ASSET,ROA,ROE,ROAPTX,NIMY,EEFFR,INTINC,EINTEXP,NONII,NONIX,NETINC,ELNATRY,LNLSNET,LNRE,LNCI,LNCON,LNAG,LNOTH,DEP,COREDEP,DEPDOM,DEPFOR,BROR,FREPP,IDT1CER,IDT1RWAJR,EQV,EQTOT,LNLSDEPR,DEPDASTR,CHBALR,NPERFV,NCLNLSR,NTLNLSR,LNATRESR,LNRESNCR,SC";
37280
+ var UBPR_FIELDS = "CERT,REPDTE,ASSET,ROA,ROE,ROAPTX,NIMY,EEFFR,INTINC,EINTEXP,NONII,NONIX,NETINC,ELNATRY,LNLSNET,LNRE,LNCI,LNCON,LNAG,DEP,COREDEP,DEPDOM,DEPFOR,BROR,FREPP,IDT1CER,IDT1RWAJR,EQV,EQTOT,LNLSDEPR,DEPDASTR,CHBALR,NPERFV,NCLNLSR,NTLNLSR,LNATRESR,LNRESNCR,SC";
37281
37281
  function safePct4(num, den) {
37282
37282
  if (num === null || den === null || den === 0) return null;
37283
37283
  return num / den * 100;
@@ -38008,7 +38008,7 @@ function buildSubsidiaryRecord(inst, financials) {
38008
38008
  return {
38009
38009
  cert: typeof inst.CERT === "number" ? inst.CERT : 0,
38010
38010
  name: String(inst.NAME ?? ""),
38011
- hc_name: inst.NAMHCR ? String(inst.NAMHCR) : null,
38011
+ hc_name: inst.NAMEHCR ? String(inst.NAMEHCR) : null,
38012
38012
  total_assets: typeof inst.ASSET === "number" ? inst.ASSET : 0,
38013
38013
  total_deposits: typeof inst.DEP === "number" ? inst.DEP : 0,
38014
38014
  roa: financials ? asNumber(financials.ROA) : null,
@@ -38019,7 +38019,7 @@ function buildSubsidiaryRecord(inst, financials) {
38019
38019
  }
38020
38020
 
38021
38021
  // src/tools/holdingCompanyProfile.ts
38022
- var INSTITUTION_FIELDS = "CERT,NAME,STALP,CITY,ASSET,DEP,NAMHCR,HCTMULT,ACTIVE,SPECGRP,CHRTAGNT";
38022
+ var INSTITUTION_FIELDS = "CERT,NAME,STALP,CITY,ASSET,DEP,NAMEHCR,HCTMULT,ACTIVE,SPECGRP,CHRTAGNT";
38023
38023
  var FINANCIAL_FIELDS2 = "CERT,ROA,EQV";
38024
38024
  function fmtPct5(val) {
38025
38025
  return val !== null ? `${val.toFixed(2)}%` : "n/a";
@@ -38115,7 +38115,7 @@ NOTE: This is an analytical tool based on public financial data.`,
38115
38115
  ENDPOINTS.INSTITUTIONS,
38116
38116
  {
38117
38117
  filters: `CERT:${rawParams.cert}`,
38118
- fields: "CERT,NAMHCR",
38118
+ fields: "CERT,NAMEHCR",
38119
38119
  limit: 1
38120
38120
  },
38121
38121
  { signal: controller.signal }
@@ -38126,11 +38126,11 @@ NOTE: This is an analytical tool based on public financial data.`,
38126
38126
  new Error(`No institution found with CERT number ${rawParams.cert}.`)
38127
38127
  );
38128
38128
  }
38129
- const namhcr = certRecords[0].NAMHCR;
38129
+ const namhcr = certRecords[0].NAMEHCR;
38130
38130
  if (!namhcr || String(namhcr).trim() === "") {
38131
38131
  return formatToolError(
38132
38132
  new Error(
38133
- `Institution with CERT ${rawParams.cert} is not part of a holding company (NAMHCR is empty).`
38133
+ `Institution with CERT ${rawParams.cert} is not part of a holding company (NAMEHCR is empty).`
38134
38134
  )
38135
38135
  );
38136
38136
  }
@@ -38147,7 +38147,7 @@ NOTE: This is an analytical tool based on public financial data.`,
38147
38147
  const instResponse = await queryEndpoint(
38148
38148
  ENDPOINTS.INSTITUTIONS,
38149
38149
  {
38150
- filters: `NAMHCR:"${hcName}"`,
38150
+ filters: `NAMEHCR:"${hcName}"`,
38151
38151
  fields: INSTITUTION_FIELDS,
38152
38152
  limit: 500,
38153
38153
  sort_by: "ASSET",
@@ -38159,7 +38159,7 @@ NOTE: This is an analytical tool based on public financial data.`,
38159
38159
  if (instRecords.length === 0) {
38160
38160
  return formatToolError(
38161
38161
  new Error(
38162
- `No institutions found for holding company "${hcName}". Check the name spelling (use NAMHCR value from FDIC data).`
38162
+ `No institutions found for holding company "${hcName}". Check the name spelling (use NAMEHCR value from FDIC data).`
38163
38163
  )
38164
38164
  );
38165
38165
  }
package/dist/server.js CHANGED
@@ -46,7 +46,7 @@ var import_types = require("@modelcontextprotocol/sdk/types.js");
46
46
  var import_express2 = __toESM(require("express"));
47
47
 
48
48
  // src/constants.ts
49
- var VERSION = true ? "1.17.0" : process.env.npm_package_version ?? "0.0.0-dev";
49
+ var VERSION = true ? "1.18.0" : process.env.npm_package_version ?? "0.0.0-dev";
50
50
  var FDIC_API_BASE_URL = "https://banks.data.fdic.gov/api";
51
51
  var CHARACTER_LIMIT = 5e4;
52
52
  var DEFAULT_FDIC_MAX_RESPONSE_BYTES = 5 * 1024 * 1024;
@@ -37291,7 +37291,7 @@ NOTE: This is an analytical tool based on public financial data. AFS/HTM breakdo
37291
37291
  var import_zod15 = require("zod");
37292
37292
 
37293
37293
  // src/tools/shared/ubprRatios.ts
37294
- var UBPR_FIELDS = "CERT,REPDTE,ASSET,ROA,ROE,ROAPTX,NIMY,EEFFR,INTINC,EINTEXP,NONII,NONIX,NETINC,ELNATRY,LNLSNET,LNRE,LNCI,LNCON,LNAG,LNOTH,DEP,COREDEP,DEPDOM,DEPFOR,BROR,FREPP,IDT1CER,IDT1RWAJR,EQV,EQTOT,LNLSDEPR,DEPDASTR,CHBALR,NPERFV,NCLNLSR,NTLNLSR,LNATRESR,LNRESNCR,SC";
37294
+ var UBPR_FIELDS = "CERT,REPDTE,ASSET,ROA,ROE,ROAPTX,NIMY,EEFFR,INTINC,EINTEXP,NONII,NONIX,NETINC,ELNATRY,LNLSNET,LNRE,LNCI,LNCON,LNAG,DEP,COREDEP,DEPDOM,DEPFOR,BROR,FREPP,IDT1CER,IDT1RWAJR,EQV,EQTOT,LNLSDEPR,DEPDASTR,CHBALR,NPERFV,NCLNLSR,NTLNLSR,LNATRESR,LNRESNCR,SC";
37295
37295
  function safePct4(num, den) {
37296
37296
  if (num === null || den === null || den === 0) return null;
37297
37297
  return num / den * 100;
@@ -38022,7 +38022,7 @@ function buildSubsidiaryRecord(inst, financials) {
38022
38022
  return {
38023
38023
  cert: typeof inst.CERT === "number" ? inst.CERT : 0,
38024
38024
  name: String(inst.NAME ?? ""),
38025
- hc_name: inst.NAMHCR ? String(inst.NAMHCR) : null,
38025
+ hc_name: inst.NAMEHCR ? String(inst.NAMEHCR) : null,
38026
38026
  total_assets: typeof inst.ASSET === "number" ? inst.ASSET : 0,
38027
38027
  total_deposits: typeof inst.DEP === "number" ? inst.DEP : 0,
38028
38028
  roa: financials ? asNumber(financials.ROA) : null,
@@ -38033,7 +38033,7 @@ function buildSubsidiaryRecord(inst, financials) {
38033
38033
  }
38034
38034
 
38035
38035
  // src/tools/holdingCompanyProfile.ts
38036
- var INSTITUTION_FIELDS = "CERT,NAME,STALP,CITY,ASSET,DEP,NAMHCR,HCTMULT,ACTIVE,SPECGRP,CHRTAGNT";
38036
+ var INSTITUTION_FIELDS = "CERT,NAME,STALP,CITY,ASSET,DEP,NAMEHCR,HCTMULT,ACTIVE,SPECGRP,CHRTAGNT";
38037
38037
  var FINANCIAL_FIELDS2 = "CERT,ROA,EQV";
38038
38038
  function fmtPct5(val) {
38039
38039
  return val !== null ? `${val.toFixed(2)}%` : "n/a";
@@ -38129,7 +38129,7 @@ NOTE: This is an analytical tool based on public financial data.`,
38129
38129
  ENDPOINTS.INSTITUTIONS,
38130
38130
  {
38131
38131
  filters: `CERT:${rawParams.cert}`,
38132
- fields: "CERT,NAMHCR",
38132
+ fields: "CERT,NAMEHCR",
38133
38133
  limit: 1
38134
38134
  },
38135
38135
  { signal: controller.signal }
@@ -38140,11 +38140,11 @@ NOTE: This is an analytical tool based on public financial data.`,
38140
38140
  new Error(`No institution found with CERT number ${rawParams.cert}.`)
38141
38141
  );
38142
38142
  }
38143
- const namhcr = certRecords[0].NAMHCR;
38143
+ const namhcr = certRecords[0].NAMEHCR;
38144
38144
  if (!namhcr || String(namhcr).trim() === "") {
38145
38145
  return formatToolError(
38146
38146
  new Error(
38147
- `Institution with CERT ${rawParams.cert} is not part of a holding company (NAMHCR is empty).`
38147
+ `Institution with CERT ${rawParams.cert} is not part of a holding company (NAMEHCR is empty).`
38148
38148
  )
38149
38149
  );
38150
38150
  }
@@ -38161,7 +38161,7 @@ NOTE: This is an analytical tool based on public financial data.`,
38161
38161
  const instResponse = await queryEndpoint(
38162
38162
  ENDPOINTS.INSTITUTIONS,
38163
38163
  {
38164
- filters: `NAMHCR:"${hcName}"`,
38164
+ filters: `NAMEHCR:"${hcName}"`,
38165
38165
  fields: INSTITUTION_FIELDS,
38166
38166
  limit: 500,
38167
38167
  sort_by: "ASSET",
@@ -38173,7 +38173,7 @@ NOTE: This is an analytical tool based on public financial data.`,
38173
38173
  if (instRecords.length === 0) {
38174
38174
  return formatToolError(
38175
38175
  new Error(
38176
- `No institutions found for holding company "${hcName}". Check the name spelling (use NAMHCR value from FDIC data).`
38176
+ `No institutions found for holding company "${hcName}". Check the name spelling (use NAMEHCR value from FDIC data).`
38177
38177
  )
38178
38178
  );
38179
38179
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fdic-mcp-server",
3
- "version": "1.17.0",
3
+ "version": "1.18.0",
4
4
  "description": "MCP server for the FDIC BankFind Suite API",
5
5
  "mcpName": "io.github.jflamb/fdic-mcp-server",
6
6
  "main": "dist/server.js",