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 +18 -0
- package/dist/index.js +9 -9
- package/dist/server.js +9 -9
- package/package.json +1 -1
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.
|
|
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,
|
|
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.
|
|
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,
|
|
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,
|
|
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].
|
|
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 (
|
|
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: `
|
|
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
|
|
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.
|
|
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,
|
|
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.
|
|
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,
|
|
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,
|
|
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].
|
|
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 (
|
|
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: `
|
|
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
|
|
38176
|
+
`No institutions found for holding company "${hcName}". Check the name spelling (use NAMEHCR value from FDIC data).`
|
|
38177
38177
|
)
|
|
38178
38178
|
);
|
|
38179
38179
|
}
|