fdic-mcp-server 1.24.0 → 1.25.1
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/dist/index.js +718 -477
- package/dist/server.js +722 -479
- package/package.json +4 -2
package/dist/server.js
CHANGED
|
@@ -35,7 +35,8 @@ __export(index_exports, {
|
|
|
35
35
|
main: () => main,
|
|
36
36
|
parseAllowedOrigins: () => parseAllowedOrigins,
|
|
37
37
|
parseHttpHost: () => parseHttpHost,
|
|
38
|
-
parseHttpPort: () => parseHttpPort
|
|
38
|
+
parseHttpPort: () => parseHttpPort,
|
|
39
|
+
resolveProfile: () => resolveProfile
|
|
39
40
|
});
|
|
40
41
|
module.exports = __toCommonJS(index_exports);
|
|
41
42
|
var import_node_crypto2 = require("node:crypto");
|
|
@@ -46,7 +47,7 @@ var import_types = require("@modelcontextprotocol/sdk/types.js");
|
|
|
46
47
|
var import_express2 = __toESM(require("express"));
|
|
47
48
|
|
|
48
49
|
// src/constants.ts
|
|
49
|
-
var VERSION = true ? "1.
|
|
50
|
+
var VERSION = true ? "1.25.1" : process.env.npm_package_version ?? "0.0.0-dev";
|
|
50
51
|
var FDIC_API_BASE_URL = "https://banks.data.fdic.gov/api";
|
|
51
52
|
var CHARACTER_LIMIT = 5e4;
|
|
52
53
|
var DEFAULT_FDIC_MAX_RESPONSE_BYTES = 5 * 1024 * 1024;
|
|
@@ -31860,13 +31861,96 @@ function formatLookupResultText(label, record, preferredKeys) {
|
|
|
31860
31861
|
return `${label}
|
|
31861
31862
|
${summarizeRecord(record, preferredKeys, 8)}`;
|
|
31862
31863
|
}
|
|
31863
|
-
|
|
31864
|
+
var ERROR_CODE_FROM_MESSAGE = [
|
|
31865
|
+
{ pattern: /Bad request to FDIC API/, code: "FDIC_BAD_FILTER", retryable: false },
|
|
31866
|
+
{ pattern: /rate limit/i, code: "FDIC_RATE_LIMIT", retryable: true },
|
|
31867
|
+
{ pattern: /server error/i, code: "FDIC_UPSTREAM_ERROR", retryable: true },
|
|
31868
|
+
{
|
|
31869
|
+
pattern: /response-size limit|maxContentLength/,
|
|
31870
|
+
code: "FDIC_RESPONSE_TOO_LARGE",
|
|
31871
|
+
retryable: false
|
|
31872
|
+
},
|
|
31873
|
+
{ pattern: /canceled/i, code: "FDIC_CANCELED", retryable: true },
|
|
31874
|
+
{ pattern: /No (institution|failure|financial)/i, code: "FDIC_NOT_FOUND", retryable: false },
|
|
31875
|
+
{ pattern: /quarter-end date/i, code: "FDIC_BAD_DATE", retryable: false }
|
|
31876
|
+
];
|
|
31877
|
+
function inferErrorCode(message) {
|
|
31878
|
+
for (const entry of ERROR_CODE_FROM_MESSAGE) {
|
|
31879
|
+
if (entry.pattern.test(message)) {
|
|
31880
|
+
return { code: entry.code, retryable: entry.retryable };
|
|
31881
|
+
}
|
|
31882
|
+
}
|
|
31883
|
+
return { code: "FDIC_UNKNOWN", retryable: false };
|
|
31884
|
+
}
|
|
31885
|
+
function formatToolError(err, override) {
|
|
31864
31886
|
const message = err instanceof Error ? err.message : String(err);
|
|
31887
|
+
const inferred = inferErrorCode(message);
|
|
31888
|
+
const payload = {
|
|
31889
|
+
code: override?.code ?? inferred.code,
|
|
31890
|
+
message: override?.message ?? message,
|
|
31891
|
+
retryable: override?.retryable ?? inferred.retryable,
|
|
31892
|
+
hint: override?.hint
|
|
31893
|
+
};
|
|
31865
31894
|
return {
|
|
31866
|
-
content: [{ type: "text", text: `Error: ${message}` }],
|
|
31895
|
+
content: [{ type: "text", text: `Error: ${payload.message}` }],
|
|
31896
|
+
structuredContent: payload,
|
|
31867
31897
|
isError: true
|
|
31868
31898
|
};
|
|
31869
31899
|
}
|
|
31900
|
+
var DEFAULT_STRUCTURED_BYTE_LIMIT = 2e5;
|
|
31901
|
+
function capStructuredContent(output, recordKey, byteLimit = DEFAULT_STRUCTURED_BYTE_LIMIT) {
|
|
31902
|
+
const records = output[recordKey];
|
|
31903
|
+
if (!Array.isArray(records)) {
|
|
31904
|
+
return output;
|
|
31905
|
+
}
|
|
31906
|
+
const initialBytes = Buffer.byteLength(JSON.stringify(output), "utf8");
|
|
31907
|
+
if (initialBytes <= byteLimit) {
|
|
31908
|
+
return output;
|
|
31909
|
+
}
|
|
31910
|
+
let lo = 0;
|
|
31911
|
+
let hi = records.length;
|
|
31912
|
+
let best = 0;
|
|
31913
|
+
while (lo <= hi) {
|
|
31914
|
+
const mid = Math.floor((lo + hi) / 2);
|
|
31915
|
+
const candidate = buildTruncatedPayload(output, recordKey, records, mid);
|
|
31916
|
+
const bytes = Buffer.byteLength(JSON.stringify(candidate), "utf8");
|
|
31917
|
+
if (bytes <= byteLimit) {
|
|
31918
|
+
best = mid;
|
|
31919
|
+
lo = mid + 1;
|
|
31920
|
+
} else {
|
|
31921
|
+
hi = mid - 1;
|
|
31922
|
+
}
|
|
31923
|
+
}
|
|
31924
|
+
if (best === 0) {
|
|
31925
|
+
throw new Error(
|
|
31926
|
+
"FDIC API response exceeded the configured response-size limit before parsing: a single record exceeded the structured-content byte cap. Request fewer fields with `fields=`, lower `limit`, or raise the cap."
|
|
31927
|
+
);
|
|
31928
|
+
}
|
|
31929
|
+
return buildTruncatedPayload(output, recordKey, records, best);
|
|
31930
|
+
}
|
|
31931
|
+
function buildTruncatedPayload(output, recordKey, records, slicedLength) {
|
|
31932
|
+
const sliced = records.slice(0, slicedLength);
|
|
31933
|
+
const result = {
|
|
31934
|
+
...output,
|
|
31935
|
+
[recordKey]: sliced,
|
|
31936
|
+
truncated: true
|
|
31937
|
+
};
|
|
31938
|
+
const offset = typeof output.offset === "number" ? output.offset : void 0;
|
|
31939
|
+
const upstreamCount = typeof output.count === "number" ? output.count : void 0;
|
|
31940
|
+
const upstreamNextOffset = typeof output.next_offset === "number" ? output.next_offset : void 0;
|
|
31941
|
+
if (offset !== void 0) {
|
|
31942
|
+
result.count = slicedLength;
|
|
31943
|
+
result.next_offset = offset + slicedLength;
|
|
31944
|
+
result.has_more = true;
|
|
31945
|
+
}
|
|
31946
|
+
if (upstreamCount !== void 0 || upstreamNextOffset !== void 0) {
|
|
31947
|
+
result.upstream = {
|
|
31948
|
+
...upstreamCount !== void 0 ? { count: upstreamCount } : {},
|
|
31949
|
+
...upstreamNextOffset !== void 0 ? { next_offset: upstreamNextOffset } : {}
|
|
31950
|
+
};
|
|
31951
|
+
}
|
|
31952
|
+
return result;
|
|
31953
|
+
}
|
|
31870
31954
|
|
|
31871
31955
|
// src/schemas/common.ts
|
|
31872
31956
|
var import_zod = require("zod");
|
|
@@ -31891,6 +31975,91 @@ var CertSchema = import_zod.z.object({
|
|
|
31891
31975
|
fields: import_zod.z.string().optional().describe("Comma-separated list of fields to return")
|
|
31892
31976
|
});
|
|
31893
31977
|
|
|
31978
|
+
// src/schemas/output.ts
|
|
31979
|
+
var import_zod2 = require("zod");
|
|
31980
|
+
var FdicRecord = import_zod2.z.record(import_zod2.z.unknown());
|
|
31981
|
+
var Pagination = {
|
|
31982
|
+
total: import_zod2.z.number().int(),
|
|
31983
|
+
offset: import_zod2.z.number().int(),
|
|
31984
|
+
count: import_zod2.z.number().int(),
|
|
31985
|
+
has_more: import_zod2.z.boolean(),
|
|
31986
|
+
next_offset: import_zod2.z.number().int().optional()
|
|
31987
|
+
};
|
|
31988
|
+
function paginatedSearchSchema(recordKey) {
|
|
31989
|
+
return import_zod2.z.object({
|
|
31990
|
+
...Pagination,
|
|
31991
|
+
[recordKey]: import_zod2.z.array(FdicRecord),
|
|
31992
|
+
truncated: import_zod2.z.boolean().optional()
|
|
31993
|
+
});
|
|
31994
|
+
}
|
|
31995
|
+
var FdicInstitutionsSearchOutputSchema = paginatedSearchSchema(
|
|
31996
|
+
"institutions"
|
|
31997
|
+
);
|
|
31998
|
+
var FdicFailuresSearchOutputSchema = paginatedSearchSchema("failures");
|
|
31999
|
+
var FdicLocationsSearchOutputSchema = paginatedSearchSchema("locations");
|
|
32000
|
+
var FdicHistorySearchOutputSchema = paginatedSearchSchema("events");
|
|
32001
|
+
var FdicFinancialsSearchOutputSchema = paginatedSearchSchema(
|
|
32002
|
+
"financials"
|
|
32003
|
+
);
|
|
32004
|
+
var FdicSummarySearchOutputSchema = paginatedSearchSchema("summary");
|
|
32005
|
+
var FdicSodSearchOutputSchema = paginatedSearchSchema("deposits");
|
|
32006
|
+
var FdicDemographicsSearchOutputSchema = paginatedSearchSchema(
|
|
32007
|
+
"demographics"
|
|
32008
|
+
);
|
|
32009
|
+
var FdicInstitutionLookupOutputSchema = import_zod2.z.object({}).passthrough();
|
|
32010
|
+
var FdicFailureLookupOutputSchema = import_zod2.z.object({}).passthrough();
|
|
32011
|
+
var ChatGptSearchResultSchema = import_zod2.z.object({
|
|
32012
|
+
results: import_zod2.z.array(
|
|
32013
|
+
import_zod2.z.object({
|
|
32014
|
+
id: import_zod2.z.string(),
|
|
32015
|
+
title: import_zod2.z.string(),
|
|
32016
|
+
url: import_zod2.z.string()
|
|
32017
|
+
})
|
|
32018
|
+
)
|
|
32019
|
+
});
|
|
32020
|
+
var ChatGptFetchResultSchema = import_zod2.z.object({
|
|
32021
|
+
id: import_zod2.z.string(),
|
|
32022
|
+
title: import_zod2.z.string(),
|
|
32023
|
+
text: import_zod2.z.string(),
|
|
32024
|
+
url: import_zod2.z.string(),
|
|
32025
|
+
metadata: import_zod2.z.record(import_zod2.z.unknown()).optional()
|
|
32026
|
+
});
|
|
32027
|
+
var Source = import_zod2.z.object({ title: import_zod2.z.string(), url: import_zod2.z.string() });
|
|
32028
|
+
var FdicBankDeepDiveOutputSchema = import_zod2.z.object({
|
|
32029
|
+
institution: import_zod2.z.object({
|
|
32030
|
+
cert: import_zod2.z.number().int(),
|
|
32031
|
+
name: import_zod2.z.string(),
|
|
32032
|
+
city: import_zod2.z.string(),
|
|
32033
|
+
state: import_zod2.z.string(),
|
|
32034
|
+
active: import_zod2.z.boolean(),
|
|
32035
|
+
asset_thousands: import_zod2.z.number().optional(),
|
|
32036
|
+
deposit_thousands: import_zod2.z.number().optional(),
|
|
32037
|
+
offices: import_zod2.z.number().optional(),
|
|
32038
|
+
charter_class: import_zod2.z.string(),
|
|
32039
|
+
regulator: import_zod2.z.string(),
|
|
32040
|
+
established: import_zod2.z.string(),
|
|
32041
|
+
report_date: import_zod2.z.string()
|
|
32042
|
+
}),
|
|
32043
|
+
assessment: import_zod2.z.object({
|
|
32044
|
+
official_rating: import_zod2.z.boolean(),
|
|
32045
|
+
proxy_band: import_zod2.z.string(),
|
|
32046
|
+
caveat: import_zod2.z.string()
|
|
32047
|
+
}),
|
|
32048
|
+
metrics: import_zod2.z.object({
|
|
32049
|
+
roa: import_zod2.z.string().optional(),
|
|
32050
|
+
roe: import_zod2.z.string().optional(),
|
|
32051
|
+
tier1_leverage: import_zod2.z.string().optional(),
|
|
32052
|
+
noncurrent_loans: import_zod2.z.string().optional(),
|
|
32053
|
+
loan_to_deposit: import_zod2.z.string().optional(),
|
|
32054
|
+
net_interest_margin: import_zod2.z.string().optional(),
|
|
32055
|
+
efficiency_ratio: import_zod2.z.string().optional()
|
|
32056
|
+
}),
|
|
32057
|
+
risk_signals: import_zod2.z.array(import_zod2.z.string()),
|
|
32058
|
+
warnings: import_zod2.z.array(import_zod2.z.string()),
|
|
32059
|
+
sources: import_zod2.z.array(Source)
|
|
32060
|
+
});
|
|
32061
|
+
var FdicAnalysisOutputSchema = import_zod2.z.object({}).passthrough();
|
|
32062
|
+
|
|
31894
32063
|
// src/tools/institutions.ts
|
|
31895
32064
|
function registerInstitutionTools(server) {
|
|
31896
32065
|
server.registerTool(
|
|
@@ -31899,6 +32068,7 @@ function registerInstitutionTools(server) {
|
|
|
31899
32068
|
title: "Search FDIC Institutions",
|
|
31900
32069
|
description: "Use this when the user needs FDIC-insured institution search results by name, state, CERT, asset size, charter class, or regulatory status. Returns institution profile rows with pagination; use fdic://schemas/institutions for the full field catalog.",
|
|
31901
32070
|
inputSchema: CommonQuerySchema,
|
|
32071
|
+
outputSchema: FdicInstitutionsSearchOutputSchema,
|
|
31902
32072
|
annotations: {
|
|
31903
32073
|
readOnlyHint: true,
|
|
31904
32074
|
destructiveHint: false,
|
|
@@ -31915,7 +32085,10 @@ function registerInstitutionTools(server) {
|
|
|
31915
32085
|
params.offset ?? 0,
|
|
31916
32086
|
records.length
|
|
31917
32087
|
);
|
|
31918
|
-
const output =
|
|
32088
|
+
const output = capStructuredContent(
|
|
32089
|
+
{ ...pagination, institutions: records },
|
|
32090
|
+
"institutions"
|
|
32091
|
+
);
|
|
31919
32092
|
const text = truncateIfNeeded(
|
|
31920
32093
|
formatSearchResultText("institutions", records, pagination, [
|
|
31921
32094
|
"CERT",
|
|
@@ -31941,8 +32114,9 @@ function registerInstitutionTools(server) {
|
|
|
31941
32114
|
"fdic_get_institution",
|
|
31942
32115
|
{
|
|
31943
32116
|
title: "Get Institution by Certificate Number",
|
|
31944
|
-
description: "Use this when the user knows an exact FDIC Certificate Number and needs one institution profile. To discover a CERT first, call fdic_search_institutions or
|
|
32117
|
+
description: "Use this when the user knows an exact FDIC Certificate Number and needs one institution profile. To discover a CERT first, call fdic_search_institutions or fdic_search.",
|
|
31945
32118
|
inputSchema: CertSchema,
|
|
32119
|
+
outputSchema: FdicInstitutionLookupOutputSchema,
|
|
31946
32120
|
annotations: {
|
|
31947
32121
|
readOnlyHint: true,
|
|
31948
32122
|
destructiveHint: false,
|
|
@@ -31997,43 +32171,9 @@ function registerFailureTools(server) {
|
|
|
31997
32171
|
"fdic_search_failures",
|
|
31998
32172
|
{
|
|
31999
32173
|
title: "Search Bank Failures",
|
|
32000
|
-
description:
|
|
32001
|
-
|
|
32002
|
-
Returns data on bank failures including failure date, resolution type, estimated cost to the FDIC Deposit Insurance Fund, and acquiring institution info.
|
|
32003
|
-
|
|
32004
|
-
Common filter examples:
|
|
32005
|
-
- By state: STALP:CA (two-letter state code)
|
|
32006
|
-
- By year range: FAILDATE:[2008-01-01 TO 2010-12-31]
|
|
32007
|
-
- Recent failures: FAILDATE:[2020-01-01 TO *]
|
|
32008
|
-
- By resolution type: RESTYPE:PAYOFF or RESTYPE:"PURCHASE AND ASSUMPTION"
|
|
32009
|
-
- Large failures by cost: COST:[100000 TO *] (cost in $thousands)
|
|
32010
|
-
- By name: NAME:"Washington Mutual"
|
|
32011
|
-
|
|
32012
|
-
Resolution types (RESTYPE):
|
|
32013
|
-
PAYOFF = depositors paid directly, no acquirer
|
|
32014
|
-
PURCHASE AND ASSUMPTION = acquirer buys assets and assumes deposits
|
|
32015
|
-
PAYOUT = variant of payoff with insured-deposit transfer
|
|
32016
|
-
|
|
32017
|
-
Key returned fields:
|
|
32018
|
-
- CERT: FDIC Certificate Number
|
|
32019
|
-
- NAME: Institution name
|
|
32020
|
-
- CITY, STALP (two-letter state code), STNAME (full state name): Location
|
|
32021
|
-
- FAILDATE: Date of failure (YYYY-MM-DD)
|
|
32022
|
-
- SAVR: Savings association flag (SA) or bank (BK)
|
|
32023
|
-
- RESTYPE: Resolution type (see above)
|
|
32024
|
-
- QBFASSET: Total assets at failure ($thousands)
|
|
32025
|
-
- COST: Estimated cost to FDIC Deposit Insurance Fund ($thousands)
|
|
32026
|
-
|
|
32027
|
-
Args:
|
|
32028
|
-
- filters (string, optional): ElasticSearch query filter
|
|
32029
|
-
- fields (string, optional): Comma-separated field names
|
|
32030
|
-
- limit (number): Records to return (default: 20)
|
|
32031
|
-
- offset (number): Pagination offset (default: 0)
|
|
32032
|
-
- sort_by (string, optional): Field to sort by (e.g., FAILDATE, COST)
|
|
32033
|
-
- sort_order ('ASC'|'DESC'): Sort direction (default: 'ASC')
|
|
32034
|
-
|
|
32035
|
-
Prefer concise human-readable summaries or tables when answering users. Structured fields are available for totals, pagination, and failure records.`,
|
|
32174
|
+
description: "Use this when the user wants details on failed FDIC-insured institutions filtered by name, state, date range, resolution type, or cost. Returns failure records with pagination; see fdic://schemas/failures for the full field catalog.",
|
|
32036
32175
|
inputSchema: CommonQuerySchema,
|
|
32176
|
+
outputSchema: FdicFailuresSearchOutputSchema,
|
|
32037
32177
|
annotations: {
|
|
32038
32178
|
readOnlyHint: true,
|
|
32039
32179
|
destructiveHint: false,
|
|
@@ -32050,7 +32190,10 @@ Prefer concise human-readable summaries or tables when answering users. Structur
|
|
|
32050
32190
|
params.offset ?? 0,
|
|
32051
32191
|
records.length
|
|
32052
32192
|
);
|
|
32053
|
-
const output =
|
|
32193
|
+
const output = capStructuredContent(
|
|
32194
|
+
{ ...pagination, failures: records },
|
|
32195
|
+
"failures"
|
|
32196
|
+
);
|
|
32054
32197
|
const text = truncateIfNeeded(
|
|
32055
32198
|
formatSearchResultText("failures", records, pagination, [
|
|
32056
32199
|
"CERT",
|
|
@@ -32077,16 +32220,9 @@ Prefer concise human-readable summaries or tables when answering users. Structur
|
|
|
32077
32220
|
"fdic_get_institution_failure",
|
|
32078
32221
|
{
|
|
32079
32222
|
title: "Get Failure Details by Certificate Number",
|
|
32080
|
-
description:
|
|
32081
|
-
|
|
32082
|
-
Use this when you know the CERT of a failed institution to get its specific failure record.
|
|
32083
|
-
|
|
32084
|
-
Args:
|
|
32085
|
-
- cert (number): FDIC Certificate Number of the failed institution
|
|
32086
|
-
- fields (string, optional): Comma-separated list of fields to return
|
|
32087
|
-
|
|
32088
|
-
Returns detailed failure information suitable for concise summaries, with structured fields available for exact values when needed.`,
|
|
32223
|
+
description: "Use this when the user knows the CERT of a failed institution and needs its specific failure record. Returns failure details (date, resolution type, cost, acquirer); responds with `found: false` if the institution did not fail.",
|
|
32089
32224
|
inputSchema: CertSchema,
|
|
32225
|
+
outputSchema: FdicFailureLookupOutputSchema,
|
|
32090
32226
|
annotations: {
|
|
32091
32227
|
readOnlyHint: true,
|
|
32092
32228
|
destructiveHint: false,
|
|
@@ -32136,7 +32272,7 @@ Returns detailed failure information suitable for concise summaries, with struct
|
|
|
32136
32272
|
}
|
|
32137
32273
|
|
|
32138
32274
|
// src/tools/locations.ts
|
|
32139
|
-
var
|
|
32275
|
+
var import_zod3 = require("zod");
|
|
32140
32276
|
|
|
32141
32277
|
// src/tools/shared/queryUtils.ts
|
|
32142
32278
|
var CHUNK_SIZE = 25;
|
|
@@ -32232,7 +32368,7 @@ async function mapWithConcurrency(values, limit, mapper) {
|
|
|
32232
32368
|
|
|
32233
32369
|
// src/tools/locations.ts
|
|
32234
32370
|
var LocationQuerySchema = CommonQuerySchema.extend({
|
|
32235
|
-
cert:
|
|
32371
|
+
cert: import_zod3.z.number().int().positive().optional().describe(
|
|
32236
32372
|
"Filter by FDIC Certificate Number to get all branches of a specific institution"
|
|
32237
32373
|
)
|
|
32238
32374
|
});
|
|
@@ -32241,53 +32377,9 @@ function registerLocationTools(server) {
|
|
|
32241
32377
|
"fdic_search_locations",
|
|
32242
32378
|
{
|
|
32243
32379
|
title: "Search Institution Locations / Branches",
|
|
32244
|
-
description:
|
|
32245
|
-
|
|
32246
|
-
Returns branch/office data including address, city, state, coordinates, branch type, and establishment date.
|
|
32247
|
-
|
|
32248
|
-
Common filter examples:
|
|
32249
|
-
- All branches of a bank: CERT:3511
|
|
32250
|
-
- By state: STALP:TX (two-letter state code)
|
|
32251
|
-
- By city: CITY:"Austin"
|
|
32252
|
-
- Main offices only: BRNUM:0
|
|
32253
|
-
- By county: COUNTY:"Travis"
|
|
32254
|
-
- Active branches only: ENDEFYMD:[9999-01-01 TO *] (sentinel date 9999-12-31 means still open)
|
|
32255
|
-
- By metro area (CBSA): CBSA_METRO_NAME:"New York-Newark-Jersey City"
|
|
32256
|
-
|
|
32257
|
-
Branch service types (BRSERTYP):
|
|
32258
|
-
11 = Full service brick and mortar
|
|
32259
|
-
12 = Full service retail
|
|
32260
|
-
21 = Limited service administrative
|
|
32261
|
-
22 = Limited service military
|
|
32262
|
-
23 = Limited service drive-through
|
|
32263
|
-
24 = Limited service loan production
|
|
32264
|
-
25 = Limited service consumer/trust
|
|
32265
|
-
26 = Limited service Internet/mobile
|
|
32266
|
-
29 = Limited service other
|
|
32267
|
-
|
|
32268
|
-
Key returned fields:
|
|
32269
|
-
- CERT: FDIC Certificate Number
|
|
32270
|
-
- UNINAME: Institution name
|
|
32271
|
-
- NAMEFULL: Full branch name
|
|
32272
|
-
- ADDRESS, CITY, STALP (two-letter state code), ZIP: Branch address
|
|
32273
|
-
- COUNTY: County name
|
|
32274
|
-
- BRNUM: Branch number (0 = main office)
|
|
32275
|
-
- BRSERTYP: Branch service type code (see above)
|
|
32276
|
-
- LATITUDE, LONGITUDE: Geographic coordinates
|
|
32277
|
-
- ESTYMD: Branch established date (YYYY-MM-DD)
|
|
32278
|
-
- ENDEFYMD: Branch end date (9999-12-31 if still active)
|
|
32279
|
-
|
|
32280
|
-
Args:
|
|
32281
|
-
- cert (number, optional): Filter by institution CERT number
|
|
32282
|
-
- filters (string, optional): Additional ElasticSearch query filters
|
|
32283
|
-
- fields (string, optional): Comma-separated field names
|
|
32284
|
-
- limit (number): Records to return (default: 20)
|
|
32285
|
-
- offset (number): Pagination offset (default: 0)
|
|
32286
|
-
- sort_by (string, optional): Field to sort by
|
|
32287
|
-
- sort_order ('ASC'|'DESC'): Sort direction (default: 'ASC')
|
|
32288
|
-
|
|
32289
|
-
Prefer concise human-readable summaries or tables when answering users. Structured fields are available for totals, pagination, and branch location records.`,
|
|
32380
|
+
description: "Use this when the user wants branch/office locations for FDIC-insured institutions, filtered by CERT, state, city, county, metro area, or branch type. Returns address, coordinates, branch number, and service-type rows; see fdic://schemas/locations for the full field catalog.",
|
|
32290
32381
|
inputSchema: LocationQuerySchema,
|
|
32382
|
+
outputSchema: FdicLocationsSearchOutputSchema,
|
|
32291
32383
|
annotations: {
|
|
32292
32384
|
readOnlyHint: true,
|
|
32293
32385
|
destructiveHint: false,
|
|
@@ -32311,7 +32403,10 @@ Prefer concise human-readable summaries or tables when answering users. Structur
|
|
|
32311
32403
|
params.offset ?? 0,
|
|
32312
32404
|
records.length
|
|
32313
32405
|
);
|
|
32314
|
-
const output =
|
|
32406
|
+
const output = capStructuredContent(
|
|
32407
|
+
{ ...pagination, locations: records },
|
|
32408
|
+
"locations"
|
|
32409
|
+
);
|
|
32315
32410
|
const text = truncateIfNeeded(
|
|
32316
32411
|
formatSearchResultText("locations", records, pagination, [
|
|
32317
32412
|
"CERT",
|
|
@@ -32336,9 +32431,9 @@ Prefer concise human-readable summaries or tables when answering users. Structur
|
|
|
32336
32431
|
}
|
|
32337
32432
|
|
|
32338
32433
|
// src/tools/history.ts
|
|
32339
|
-
var
|
|
32434
|
+
var import_zod4 = require("zod");
|
|
32340
32435
|
var HistoryQuerySchema = CommonQuerySchema.extend({
|
|
32341
|
-
cert:
|
|
32436
|
+
cert: import_zod4.z.number().int().positive().optional().describe(
|
|
32342
32437
|
"Filter by FDIC Certificate Number to get history for a specific institution"
|
|
32343
32438
|
)
|
|
32344
32439
|
});
|
|
@@ -32347,57 +32442,9 @@ function registerHistoryTools(server) {
|
|
|
32347
32442
|
"fdic_search_history",
|
|
32348
32443
|
{
|
|
32349
32444
|
title: "Search Institution History / Structure Changes",
|
|
32350
|
-
description:
|
|
32351
|
-
|
|
32352
|
-
Returns records on mergers, acquisitions, name changes, charter conversions, failures, and other significant structural events.
|
|
32353
|
-
|
|
32354
|
-
Common filter examples:
|
|
32355
|
-
- History for a specific bank: CERT:3511
|
|
32356
|
-
- Mergers: TYPE:merger
|
|
32357
|
-
- Failures: TYPE:failure
|
|
32358
|
-
- Name changes: CHANGECODE:CO
|
|
32359
|
-
- By date range: PROCDATE:[2008-01-01 TO 2009-12-31]
|
|
32360
|
-
- By state: PSTALP:CA (two-letter state code)
|
|
32361
|
-
|
|
32362
|
-
Event types (TYPE):
|
|
32363
|
-
merger = institution was merged into another
|
|
32364
|
-
failure = institution failed
|
|
32365
|
-
assistance = received FDIC assistance transaction
|
|
32366
|
-
insurance = insurance-related event (new coverage, termination)
|
|
32367
|
-
|
|
32368
|
-
Common change codes (CHANGECODE):
|
|
32369
|
-
CO = name change
|
|
32370
|
-
CR = charter conversion
|
|
32371
|
-
DC = deposit assumption change
|
|
32372
|
-
MA = merger/acquisition (absorbed by another institution)
|
|
32373
|
-
NI = new institution insured
|
|
32374
|
-
TC = trust company conversion
|
|
32375
|
-
|
|
32376
|
-
Key returned fields:
|
|
32377
|
-
- CERT: FDIC Certificate Number
|
|
32378
|
-
- INSTNAME: Institution name
|
|
32379
|
-
- CLASS: Charter class at time of change
|
|
32380
|
-
- PCITY, PSTALP: Location (city, two-letter state code)
|
|
32381
|
-
- PROCDATE: Processing date of the change (YYYY-MM-DD)
|
|
32382
|
-
- EFFDATE: Effective date of the change (YYYY-MM-DD)
|
|
32383
|
-
- ENDEFYMD: End effective date
|
|
32384
|
-
- PCERT: Predecessor/successor CERT (for mergers)
|
|
32385
|
-
- TYPE: Type of structural change (see above)
|
|
32386
|
-
- CHANGECODE: Code for type of change (see above)
|
|
32387
|
-
- CHANGECODE_DESC: Human-readable description of the change code
|
|
32388
|
-
- INSDATE: Insurance date
|
|
32389
|
-
|
|
32390
|
-
Args:
|
|
32391
|
-
- cert (number, optional): Filter by institution CERT number
|
|
32392
|
-
- filters (string, optional): ElasticSearch query filters
|
|
32393
|
-
- fields (string, optional): Comma-separated field names
|
|
32394
|
-
- limit (number): Records to return (default: 20)
|
|
32395
|
-
- offset (number): Pagination offset (default: 0)
|
|
32396
|
-
- sort_by (string, optional): Field to sort by (e.g., PROCDATE)
|
|
32397
|
-
- sort_order ('ASC'|'DESC'): Sort direction (default: 'ASC')
|
|
32398
|
-
|
|
32399
|
-
Prefer concise human-readable summaries or tables when answering users. Structured fields are available for totals, pagination, and event records.`,
|
|
32445
|
+
description: "Use this when the user wants structural-change events (mergers, acquisitions, name changes, charter conversions, failures) for FDIC-insured institutions, filtered by CERT, type, change code, date range, or state. See fdic://schemas/history for the full field catalog.",
|
|
32400
32446
|
inputSchema: HistoryQuerySchema,
|
|
32447
|
+
outputSchema: FdicHistorySearchOutputSchema,
|
|
32401
32448
|
annotations: {
|
|
32402
32449
|
readOnlyHint: true,
|
|
32403
32450
|
destructiveHint: false,
|
|
@@ -32421,7 +32468,10 @@ Prefer concise human-readable summaries or tables when answering users. Structur
|
|
|
32421
32468
|
params.offset ?? 0,
|
|
32422
32469
|
records.length
|
|
32423
32470
|
);
|
|
32424
|
-
const output =
|
|
32471
|
+
const output = capStructuredContent(
|
|
32472
|
+
{ ...pagination, events: records },
|
|
32473
|
+
"events"
|
|
32474
|
+
);
|
|
32425
32475
|
const text = truncateIfNeeded(
|
|
32426
32476
|
formatSearchResultText("events", records, pagination, [
|
|
32427
32477
|
"CERT",
|
|
@@ -32446,63 +32496,30 @@ Prefer concise human-readable summaries or tables when answering users. Structur
|
|
|
32446
32496
|
}
|
|
32447
32497
|
|
|
32448
32498
|
// src/tools/financials.ts
|
|
32449
|
-
var
|
|
32499
|
+
var import_zod5 = require("zod");
|
|
32450
32500
|
var FinancialQuerySchema = CommonQuerySchema.extend({
|
|
32451
|
-
sort_order:
|
|
32501
|
+
sort_order: import_zod5.z.enum(["ASC", "DESC"]).default("DESC").describe(
|
|
32452
32502
|
"Sort direction: DESC (descending, default for most recent first) or ASC (ascending)"
|
|
32453
32503
|
),
|
|
32454
|
-
cert:
|
|
32504
|
+
cert: import_zod5.z.number().int().positive().optional().describe(
|
|
32455
32505
|
"Filter by FDIC Certificate Number to get financials for a specific institution"
|
|
32456
32506
|
),
|
|
32457
|
-
repdte:
|
|
32458
|
-
"Filter by Report Date (REPDTE) in YYYYMMDD format
|
|
32507
|
+
repdte: import_zod5.z.string().optional().describe(
|
|
32508
|
+
"Filter by Report Date (REPDTE) in YYYYMMDD format (quarter-end: 0331, 0630, 0930, 1231). If omitted, returns all available dates (sorted most recent first)."
|
|
32459
32509
|
)
|
|
32460
32510
|
});
|
|
32461
32511
|
var SummaryQuerySchema = CommonQuerySchema.extend({
|
|
32462
|
-
cert:
|
|
32463
|
-
year:
|
|
32512
|
+
cert: import_zod5.z.number().int().positive().optional().describe("Filter by FDIC Certificate Number"),
|
|
32513
|
+
year: import_zod5.z.number().int().min(1934).optional().describe("Filter by specific year (e.g., 2022)")
|
|
32464
32514
|
});
|
|
32465
32515
|
function registerFinancialTools(server) {
|
|
32466
32516
|
server.registerTool(
|
|
32467
32517
|
"fdic_search_financials",
|
|
32468
32518
|
{
|
|
32469
32519
|
title: "Search Institution Financial Data",
|
|
32470
|
-
description:
|
|
32471
|
-
|
|
32472
|
-
Returns balance sheet, income statement, capital, and performance ratio data from FDIC Call Reports.
|
|
32473
|
-
|
|
32474
|
-
Common filter examples:
|
|
32475
|
-
- Financials for a specific bank: CERT:3511
|
|
32476
|
-
- By report date: REPDTE:20231231
|
|
32477
|
-
- High-profit banks in Q4 2023: REPDTE:20231231 AND ROA:[1.5 TO *]
|
|
32478
|
-
- Large banks most recent: ASSET:[10000000 TO *]
|
|
32479
|
-
- Negative net income: NETINC:[* TO 0]
|
|
32480
|
-
|
|
32481
|
-
Key returned fields:
|
|
32482
|
-
- CERT: FDIC Certificate Number
|
|
32483
|
-
- REPDTE: Report Date \u2014 the last day of the quarterly reporting period (YYYYMMDD)
|
|
32484
|
-
- ASSET: Total assets ($thousands)
|
|
32485
|
-
- DEP: Total deposits ($thousands)
|
|
32486
|
-
- DEPDOM: Domestic deposits ($thousands)
|
|
32487
|
-
- INTINC: Total interest income ($thousands)
|
|
32488
|
-
- EINTEXP: Total interest expense ($thousands)
|
|
32489
|
-
- NETINC: Net income ($thousands)
|
|
32490
|
-
- ROA: Return on assets (%)
|
|
32491
|
-
- ROE: Return on equity (%)
|
|
32492
|
-
- NETNIM: Net interest margin (%)
|
|
32493
|
-
|
|
32494
|
-
Args:
|
|
32495
|
-
- cert (number, optional): Filter by institution CERT number
|
|
32496
|
-
- repdte (string, optional): Report Date in YYYYMMDD format (quarter-end dates: 0331, 0630, 0930, 1231)
|
|
32497
|
-
- filters (string, optional): Additional ElasticSearch query filters
|
|
32498
|
-
- fields (string, optional): Comma-separated field names (the full set has 1,100+ fields)
|
|
32499
|
-
- limit (number): Records to return (default: 20)
|
|
32500
|
-
- offset (number): Pagination offset (default: 0)
|
|
32501
|
-
- sort_by (string, optional): Field to sort by
|
|
32502
|
-
- sort_order ('ASC'|'DESC'): Sort direction (default: 'DESC' recommended for most recent first)
|
|
32503
|
-
|
|
32504
|
-
Prefer concise human-readable summaries or tables when answering users. Structured fields are available for totals, pagination, and quarterly financial records.`,
|
|
32520
|
+
description: "Use this when the user wants quarterly Call Report data (balance sheet, income, capital, performance ratios) for FDIC-insured institutions. Filter by CERT and/or REPDTE plus optional ElasticSearch filters. See fdic://schemas/financials for the full 1,100+ field catalog.",
|
|
32505
32521
|
inputSchema: FinancialQuerySchema,
|
|
32522
|
+
outputSchema: FdicFinancialsSearchOutputSchema,
|
|
32506
32523
|
annotations: {
|
|
32507
32524
|
readOnlyHint: true,
|
|
32508
32525
|
destructiveHint: false,
|
|
@@ -32527,7 +32544,10 @@ Prefer concise human-readable summaries or tables when answering users. Structur
|
|
|
32527
32544
|
params.offset ?? 0,
|
|
32528
32545
|
records.length
|
|
32529
32546
|
);
|
|
32530
|
-
const output =
|
|
32547
|
+
const output = capStructuredContent(
|
|
32548
|
+
{ ...pagination, financials: records },
|
|
32549
|
+
"financials"
|
|
32550
|
+
);
|
|
32531
32551
|
const text = truncateIfNeeded(
|
|
32532
32552
|
formatSearchResultText("financial records", records, pagination, [
|
|
32533
32553
|
"CERT",
|
|
@@ -32553,40 +32573,9 @@ Prefer concise human-readable summaries or tables when answering users. Structur
|
|
|
32553
32573
|
"fdic_search_summary",
|
|
32554
32574
|
{
|
|
32555
32575
|
title: "Search Annual Financial Summary Data",
|
|
32556
|
-
description:
|
|
32557
|
-
|
|
32558
|
-
Returns annual snapshots of key financial metrics \u2014 useful for tracking an institution's growth over time.
|
|
32559
|
-
|
|
32560
|
-
Common filter examples:
|
|
32561
|
-
- Annual history for a bank: CERT:3511
|
|
32562
|
-
- Specific year: YEAR:2022
|
|
32563
|
-
- Year range: YEAR:[2010 TO 2020]
|
|
32564
|
-
- Large banks in 2022: YEAR:2022 AND ASSET:[10000000 TO *]
|
|
32565
|
-
- Profitable in 2023: YEAR:2023 AND ROE:[10 TO *]
|
|
32566
|
-
|
|
32567
|
-
Key returned fields:
|
|
32568
|
-
- CERT: FDIC Certificate Number
|
|
32569
|
-
- YEAR: Report year
|
|
32570
|
-
- ASSET: Total assets ($thousands)
|
|
32571
|
-
- DEP: Total deposits ($thousands)
|
|
32572
|
-
- NETINC: Net income ($thousands)
|
|
32573
|
-
- ROA: Return on assets (%)
|
|
32574
|
-
- ROE: Return on equity (%)
|
|
32575
|
-
- OFFICES: Number of branch offices
|
|
32576
|
-
- REPDTE: Report Date \u2014 the last day of the reporting period (YYYYMMDD)
|
|
32577
|
-
|
|
32578
|
-
Args:
|
|
32579
|
-
- cert (number, optional): Filter by institution CERT number
|
|
32580
|
-
- year (number, optional): Filter by specific year (1934-present)
|
|
32581
|
-
- filters (string, optional): Additional ElasticSearch query filters
|
|
32582
|
-
- fields (string, optional): Comma-separated field names
|
|
32583
|
-
- limit (number): Records to return (default: 20)
|
|
32584
|
-
- offset (number): Pagination offset (default: 0)
|
|
32585
|
-
- sort_by (string, optional): Field to sort by (e.g., YEAR, ASSET)
|
|
32586
|
-
- sort_order ('ASC'|'DESC'): Sort direction (default: 'ASC')
|
|
32587
|
-
|
|
32588
|
-
Prefer concise human-readable summaries or tables when answering users. Structured fields are available for totals, pagination, and annual summary records.`,
|
|
32576
|
+
description: "Use this when the user wants annual financial-summary snapshots (assets, deposits, ROA, ROE, offices) for FDIC-insured institutions, filtered by CERT and/or year. See fdic://schemas/summary for the full field catalog.",
|
|
32589
32577
|
inputSchema: SummaryQuerySchema,
|
|
32578
|
+
outputSchema: FdicSummarySearchOutputSchema,
|
|
32590
32579
|
annotations: {
|
|
32591
32580
|
readOnlyHint: true,
|
|
32592
32581
|
destructiveHint: false,
|
|
@@ -32611,7 +32600,10 @@ Prefer concise human-readable summaries or tables when answering users. Structur
|
|
|
32611
32600
|
params.offset ?? 0,
|
|
32612
32601
|
records.length
|
|
32613
32602
|
);
|
|
32614
|
-
const output =
|
|
32603
|
+
const output = capStructuredContent(
|
|
32604
|
+
{ ...pagination, summary: records },
|
|
32605
|
+
"summary"
|
|
32606
|
+
);
|
|
32615
32607
|
const text = truncateIfNeeded(
|
|
32616
32608
|
formatSearchResultText("annual summary records", records, pagination, [
|
|
32617
32609
|
"CERT",
|
|
@@ -32636,10 +32628,10 @@ Prefer concise human-readable summaries or tables when answering users. Structur
|
|
|
32636
32628
|
}
|
|
32637
32629
|
|
|
32638
32630
|
// src/tools/sod.ts
|
|
32639
|
-
var
|
|
32631
|
+
var import_zod6 = require("zod");
|
|
32640
32632
|
var SodQuerySchema = CommonQuerySchema.extend({
|
|
32641
|
-
cert:
|
|
32642
|
-
year:
|
|
32633
|
+
cert: import_zod6.z.number().int().positive().optional().describe("Filter by FDIC Certificate Number"),
|
|
32634
|
+
year: import_zod6.z.number().int().min(1994).optional().describe(
|
|
32643
32635
|
"Filter by specific year (1994-present). SOD data is annual."
|
|
32644
32636
|
)
|
|
32645
32637
|
});
|
|
@@ -32648,40 +32640,9 @@ function registerSodTools(server) {
|
|
|
32648
32640
|
"fdic_search_sod",
|
|
32649
32641
|
{
|
|
32650
32642
|
title: "Search Summary of Deposits (SOD)",
|
|
32651
|
-
description:
|
|
32652
|
-
|
|
32653
|
-
The SOD report provides annual deposit data at the branch level, showing deposit balances for each office of every FDIC-insured institution as of June 30 each year.
|
|
32654
|
-
|
|
32655
|
-
Common filter examples:
|
|
32656
|
-
- All branches for a bank: CERT:3511
|
|
32657
|
-
- SOD for specific year: YEAR:2022
|
|
32658
|
-
- Branches in a state: STALPBR:CA
|
|
32659
|
-
- Branches in a city: CITYBR:"Austin"
|
|
32660
|
-
- High-deposit branches: DEPSUMBR:[1000000 TO *]
|
|
32661
|
-
- By metro area (MSA code): MSABR:19100
|
|
32662
|
-
|
|
32663
|
-
Key returned fields:
|
|
32664
|
-
- YEAR: Report year (as of June 30)
|
|
32665
|
-
- CERT: FDIC Certificate Number
|
|
32666
|
-
- BRNUM: Branch number (0 = main office)
|
|
32667
|
-
- NAMEFULL: Branch or institution name
|
|
32668
|
-
- ADDRESBR, CITYBR, STALPBR, ZIPBR: Branch address
|
|
32669
|
-
- DEPSUMBR: Total deposits at branch ($thousands)
|
|
32670
|
-
- MSABR: Metropolitan Statistical Area code (numeric; 0 = non-MSA)
|
|
32671
|
-
- LATITUDE, LONGITUDE: Coordinates
|
|
32672
|
-
|
|
32673
|
-
Args:
|
|
32674
|
-
- cert (number, optional): Filter by institution CERT number
|
|
32675
|
-
- year (number, optional): SOD report year (1994-present)
|
|
32676
|
-
- filters (string, optional): Additional ElasticSearch query filters
|
|
32677
|
-
- fields (string, optional): Comma-separated field names
|
|
32678
|
-
- limit (number): Records to return (default: 20)
|
|
32679
|
-
- offset (number): Pagination offset (default: 0)
|
|
32680
|
-
- sort_by (string, optional): Field to sort by (e.g., DEPSUMBR, YEAR)
|
|
32681
|
-
- sort_order ('ASC'|'DESC'): Sort direction (default: 'ASC')
|
|
32682
|
-
|
|
32683
|
-
Prefer concise human-readable summaries or tables when answering users. Structured fields are available for totals, pagination, and deposit records.`,
|
|
32643
|
+
description: "Use this when the user wants annual branch-level deposit data (SOD, as of June 30 each year) \u2014 branch deposits, MSAs, geographic distribution. Filter by CERT and/or year. See fdic://schemas/sod for the full field catalog.",
|
|
32684
32644
|
inputSchema: SodQuerySchema,
|
|
32645
|
+
outputSchema: FdicSodSearchOutputSchema,
|
|
32685
32646
|
annotations: {
|
|
32686
32647
|
readOnlyHint: true,
|
|
32687
32648
|
destructiveHint: false,
|
|
@@ -32706,7 +32667,10 @@ Prefer concise human-readable summaries or tables when answering users. Structur
|
|
|
32706
32667
|
params.offset ?? 0,
|
|
32707
32668
|
records.length
|
|
32708
32669
|
);
|
|
32709
|
-
const output =
|
|
32670
|
+
const output = capStructuredContent(
|
|
32671
|
+
{ ...pagination, deposits: records },
|
|
32672
|
+
"deposits"
|
|
32673
|
+
);
|
|
32710
32674
|
const text = truncateIfNeeded(
|
|
32711
32675
|
formatSearchResultText("deposit records", records, pagination, [
|
|
32712
32676
|
"CERT",
|
|
@@ -32731,11 +32695,11 @@ Prefer concise human-readable summaries or tables when answering users. Structur
|
|
|
32731
32695
|
}
|
|
32732
32696
|
|
|
32733
32697
|
// src/tools/demographics.ts
|
|
32734
|
-
var
|
|
32698
|
+
var import_zod7 = require("zod");
|
|
32735
32699
|
var DemographicsQuerySchema = CommonQuerySchema.extend({
|
|
32736
|
-
cert:
|
|
32737
|
-
repdte:
|
|
32738
|
-
"Filter by Report Date (REPDTE) in YYYYMMDD format
|
|
32700
|
+
cert: import_zod7.z.number().int().positive().optional().describe("Filter by FDIC Certificate Number"),
|
|
32701
|
+
repdte: import_zod7.z.string().optional().describe(
|
|
32702
|
+
"Filter by Report Date (REPDTE) in YYYYMMDD format (quarter-end: 0331, 0630, 0930, 1231)."
|
|
32739
32703
|
)
|
|
32740
32704
|
});
|
|
32741
32705
|
function registerDemographicsTools(server) {
|
|
@@ -32743,43 +32707,9 @@ function registerDemographicsTools(server) {
|
|
|
32743
32707
|
"fdic_search_demographics",
|
|
32744
32708
|
{
|
|
32745
32709
|
title: "Search Institution Demographics Data",
|
|
32746
|
-
description:
|
|
32747
|
-
|
|
32748
|
-
Returns quarterly demographic and market-structure attributes such as office counts, territory assignments, metro classification, county/country codes, and selected geographic reference data.
|
|
32749
|
-
|
|
32750
|
-
Common filter examples:
|
|
32751
|
-
- Demographics for a specific bank: CERT:3511
|
|
32752
|
-
- By report date: REPDTE:20251231
|
|
32753
|
-
- Institutions in metro areas: METRO:1
|
|
32754
|
-
- Institutions with out-of-state offices: OFFSTATE:[1 TO *]
|
|
32755
|
-
- Minority status date present: MNRTYDTE:[19000101 TO 99991231]
|
|
32756
|
-
|
|
32757
|
-
Key returned fields:
|
|
32758
|
-
- CERT: FDIC Certificate Number
|
|
32759
|
-
- REPDTE: Report Date \u2014 the last day of the quarterly reporting period (YYYYMMDD)
|
|
32760
|
-
- QTRNO: Quarter number
|
|
32761
|
-
- OFFTOT: Total offices
|
|
32762
|
-
- OFFSTATE: Offices in other states
|
|
32763
|
-
- OFFNDOM: Offices in non-domestic territories
|
|
32764
|
-
- OFFOTH: Other offices
|
|
32765
|
-
- OFFSOD: Offices included in Summary of Deposits
|
|
32766
|
-
- METRO, MICRO: Metro/micro area flags
|
|
32767
|
-
- CBSANAME, CSA: Core-based statistical area data
|
|
32768
|
-
- FDICTERR, RISKTERR: FDIC and risk territory assignments
|
|
32769
|
-
- SIMS_LAT, SIMS_LONG: Geographic coordinates
|
|
32770
|
-
|
|
32771
|
-
Args:
|
|
32772
|
-
- cert (number, optional): Filter by institution CERT number
|
|
32773
|
-
- repdte (string, optional): Report Date in YYYYMMDD format (quarter-end dates: 0331, 0630, 0930, 1231)
|
|
32774
|
-
- filters (string, optional): Additional ElasticSearch query filters
|
|
32775
|
-
- fields (string, optional): Comma-separated field names
|
|
32776
|
-
- limit (number): Records to return (default: 20)
|
|
32777
|
-
- offset (number): Pagination offset (default: 0)
|
|
32778
|
-
- sort_by (string, optional): Field to sort by
|
|
32779
|
-
- sort_order ('ASC'|'DESC'): Sort direction (default: 'ASC')
|
|
32780
|
-
|
|
32781
|
-
Prefer concise human-readable summaries or tables when answering users. Structured fields are available for totals, pagination, and demographic records.`,
|
|
32710
|
+
description: "Use this when the user wants quarterly demographic and market-structure attributes (office counts, metro classification, county/territory codes, geographic reference data) for FDIC-insured institutions. Filter by CERT and/or REPDTE. See fdic://schemas/demographics for the full field catalog.",
|
|
32782
32711
|
inputSchema: DemographicsQuerySchema,
|
|
32712
|
+
outputSchema: FdicDemographicsSearchOutputSchema,
|
|
32783
32713
|
annotations: {
|
|
32784
32714
|
readOnlyHint: true,
|
|
32785
32715
|
destructiveHint: false,
|
|
@@ -32804,7 +32734,10 @@ Prefer concise human-readable summaries or tables when answering users. Structur
|
|
|
32804
32734
|
params.offset ?? 0,
|
|
32805
32735
|
records.length
|
|
32806
32736
|
);
|
|
32807
|
-
const output =
|
|
32737
|
+
const output = capStructuredContent(
|
|
32738
|
+
{ ...pagination, demographics: records },
|
|
32739
|
+
"demographics"
|
|
32740
|
+
);
|
|
32808
32741
|
const text = truncateIfNeeded(
|
|
32809
32742
|
formatSearchResultText("demographic records", records, pagination, [
|
|
32810
32743
|
"CERT",
|
|
@@ -32829,7 +32762,7 @@ Prefer concise human-readable summaries or tables when answering users. Structur
|
|
|
32829
32762
|
}
|
|
32830
32763
|
|
|
32831
32764
|
// src/tools/analysis.ts
|
|
32832
|
-
var
|
|
32765
|
+
var import_zod8 = require("zod");
|
|
32833
32766
|
|
|
32834
32767
|
// src/tools/shared/progress.ts
|
|
32835
32768
|
function asProgressToken(value) {
|
|
@@ -32855,7 +32788,7 @@ async function sendProgressNotification(sender, progressToken, progress, message
|
|
|
32855
32788
|
}
|
|
32856
32789
|
|
|
32857
32790
|
// src/tools/analysis.ts
|
|
32858
|
-
var SortFieldSchema =
|
|
32791
|
+
var SortFieldSchema = import_zod8.z.enum([
|
|
32859
32792
|
"asset_growth",
|
|
32860
32793
|
"asset_growth_pct",
|
|
32861
32794
|
"dep_growth",
|
|
@@ -32869,35 +32802,35 @@ var SortFieldSchema = import_zod7.z.enum([
|
|
|
32869
32802
|
"deposits_per_office_change",
|
|
32870
32803
|
"deposits_to_assets_change"
|
|
32871
32804
|
]);
|
|
32872
|
-
var AnalysisModeSchema =
|
|
32873
|
-
var SnapshotAnalysisSchema =
|
|
32874
|
-
state:
|
|
32805
|
+
var AnalysisModeSchema = import_zod8.z.enum(["snapshot", "timeseries"]);
|
|
32806
|
+
var SnapshotAnalysisSchema = import_zod8.z.object({
|
|
32807
|
+
state: import_zod8.z.string().optional().describe(
|
|
32875
32808
|
'State name for the institution roster filter. Example: "North Carolina"'
|
|
32876
32809
|
),
|
|
32877
|
-
certs:
|
|
32810
|
+
certs: import_zod8.z.array(import_zod8.z.number().int().positive()).max(100).optional().describe(
|
|
32878
32811
|
"Optional list of FDIC certificate numbers to compare directly. Max 100."
|
|
32879
32812
|
),
|
|
32880
|
-
institution_filters:
|
|
32813
|
+
institution_filters: import_zod8.z.string().optional().describe(
|
|
32881
32814
|
'Additional institution-level filter used when building the comparison set. Example: BKCLASS:N or CITY:"Charlotte"'
|
|
32882
32815
|
),
|
|
32883
|
-
active_only:
|
|
32884
|
-
start_repdte:
|
|
32816
|
+
active_only: import_zod8.z.boolean().default(true).describe("Limit the comparison set to currently active institutions."),
|
|
32817
|
+
start_repdte: import_zod8.z.string().regex(/^\d{8}$/).optional().describe(
|
|
32885
32818
|
"Starting Report Date (REPDTE) in YYYYMMDD format. Must be a quarter-end date: March 31 (0331), June 30 (0630), September 30 (0930), or December 31 (1231). Example: 20210331 for Q1 2021. If omitted, defaults to the same quarter one year before end_repdte."
|
|
32886
32819
|
),
|
|
32887
|
-
end_repdte:
|
|
32820
|
+
end_repdte: import_zod8.z.string().regex(/^\d{8}$/).optional().describe(
|
|
32888
32821
|
"Ending Report Date (REPDTE) in YYYYMMDD format. Must be a quarter-end date: March 31 (0331), June 30 (0630), September 30 (0930), or December 31 (1231). Must be later than start_repdte. Example: 20251231 for Q4 2025. If omitted, defaults to the most recent quarter-end date with published data (~90-day lag)."
|
|
32889
32822
|
),
|
|
32890
32823
|
analysis_mode: AnalysisModeSchema.default("snapshot").describe(
|
|
32891
32824
|
"Use snapshot for two-point comparison or timeseries for quarterly trend analysis across the date range."
|
|
32892
32825
|
),
|
|
32893
|
-
include_demographics:
|
|
32826
|
+
include_demographics: import_zod8.z.boolean().default(true).describe(
|
|
32894
32827
|
"Include office-count changes from the demographics dataset when available."
|
|
32895
32828
|
),
|
|
32896
|
-
limit:
|
|
32829
|
+
limit: import_zod8.z.number().int().min(1).max(100).default(10).describe("Maximum number of ranked comparisons to return."),
|
|
32897
32830
|
sort_by: SortFieldSchema.default("asset_growth").describe(
|
|
32898
32831
|
"Comparison field used to rank institutions. Valid options: asset_growth, asset_growth_pct, dep_growth, dep_growth_pct, netinc_change, netinc_change_pct, roa_change, roe_change, offices_change, assets_per_office_change, deposits_per_office_change, deposits_to_assets_change."
|
|
32899
32832
|
),
|
|
32900
|
-
sort_order:
|
|
32833
|
+
sort_order: import_zod8.z.enum(["ASC", "DESC"]).default("DESC").describe("Sort direction for the ranked comparisons.")
|
|
32901
32834
|
});
|
|
32902
32835
|
function resolveSnapshotDefaults(params) {
|
|
32903
32836
|
const end_repdte = params.end_repdte ?? getDefaultReportDate();
|
|
@@ -33448,6 +33381,7 @@ Inputs:
|
|
|
33448
33381
|
|
|
33449
33382
|
Returns concise comparison text plus structured deltas, derived metrics, and insight tags for each institution.`,
|
|
33450
33383
|
inputSchema: SnapshotAnalysisSchema,
|
|
33384
|
+
outputSchema: FdicAnalysisOutputSchema,
|
|
33451
33385
|
annotations: {
|
|
33452
33386
|
readOnlyHint: true,
|
|
33453
33387
|
destructiveHint: false,
|
|
@@ -33701,7 +33635,7 @@ Returns concise comparison text plus structured deltas, derived metrics, and ins
|
|
|
33701
33635
|
}
|
|
33702
33636
|
|
|
33703
33637
|
// src/tools/peerGroup.ts
|
|
33704
|
-
var
|
|
33638
|
+
var import_zod9 = require("zod");
|
|
33705
33639
|
|
|
33706
33640
|
// src/tools/shared/financialMetrics.ts
|
|
33707
33641
|
function safeRatio(numerator, denominator) {
|
|
@@ -33845,33 +33779,33 @@ var METRIC_DEFINITIONS = {
|
|
|
33845
33779
|
label: "Non-Interest Income Share"
|
|
33846
33780
|
}
|
|
33847
33781
|
};
|
|
33848
|
-
var PeerGroupInputSchema =
|
|
33849
|
-
cert:
|
|
33782
|
+
var PeerGroupInputSchema = import_zod9.z.object({
|
|
33783
|
+
cert: import_zod9.z.number().int().positive().optional().describe(
|
|
33850
33784
|
"Subject institution CERT number. When provided, auto-derives peer criteria and ranks this bank against peers."
|
|
33851
33785
|
),
|
|
33852
|
-
repdte:
|
|
33786
|
+
repdte: import_zod9.z.string().regex(/^\d{8}$/).optional().describe(
|
|
33853
33787
|
"Report Date (REPDTE) in YYYYMMDD format. FDIC data is published quarterly on: March 31, June 30, September 30, and December 31. Example: 20231231 for Q4 2023. If omitted, defaults to the most recent quarter-end date likely to have published data (~90-day lag)."
|
|
33854
33788
|
),
|
|
33855
|
-
asset_min:
|
|
33789
|
+
asset_min: import_zod9.z.number().positive().optional().describe(
|
|
33856
33790
|
"Minimum total assets ($thousands) for peer selection. Defaults to 50% of subject's report-date assets when cert is provided."
|
|
33857
33791
|
),
|
|
33858
|
-
asset_max:
|
|
33792
|
+
asset_max: import_zod9.z.number().positive().optional().describe(
|
|
33859
33793
|
"Maximum total assets ($thousands) for peer selection. Defaults to 200% of subject's report-date assets when cert is provided."
|
|
33860
33794
|
),
|
|
33861
|
-
charter_classes:
|
|
33795
|
+
charter_classes: import_zod9.z.array(import_zod9.z.string()).optional().describe(
|
|
33862
33796
|
`Charter class codes to include (e.g., ["N", "SM"]). Defaults to the subject's charter class when cert is provided.`
|
|
33863
33797
|
),
|
|
33864
|
-
state:
|
|
33865
|
-
raw_filter:
|
|
33798
|
+
state: import_zod9.z.string().regex(/^[A-Z]{2}$/).optional().describe('Two-letter state code (e.g., "NC", "TX").'),
|
|
33799
|
+
raw_filter: import_zod9.z.string().optional().describe(
|
|
33866
33800
|
"Advanced: raw ElasticSearch query string appended to peer selection criteria with AND."
|
|
33867
33801
|
),
|
|
33868
|
-
active_only:
|
|
33802
|
+
active_only: import_zod9.z.boolean().default(true).describe(
|
|
33869
33803
|
"Limit to institutions where ACTIVE:1 (currently operating, FDIC-insured)."
|
|
33870
33804
|
),
|
|
33871
|
-
extra_fields:
|
|
33805
|
+
extra_fields: import_zod9.z.array(import_zod9.z.string()).optional().describe(
|
|
33872
33806
|
"Additional FDIC field names to include as raw values in the response. Does not affect peer selection."
|
|
33873
33807
|
),
|
|
33874
|
-
limit:
|
|
33808
|
+
limit: import_zod9.z.number().int().min(1).max(500).default(50).describe(
|
|
33875
33809
|
"Max peer records returned in the response. All matched peers are used for ranking regardless of this limit."
|
|
33876
33810
|
)
|
|
33877
33811
|
});
|
|
@@ -34000,6 +33934,7 @@ Output includes:
|
|
|
34000
33934
|
|
|
34001
33935
|
Override precedence: cert derives defaults, then explicit params override them.`,
|
|
34002
33936
|
inputSchema: PeerGroupInputSchema,
|
|
33937
|
+
outputSchema: FdicAnalysisOutputSchema,
|
|
34003
33938
|
annotations: {
|
|
34004
33939
|
readOnlyHint: true,
|
|
34005
33940
|
destructiveHint: false,
|
|
@@ -34336,7 +34271,7 @@ Override precedence: cert derives defaults, then explicit params override them.`
|
|
|
34336
34271
|
}
|
|
34337
34272
|
|
|
34338
34273
|
// src/tools/bankHealth.ts
|
|
34339
|
-
var
|
|
34274
|
+
var import_zod10 = require("zod");
|
|
34340
34275
|
|
|
34341
34276
|
// src/tools/shared/camelsScoring.ts
|
|
34342
34277
|
var SCORING_RULES = {
|
|
@@ -35657,12 +35592,12 @@ function collectRiskSignals(metrics, components, trends) {
|
|
|
35657
35592
|
}
|
|
35658
35593
|
return signals;
|
|
35659
35594
|
}
|
|
35660
|
-
var BankHealthInputSchema =
|
|
35661
|
-
cert:
|
|
35662
|
-
repdte:
|
|
35595
|
+
var BankHealthInputSchema = import_zod10.z.object({
|
|
35596
|
+
cert: import_zod10.z.number().int().positive().describe("FDIC Certificate Number of the institution to analyze."),
|
|
35597
|
+
repdte: import_zod10.z.string().regex(/^\d{8}$/).optional().describe(
|
|
35663
35598
|
"Report Date (YYYYMMDD). Defaults to the most recent quarter likely to have published data."
|
|
35664
35599
|
),
|
|
35665
|
-
quarters:
|
|
35600
|
+
quarters: import_zod10.z.number().int().min(1).max(20).default(8).describe("Number of prior quarters to fetch for trend analysis (default 8).")
|
|
35666
35601
|
});
|
|
35667
35602
|
function registerBankHealthTools(server) {
|
|
35668
35603
|
server.registerTool(
|
|
@@ -35683,6 +35618,7 @@ Output includes:
|
|
|
35683
35618
|
|
|
35684
35619
|
NOTE: Management (M) is omitted from component scoring \u2014 cannot be assessed from public data. Sensitivity (S) uses proxy metrics (NIM trend, securities concentration). This is a public off-site analytical proxy, not an official CAMELS rating.`,
|
|
35685
35620
|
inputSchema: BankHealthInputSchema,
|
|
35621
|
+
outputSchema: FdicAnalysisOutputSchema,
|
|
35686
35622
|
annotations: {
|
|
35687
35623
|
readOnlyHint: true,
|
|
35688
35624
|
destructiveHint: false,
|
|
@@ -35824,7 +35760,7 @@ NOTE: Management (M) is omitted from component scoring \u2014 cannot be assessed
|
|
|
35824
35760
|
}
|
|
35825
35761
|
|
|
35826
35762
|
// src/tools/peerHealth.ts
|
|
35827
|
-
var
|
|
35763
|
+
var import_zod11 = require("zod");
|
|
35828
35764
|
|
|
35829
35765
|
// src/tools/shared/peerEngine.ts
|
|
35830
35766
|
function computeMedian2(values) {
|
|
@@ -35898,15 +35834,15 @@ function computePeerStats(subjectValue, peerValues, options) {
|
|
|
35898
35834
|
}
|
|
35899
35835
|
|
|
35900
35836
|
// src/tools/peerHealth.ts
|
|
35901
|
-
var PeerHealthInputSchema =
|
|
35902
|
-
cert:
|
|
35903
|
-
certs:
|
|
35904
|
-
state:
|
|
35905
|
-
asset_min:
|
|
35906
|
-
asset_max:
|
|
35907
|
-
repdte:
|
|
35908
|
-
sort_by:
|
|
35909
|
-
limit:
|
|
35837
|
+
var PeerHealthInputSchema = import_zod11.z.object({
|
|
35838
|
+
cert: import_zod11.z.number().int().positive().optional().describe("Subject institution CERT to highlight in the ranking. Optional."),
|
|
35839
|
+
certs: import_zod11.z.array(import_zod11.z.number().int().positive()).max(50).optional().describe("Explicit list of CERTs to compare (max 50)."),
|
|
35840
|
+
state: import_zod11.z.string().regex(/^[A-Z]{2}$/).optional().describe('Two-letter state code to select all active institutions (e.g., "WY").'),
|
|
35841
|
+
asset_min: import_zod11.z.number().positive().optional().describe("Minimum total assets ($thousands) for peer selection."),
|
|
35842
|
+
asset_max: import_zod11.z.number().positive().optional().describe("Maximum total assets ($thousands) for peer selection."),
|
|
35843
|
+
repdte: import_zod11.z.string().regex(/^\d{8}$/).optional().describe("Report Date (YYYYMMDD). Defaults to the most recent quarter."),
|
|
35844
|
+
sort_by: import_zod11.z.enum(["composite", "capital", "asset_quality", "earnings", "liquidity", "sensitivity"]).default("composite").describe("Sort results by composite or a specific CAMELS component rating."),
|
|
35845
|
+
limit: import_zod11.z.number().int().min(1).max(100).default(25).describe("Max institutions to return in the response.")
|
|
35910
35846
|
});
|
|
35911
35847
|
function sortKeyToComponent(key) {
|
|
35912
35848
|
const map = {
|
|
@@ -35936,6 +35872,7 @@ Output: Ranked list with per-institution proxy_score (1-4 scale) and proxy_band,
|
|
|
35936
35872
|
|
|
35937
35873
|
NOTE: Public off-site analytical proxy \u2014 not official supervisory ratings.`,
|
|
35938
35874
|
inputSchema: PeerHealthInputSchema,
|
|
35875
|
+
outputSchema: FdicAnalysisOutputSchema,
|
|
35939
35876
|
annotations: {
|
|
35940
35877
|
readOnlyHint: true,
|
|
35941
35878
|
destructiveHint: false,
|
|
@@ -36305,7 +36242,7 @@ NOTE: Public off-site analytical proxy \u2014 not official supervisory ratings.`
|
|
|
36305
36242
|
}
|
|
36306
36243
|
|
|
36307
36244
|
// src/tools/riskSignals.ts
|
|
36308
|
-
var
|
|
36245
|
+
var import_zod12 = require("zod");
|
|
36309
36246
|
function classifyRiskSignals(metrics, trends) {
|
|
36310
36247
|
const signals = [];
|
|
36311
36248
|
if (metrics.tier1_leverage !== null && metrics.tier1_leverage < 5) {
|
|
@@ -36376,15 +36313,15 @@ function classifyRiskSignals(metrics, trends) {
|
|
|
36376
36313
|
return signals;
|
|
36377
36314
|
}
|
|
36378
36315
|
var SEVERITY_ORDER = { critical: 0, warning: 1, info: 2 };
|
|
36379
|
-
var RiskSignalsInputSchema =
|
|
36380
|
-
state:
|
|
36381
|
-
certs:
|
|
36382
|
-
asset_min:
|
|
36383
|
-
asset_max:
|
|
36384
|
-
repdte:
|
|
36385
|
-
min_severity:
|
|
36386
|
-
quarters:
|
|
36387
|
-
limit:
|
|
36316
|
+
var RiskSignalsInputSchema = import_zod12.z.object({
|
|
36317
|
+
state: import_zod12.z.string().regex(/^[A-Z]{2}$/).optional().describe("Scan all active institutions in this state."),
|
|
36318
|
+
certs: import_zod12.z.array(import_zod12.z.number().int().positive()).max(50).optional().describe("Specific CERTs to scan (max 50)."),
|
|
36319
|
+
asset_min: import_zod12.z.number().positive().optional().describe("Minimum total assets ($thousands) filter."),
|
|
36320
|
+
asset_max: import_zod12.z.number().positive().optional().describe("Maximum total assets ($thousands) filter."),
|
|
36321
|
+
repdte: import_zod12.z.string().regex(/^\d{8}$/).optional().describe("Report Date (YYYYMMDD). Defaults to the most recent quarter."),
|
|
36322
|
+
min_severity: import_zod12.z.enum(["info", "warning", "critical"]).default("warning").describe("Minimum severity level to include in results (default: warning)."),
|
|
36323
|
+
quarters: import_zod12.z.number().int().min(1).max(12).default(4).describe("Prior quarters to fetch for trend analysis (default 4)."),
|
|
36324
|
+
limit: import_zod12.z.number().int().min(1).max(100).default(25).describe("Max flagged institutions to return.")
|
|
36388
36325
|
});
|
|
36389
36326
|
function registerRiskSignalTools(server) {
|
|
36390
36327
|
server.registerTool(
|
|
@@ -36407,6 +36344,7 @@ Output: Per-institution risk signals ranked by severity count. The proxy engine
|
|
|
36407
36344
|
|
|
36408
36345
|
NOTE: Public off-site analytical proxy \u2014 not official supervisory ratings.`,
|
|
36409
36346
|
inputSchema: RiskSignalsInputSchema,
|
|
36347
|
+
outputSchema: FdicAnalysisOutputSchema,
|
|
36410
36348
|
annotations: {
|
|
36411
36349
|
readOnlyHint: true,
|
|
36412
36350
|
destructiveHint: false,
|
|
@@ -36626,7 +36564,7 @@ NOTE: Public off-site analytical proxy \u2014 not official supervisory ratings.`
|
|
|
36626
36564
|
}
|
|
36627
36565
|
|
|
36628
36566
|
// src/tools/creditConcentration.ts
|
|
36629
|
-
var
|
|
36567
|
+
var import_zod13 = require("zod");
|
|
36630
36568
|
|
|
36631
36569
|
// src/tools/shared/creditConcentration.ts
|
|
36632
36570
|
var CREDIT_FIELDS = [
|
|
@@ -36742,9 +36680,9 @@ function formatCreditSummaryText(summary) {
|
|
|
36742
36680
|
}
|
|
36743
36681
|
return parts.join("\n");
|
|
36744
36682
|
}
|
|
36745
|
-
var CreditConcentrationSchema =
|
|
36746
|
-
cert:
|
|
36747
|
-
repdte:
|
|
36683
|
+
var CreditConcentrationSchema = import_zod13.z.object({
|
|
36684
|
+
cert: import_zod13.z.number().int().positive().describe("FDIC Certificate Number"),
|
|
36685
|
+
repdte: import_zod13.z.string().regex(/^\d{8}$/).optional().describe("Report date (YYYYMMDD). Defaults to most recent quarter.")
|
|
36748
36686
|
});
|
|
36749
36687
|
function registerCreditConcentrationTools(server) {
|
|
36750
36688
|
server.registerTool(
|
|
@@ -36762,6 +36700,7 @@ Output includes:
|
|
|
36762
36700
|
|
|
36763
36701
|
NOTE: This is an analytical tool based on public financial data.`,
|
|
36764
36702
|
inputSchema: CreditConcentrationSchema,
|
|
36703
|
+
outputSchema: FdicAnalysisOutputSchema,
|
|
36765
36704
|
annotations: {
|
|
36766
36705
|
readOnlyHint: true,
|
|
36767
36706
|
destructiveHint: false,
|
|
@@ -36848,7 +36787,7 @@ NOTE: This is an analytical tool based on public financial data.`,
|
|
|
36848
36787
|
}
|
|
36849
36788
|
|
|
36850
36789
|
// src/tools/fundingProfile.ts
|
|
36851
|
-
var
|
|
36790
|
+
var import_zod14 = require("zod");
|
|
36852
36791
|
|
|
36853
36792
|
// src/tools/shared/fundingProfile.ts
|
|
36854
36793
|
var FUNDING_FIELDS = "CERT,REPDTE,ASSET,DEP,DEPDOM,DEPFOR,COREDEP,BROR,FREPP,EFREPP,EINTEXP,DEPDASTR,CHBALR,LNLSDEPR";
|
|
@@ -36948,9 +36887,9 @@ function formatFundingSummaryText(summary) {
|
|
|
36948
36887
|
}
|
|
36949
36888
|
return parts.join("\n");
|
|
36950
36889
|
}
|
|
36951
|
-
var FundingProfileSchema =
|
|
36952
|
-
cert:
|
|
36953
|
-
repdte:
|
|
36890
|
+
var FundingProfileSchema = import_zod14.z.object({
|
|
36891
|
+
cert: import_zod14.z.number().int().positive().describe("FDIC Certificate Number"),
|
|
36892
|
+
repdte: import_zod14.z.string().regex(/^\d{8}$/).optional().describe("Report date (YYYYMMDD). Defaults to most recent quarter.")
|
|
36954
36893
|
});
|
|
36955
36894
|
function registerFundingProfileTools(server) {
|
|
36956
36895
|
server.registerTool(
|
|
@@ -36968,6 +36907,7 @@ Output includes:
|
|
|
36968
36907
|
|
|
36969
36908
|
NOTE: This is an analytical tool based on public financial data.`,
|
|
36970
36909
|
inputSchema: FundingProfileSchema,
|
|
36910
|
+
outputSchema: FdicAnalysisOutputSchema,
|
|
36971
36911
|
annotations: {
|
|
36972
36912
|
readOnlyHint: true,
|
|
36973
36913
|
destructiveHint: false,
|
|
@@ -37054,7 +36994,7 @@ NOTE: This is an analytical tool based on public financial data.`,
|
|
|
37054
36994
|
}
|
|
37055
36995
|
|
|
37056
36996
|
// src/tools/securitiesPortfolio.ts
|
|
37057
|
-
var
|
|
36997
|
+
var import_zod15 = require("zod");
|
|
37058
36998
|
|
|
37059
36999
|
// src/tools/shared/securitiesPortfolio.ts
|
|
37060
37000
|
var SECURITIES_FIELDS = "CERT,REPDTE,ASSET,EQTOT,SC,SCRES";
|
|
@@ -37139,9 +37079,9 @@ function formatSecuritiesSummaryText(summary) {
|
|
|
37139
37079
|
}
|
|
37140
37080
|
return parts.join("\n");
|
|
37141
37081
|
}
|
|
37142
|
-
var SecuritiesPortfolioSchema =
|
|
37143
|
-
cert:
|
|
37144
|
-
repdte:
|
|
37082
|
+
var SecuritiesPortfolioSchema = import_zod15.z.object({
|
|
37083
|
+
cert: import_zod15.z.number().int().positive().describe("FDIC Certificate Number"),
|
|
37084
|
+
repdte: import_zod15.z.string().regex(/^\d{8}$/).optional().describe("Report date (YYYYMMDD). Defaults to most recent quarter.")
|
|
37145
37085
|
});
|
|
37146
37086
|
function registerSecuritiesPortfolioTools(server) {
|
|
37147
37087
|
server.registerTool(
|
|
@@ -37159,6 +37099,7 @@ Output includes:
|
|
|
37159
37099
|
|
|
37160
37100
|
NOTE: This is an analytical tool based on public financial data. AFS/HTM breakdown is not currently available from the FDIC API.`,
|
|
37161
37101
|
inputSchema: SecuritiesPortfolioSchema,
|
|
37102
|
+
outputSchema: FdicAnalysisOutputSchema,
|
|
37162
37103
|
annotations: {
|
|
37163
37104
|
readOnlyHint: true,
|
|
37164
37105
|
destructiveHint: false,
|
|
@@ -37245,7 +37186,7 @@ NOTE: This is an analytical tool based on public financial data. AFS/HTM breakdo
|
|
|
37245
37186
|
}
|
|
37246
37187
|
|
|
37247
37188
|
// src/tools/ubprAnalysis.ts
|
|
37248
|
-
var
|
|
37189
|
+
var import_zod16 = require("zod");
|
|
37249
37190
|
|
|
37250
37191
|
// src/tools/shared/ubprRatios.ts
|
|
37251
37192
|
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";
|
|
@@ -37356,9 +37297,9 @@ function formatUbprSummaryText(summary) {
|
|
|
37356
37297
|
parts.push("UBPR-equivalent calculations, not official FFIEC UBPR output.");
|
|
37357
37298
|
return parts.join("\n");
|
|
37358
37299
|
}
|
|
37359
|
-
var UbprAnalysisSchema =
|
|
37360
|
-
cert:
|
|
37361
|
-
repdte:
|
|
37300
|
+
var UbprAnalysisSchema = import_zod16.z.object({
|
|
37301
|
+
cert: import_zod16.z.number().int().positive().describe("FDIC Certificate Number"),
|
|
37302
|
+
repdte: import_zod16.z.string().length(8).optional().describe("Report date (YYYYMMDD). Defaults to most recent quarter.")
|
|
37362
37303
|
});
|
|
37363
37304
|
function registerUbprAnalysisTools(server) {
|
|
37364
37305
|
server.registerTool(
|
|
@@ -37377,6 +37318,7 @@ Output includes:
|
|
|
37377
37318
|
|
|
37378
37319
|
NOTE: This is an analytical tool based on public financial data.`,
|
|
37379
37320
|
inputSchema: UbprAnalysisSchema,
|
|
37321
|
+
outputSchema: FdicAnalysisOutputSchema,
|
|
37380
37322
|
annotations: {
|
|
37381
37323
|
readOnlyHint: true,
|
|
37382
37324
|
destructiveHint: false,
|
|
@@ -37477,7 +37419,7 @@ NOTE: This is an analytical tool based on public financial data.`,
|
|
|
37477
37419
|
}
|
|
37478
37420
|
|
|
37479
37421
|
// src/tools/marketShareAnalysis.ts
|
|
37480
|
-
var
|
|
37422
|
+
var import_zod17 = require("zod");
|
|
37481
37423
|
|
|
37482
37424
|
// src/tools/shared/marketShare.ts
|
|
37483
37425
|
function computeMarketShare(branches) {
|
|
@@ -37590,16 +37532,16 @@ function formatMarketShareText(summary) {
|
|
|
37590
37532
|
function getDefaultSodYear() {
|
|
37591
37533
|
return (/* @__PURE__ */ new Date()).getFullYear() - 1;
|
|
37592
37534
|
}
|
|
37593
|
-
var MarketShareInputSchema =
|
|
37594
|
-
msa:
|
|
37535
|
+
var MarketShareInputSchema = import_zod17.z.object({
|
|
37536
|
+
msa: import_zod17.z.number().int().positive().optional().describe(
|
|
37595
37537
|
"FDIC MSABR numeric code for the Metropolitan Statistical Area (e.g., 19100 for Dallas-Fort Worth-Arlington, 42660 for Seattle-Tacoma-Bellevue). Use fdic_search_sod with MSABR to look up codes."
|
|
37596
37538
|
),
|
|
37597
|
-
city:
|
|
37598
|
-
state:
|
|
37539
|
+
city: import_zod17.z.string().optional().describe('City name (e.g., "Austin"). Requires state.'),
|
|
37540
|
+
state: import_zod17.z.string().length(2).optional().describe(
|
|
37599
37541
|
"Two-letter state abbreviation (e.g., TX). Required when using city filter."
|
|
37600
37542
|
),
|
|
37601
|
-
year:
|
|
37602
|
-
cert:
|
|
37543
|
+
year: import_zod17.z.number().int().min(1994).optional().describe("SOD report year (1994-present). Defaults to most recent."),
|
|
37544
|
+
cert: import_zod17.z.number().int().positive().optional().describe("Highlight a specific institution in the results.")
|
|
37603
37545
|
});
|
|
37604
37546
|
function registerMarketShareAnalysisTools(server) {
|
|
37605
37547
|
server.registerTool(
|
|
@@ -37622,6 +37564,7 @@ Output includes:
|
|
|
37622
37564
|
|
|
37623
37565
|
Requires at least one of: msa (numeric MSABR code), or city + state.`,
|
|
37624
37566
|
inputSchema: MarketShareInputSchema,
|
|
37567
|
+
outputSchema: FdicAnalysisOutputSchema,
|
|
37625
37568
|
annotations: {
|
|
37626
37569
|
readOnlyHint: true,
|
|
37627
37570
|
destructiveHint: false,
|
|
@@ -37737,7 +37680,7 @@ Requires at least one of: msa (numeric MSABR code), or city + state.`,
|
|
|
37737
37680
|
}
|
|
37738
37681
|
|
|
37739
37682
|
// src/tools/franchiseFootprint.ts
|
|
37740
|
-
var
|
|
37683
|
+
var import_zod18 = require("zod");
|
|
37741
37684
|
var SOD_BRANCH_FIELDS = "CERT,NAMEFULL,DEPSUMBR,BRNUM,MSABR,STALPBR,YEAR";
|
|
37742
37685
|
var SOD_FETCH_LIMIT2 = 1e4;
|
|
37743
37686
|
var NON_MSA_LABEL = "Non-MSA / Rural";
|
|
@@ -37776,9 +37719,9 @@ function formatFranchiseFootprintText(summary) {
|
|
|
37776
37719
|
function getDefaultSodYear2() {
|
|
37777
37720
|
return (/* @__PURE__ */ new Date()).getFullYear() - 1;
|
|
37778
37721
|
}
|
|
37779
|
-
var FranchiseFootprintInputSchema =
|
|
37780
|
-
cert:
|
|
37781
|
-
year:
|
|
37722
|
+
var FranchiseFootprintInputSchema = import_zod18.z.object({
|
|
37723
|
+
cert: import_zod18.z.number().int().positive().describe("FDIC Certificate Number"),
|
|
37724
|
+
year: import_zod18.z.number().int().min(1994).optional().describe("SOD report year. Defaults to most recent.")
|
|
37782
37725
|
});
|
|
37783
37726
|
function registerFranchiseFootprintTools(server) {
|
|
37784
37727
|
server.registerTool(
|
|
@@ -37796,6 +37739,7 @@ Output includes:
|
|
|
37796
37739
|
|
|
37797
37740
|
Branches outside MSAs are grouped under "Non-MSA / Rural".`,
|
|
37798
37741
|
inputSchema: FranchiseFootprintInputSchema,
|
|
37742
|
+
outputSchema: FdicAnalysisOutputSchema,
|
|
37799
37743
|
annotations: {
|
|
37800
37744
|
readOnlyHint: true,
|
|
37801
37745
|
destructiveHint: false,
|
|
@@ -37916,7 +37860,7 @@ Branches outside MSAs are grouped under "Non-MSA / Rural".`,
|
|
|
37916
37860
|
}
|
|
37917
37861
|
|
|
37918
37862
|
// src/tools/holdingCompanyProfile.ts
|
|
37919
|
-
var
|
|
37863
|
+
var import_zod19 = require("zod");
|
|
37920
37864
|
|
|
37921
37865
|
// src/tools/shared/holdingCompany.ts
|
|
37922
37866
|
var INDEPENDENT_LABEL = "(Independent)";
|
|
@@ -38033,11 +37977,11 @@ function formatHoldingCompanyProfileText(result) {
|
|
|
38033
37977
|
}
|
|
38034
37978
|
return parts.join("\n");
|
|
38035
37979
|
}
|
|
38036
|
-
var HoldingCompanyProfileSchema =
|
|
38037
|
-
hc_name:
|
|
37980
|
+
var HoldingCompanyProfileSchema = import_zod19.z.object({
|
|
37981
|
+
hc_name: import_zod19.z.string().optional().describe(
|
|
38038
37982
|
'Holding company name (e.g., "JPMORGAN CHASE & CO"). Uses NAMEHCR field.'
|
|
38039
37983
|
),
|
|
38040
|
-
cert:
|
|
37984
|
+
cert: import_zod19.z.number().int().positive().optional().describe(
|
|
38041
37985
|
"CERT of any subsidiary \u2014 looks up its holding company, then profiles the entire HC."
|
|
38042
37986
|
)
|
|
38043
37987
|
});
|
|
@@ -38055,6 +37999,7 @@ Output includes:
|
|
|
38055
37999
|
|
|
38056
38000
|
NOTE: This is an analytical tool based on public financial data.`,
|
|
38057
38001
|
inputSchema: HoldingCompanyProfileSchema,
|
|
38002
|
+
outputSchema: FdicAnalysisOutputSchema,
|
|
38058
38003
|
annotations: {
|
|
38059
38004
|
readOnlyHint: true,
|
|
38060
38005
|
destructiveHint: false,
|
|
@@ -38225,7 +38170,7 @@ NOTE: This is an analytical tool based on public financial data.`,
|
|
|
38225
38170
|
}
|
|
38226
38171
|
|
|
38227
38172
|
// src/tools/regionalContext.ts
|
|
38228
|
-
var
|
|
38173
|
+
var import_zod20 = require("zod");
|
|
38229
38174
|
|
|
38230
38175
|
// src/services/fredClient.ts
|
|
38231
38176
|
var import_axios2 = __toESM(require("axios"));
|
|
@@ -38425,14 +38370,14 @@ function formatRegionalContextText(summary) {
|
|
|
38425
38370
|
parts.push("Note: Economic data from FRED (Federal Reserve Economic Data).");
|
|
38426
38371
|
return parts.join("\n");
|
|
38427
38372
|
}
|
|
38428
|
-
var RegionalContextSchema =
|
|
38429
|
-
cert:
|
|
38373
|
+
var RegionalContextSchema = import_zod20.z.object({
|
|
38374
|
+
cert: import_zod20.z.number().int().positive().optional().describe(
|
|
38430
38375
|
"FDIC Certificate Number \u2014 auto-detects state from institution record."
|
|
38431
38376
|
),
|
|
38432
|
-
state:
|
|
38377
|
+
state: import_zod20.z.string().length(2).optional().describe(
|
|
38433
38378
|
"Two-letter state abbreviation (e.g., TX). Alternative to cert-based lookup."
|
|
38434
38379
|
),
|
|
38435
|
-
repdte:
|
|
38380
|
+
repdte: import_zod20.z.string().regex(/^\d{8}$/).optional().describe(
|
|
38436
38381
|
"Reference report date (YYYYMMDD). FRED data fetched for 2 years before this date."
|
|
38437
38382
|
)
|
|
38438
38383
|
});
|
|
@@ -38451,6 +38396,7 @@ Output includes:
|
|
|
38451
38396
|
|
|
38452
38397
|
NOTE: Requires FRED_API_KEY environment variable for reliable data access. Degrades gracefully without it.`,
|
|
38453
38398
|
inputSchema: RegionalContextSchema,
|
|
38399
|
+
outputSchema: FdicAnalysisOutputSchema,
|
|
38454
38400
|
annotations: {
|
|
38455
38401
|
readOnlyHint: true,
|
|
38456
38402
|
destructiveHint: false,
|
|
@@ -38589,7 +38535,7 @@ NOTE: Requires FRED_API_KEY environment variable for reliable data access. Degra
|
|
|
38589
38535
|
}
|
|
38590
38536
|
|
|
38591
38537
|
// src/tools/chatgptRetrieval.ts
|
|
38592
|
-
var
|
|
38538
|
+
var import_zod21 = require("zod");
|
|
38593
38539
|
|
|
38594
38540
|
// src/tools/shared/chatgptUrls.ts
|
|
38595
38541
|
var FDIC_BANKFIND_BASE_URL = "https://banks.data.fdic.gov/bankfind-suite";
|
|
@@ -38609,11 +38555,11 @@ function getBranchCitationUrl() {
|
|
|
38609
38555
|
}
|
|
38610
38556
|
|
|
38611
38557
|
// src/tools/chatgptRetrieval.ts
|
|
38612
|
-
var SearchInputSchema =
|
|
38613
|
-
query:
|
|
38558
|
+
var SearchInputSchema = import_zod21.z.object({
|
|
38559
|
+
query: import_zod21.z.string().min(1).describe("Natural-language search query.")
|
|
38614
38560
|
});
|
|
38615
|
-
var FetchInputSchema =
|
|
38616
|
-
id:
|
|
38561
|
+
var FetchInputSchema = import_zod21.z.object({
|
|
38562
|
+
id: import_zod21.z.string().min(1).describe(
|
|
38617
38563
|
"Retrieval item id, such as institution:<CERT>, failure:<CERT>, branch:<UNINUM>, or schema:<endpoint>."
|
|
38618
38564
|
)
|
|
38619
38565
|
});
|
|
@@ -38960,13 +38906,39 @@ async function fetchById(id) {
|
|
|
38960
38906
|
}
|
|
38961
38907
|
throw new Error(`Unsupported fetch id kind: ${kind}.`);
|
|
38962
38908
|
}
|
|
38963
|
-
function
|
|
38909
|
+
async function runSearch(query) {
|
|
38910
|
+
const normalized = normalizeQuery(query);
|
|
38911
|
+
const shouldIncludeFailures = shouldSearchFailures(normalized);
|
|
38912
|
+
const shouldIncludeBranches = shouldSearchBranches(normalized);
|
|
38913
|
+
const shouldIncludeSchemas = shouldSearchSchemas(normalized);
|
|
38914
|
+
const [institutions, failures, branches] = await Promise.all([
|
|
38915
|
+
safeSearch(() => searchInstitutions(normalized)),
|
|
38916
|
+
shouldIncludeFailures ? safeSearch(() => searchFailures(normalized)) : Promise.resolve([]),
|
|
38917
|
+
shouldIncludeBranches ? safeSearch(() => searchBranches(normalized)) : Promise.resolve([])
|
|
38918
|
+
]);
|
|
38919
|
+
const fallbackFailures = failures.length === 0 && institutions.length === 0 ? await safeSearch(() => searchFailures(normalized)) : [];
|
|
38920
|
+
const fallbackBranches = branches.length === 0 && institutions.length === 0 ? await safeSearch(() => searchBranches(normalized)) : [];
|
|
38921
|
+
const schemas = shouldIncludeSchemas ? schemaSearchResults(normalized) : [];
|
|
38922
|
+
const results = dedupeResults([
|
|
38923
|
+
...institutions,
|
|
38924
|
+
...failures,
|
|
38925
|
+
...branches,
|
|
38926
|
+
...fallbackFailures,
|
|
38927
|
+
...fallbackBranches,
|
|
38928
|
+
...schemas
|
|
38929
|
+
]);
|
|
38930
|
+
return { results };
|
|
38931
|
+
}
|
|
38932
|
+
var SEARCH_DESCRIPTION = "Use this when the model needs citation-friendly FDIC BankFind search results for institutions, failed banks, branches, or schema documentation. Returns up to 8 results with id, title, and source URL.";
|
|
38933
|
+
var FETCH_DESCRIPTION = "Use this when the model needs the full citation text for a result returned by search. Pass the search result id (e.g. 'institution:3511', 'failure:1234', 'branch:<UNINUM>', 'schema:institutions').";
|
|
38934
|
+
function registerSearchTool(server, name) {
|
|
38964
38935
|
server.registerTool(
|
|
38965
|
-
|
|
38936
|
+
name,
|
|
38966
38937
|
{
|
|
38967
38938
|
title: "Search FDIC BankFind",
|
|
38968
|
-
description:
|
|
38939
|
+
description: SEARCH_DESCRIPTION,
|
|
38969
38940
|
inputSchema: SearchInputSchema,
|
|
38941
|
+
outputSchema: ChatGptSearchResultSchema,
|
|
38970
38942
|
annotations: {
|
|
38971
38943
|
readOnlyHint: true,
|
|
38972
38944
|
destructiveHint: false,
|
|
@@ -38975,37 +38947,22 @@ function registerChatGptRetrievalTools(server) {
|
|
|
38975
38947
|
}
|
|
38976
38948
|
},
|
|
38977
38949
|
async ({ query }) => {
|
|
38978
|
-
const
|
|
38979
|
-
const shouldIncludeFailures = shouldSearchFailures(normalized);
|
|
38980
|
-
const shouldIncludeBranches = shouldSearchBranches(normalized);
|
|
38981
|
-
const shouldIncludeSchemas = shouldSearchSchemas(normalized);
|
|
38982
|
-
const [institutions, failures, branches] = await Promise.all([
|
|
38983
|
-
safeSearch(() => searchInstitutions(normalized)),
|
|
38984
|
-
shouldIncludeFailures ? safeSearch(() => searchFailures(normalized)) : Promise.resolve([]),
|
|
38985
|
-
shouldIncludeBranches ? safeSearch(() => searchBranches(normalized)) : Promise.resolve([])
|
|
38986
|
-
]);
|
|
38987
|
-
const fallbackFailures = failures.length === 0 && institutions.length === 0 ? await safeSearch(() => searchFailures(normalized)) : [];
|
|
38988
|
-
const fallbackBranches = branches.length === 0 && institutions.length === 0 ? await safeSearch(() => searchBranches(normalized)) : [];
|
|
38989
|
-
const schemas = shouldIncludeSchemas ? schemaSearchResults(normalized) : [];
|
|
38990
|
-
const results = dedupeResults([
|
|
38991
|
-
...institutions,
|
|
38992
|
-
...failures,
|
|
38993
|
-
...branches,
|
|
38994
|
-
...fallbackFailures,
|
|
38995
|
-
...fallbackBranches,
|
|
38996
|
-
...schemas
|
|
38997
|
-
]);
|
|
38950
|
+
const payload = await runSearch(query);
|
|
38998
38951
|
return {
|
|
38999
|
-
content: [{ type: "text", text: jsonText(
|
|
38952
|
+
content: [{ type: "text", text: jsonText(payload) }],
|
|
38953
|
+
structuredContent: payload
|
|
39000
38954
|
};
|
|
39001
38955
|
}
|
|
39002
38956
|
);
|
|
38957
|
+
}
|
|
38958
|
+
function registerFetchTool(server, name) {
|
|
39003
38959
|
server.registerTool(
|
|
39004
|
-
|
|
38960
|
+
name,
|
|
39005
38961
|
{
|
|
39006
38962
|
title: "Fetch FDIC BankFind Result",
|
|
39007
|
-
description:
|
|
38963
|
+
description: FETCH_DESCRIPTION,
|
|
39008
38964
|
inputSchema: FetchInputSchema,
|
|
38965
|
+
outputSchema: ChatGptFetchResultSchema,
|
|
39009
38966
|
annotations: {
|
|
39010
38967
|
readOnlyHint: true,
|
|
39011
38968
|
destructiveHint: false,
|
|
@@ -39017,7 +38974,8 @@ function registerChatGptRetrievalTools(server) {
|
|
|
39017
38974
|
try {
|
|
39018
38975
|
const result = await fetchById(id);
|
|
39019
38976
|
return {
|
|
39020
|
-
content: [{ type: "text", text: jsonText(result) }]
|
|
38977
|
+
content: [{ type: "text", text: jsonText(result) }],
|
|
38978
|
+
structuredContent: result
|
|
39021
38979
|
};
|
|
39022
38980
|
} catch (err) {
|
|
39023
38981
|
return formatToolError(err);
|
|
@@ -39025,9 +38983,21 @@ function registerChatGptRetrievalTools(server) {
|
|
|
39025
38983
|
}
|
|
39026
38984
|
);
|
|
39027
38985
|
}
|
|
38986
|
+
function registerChatGptRetrievalTools(server, options = {}) {
|
|
38987
|
+
const includeCanonical = options.includeCanonicalNames ?? true;
|
|
38988
|
+
const includeAliases = options.includeNamespacedAliases ?? true;
|
|
38989
|
+
if (includeCanonical) {
|
|
38990
|
+
registerSearchTool(server, "search");
|
|
38991
|
+
registerFetchTool(server, "fetch");
|
|
38992
|
+
}
|
|
38993
|
+
if (includeAliases) {
|
|
38994
|
+
registerSearchTool(server, "fdic_search");
|
|
38995
|
+
registerFetchTool(server, "fdic_fetch");
|
|
38996
|
+
}
|
|
38997
|
+
}
|
|
39028
38998
|
|
|
39029
38999
|
// src/tools/chatgptBankDeepDive.ts
|
|
39030
|
-
var
|
|
39000
|
+
var import_zod22 = require("zod");
|
|
39031
39001
|
|
|
39032
39002
|
// src/resources/chatgptAppResources.ts
|
|
39033
39003
|
var BANK_DEEP_DIVE_WIDGET_URI = "ui://widget/fdic-bank-deep-dive-v1.html";
|
|
@@ -39288,9 +39258,9 @@ function registerChatGptAppResources(server) {
|
|
|
39288
39258
|
}
|
|
39289
39259
|
|
|
39290
39260
|
// src/tools/chatgptBankDeepDive.ts
|
|
39291
|
-
var BankDeepDiveInputSchema =
|
|
39292
|
-
cert:
|
|
39293
|
-
repdte:
|
|
39261
|
+
var BankDeepDiveInputSchema = import_zod22.z.object({
|
|
39262
|
+
cert: import_zod22.z.number().int().positive().describe("FDIC Certificate Number of the institution to render."),
|
|
39263
|
+
repdte: import_zod22.z.string().regex(/^\d{8}$/).optional().describe(
|
|
39294
39264
|
"Quarter-end report date in YYYYMMDD format. Defaults to the most recent likely published quarter."
|
|
39295
39265
|
)
|
|
39296
39266
|
});
|
|
@@ -39332,21 +39302,72 @@ function collectDashboardRiskSignals(financials) {
|
|
|
39332
39302
|
}
|
|
39333
39303
|
return signals;
|
|
39334
39304
|
}
|
|
39335
|
-
function
|
|
39336
|
-
|
|
39337
|
-
|
|
39338
|
-
|
|
39339
|
-
|
|
39340
|
-
|
|
39341
|
-
|
|
39342
|
-
|
|
39343
|
-
|
|
39344
|
-
|
|
39345
|
-
|
|
39346
|
-
|
|
39305
|
+
function formatDollarsInThousands(value) {
|
|
39306
|
+
if (value === void 0) {
|
|
39307
|
+
return "n/a";
|
|
39308
|
+
}
|
|
39309
|
+
if (Math.abs(value) >= 1e6) {
|
|
39310
|
+
return `$${(value / 1e6).toFixed(1)}B`;
|
|
39311
|
+
}
|
|
39312
|
+
if (Math.abs(value) >= 1e3) {
|
|
39313
|
+
return `$${(value / 1e3).toFixed(1)}M`;
|
|
39314
|
+
}
|
|
39315
|
+
return `$${value.toLocaleString()}k`;
|
|
39316
|
+
}
|
|
39317
|
+
function buildDashboardMarkdown(data) {
|
|
39318
|
+
const { institution: inst, assessment, metrics } = data;
|
|
39319
|
+
const status = inst.active ? "Active" : "Inactive or unknown";
|
|
39320
|
+
const lines = [];
|
|
39321
|
+
lines.push(`## FDIC Bank Deep Dive: ${inst.name}`);
|
|
39322
|
+
lines.push("");
|
|
39323
|
+
lines.push(
|
|
39324
|
+
`**CERT** ${inst.cert} \xB7 ${inst.city}, ${inst.state} \xB7 ${status} \xB7 **Report date** ${inst.report_date}`
|
|
39325
|
+
);
|
|
39326
|
+
lines.push("");
|
|
39327
|
+
lines.push(`> ${assessment.caveat}`);
|
|
39328
|
+
lines.push("");
|
|
39329
|
+
lines.push("### Headline metrics");
|
|
39330
|
+
lines.push("");
|
|
39331
|
+
lines.push("| Metric | Value |");
|
|
39332
|
+
lines.push("| --- | --- |");
|
|
39333
|
+
lines.push(`| Assets | ${formatDollarsInThousands(inst.asset_thousands)} |`);
|
|
39334
|
+
lines.push(
|
|
39335
|
+
`| Deposits | ${formatDollarsInThousands(inst.deposit_thousands)} |`
|
|
39336
|
+
);
|
|
39337
|
+
lines.push(`| Offices | ${inst.offices ?? "n/a"} |`);
|
|
39338
|
+
lines.push(`| Proxy band | ${assessment.proxy_band} |`);
|
|
39339
|
+
lines.push(`| ROA | ${metrics.roa ?? "n/a"} |`);
|
|
39340
|
+
lines.push(`| ROE | ${metrics.roe ?? "n/a"} |`);
|
|
39341
|
+
lines.push(`| Tier 1 leverage | ${metrics.tier1_leverage ?? "n/a"} |`);
|
|
39342
|
+
lines.push(`| Noncurrent loans | ${metrics.noncurrent_loans ?? "n/a"} |`);
|
|
39343
|
+
lines.push(`| Loan-to-deposit | ${metrics.loan_to_deposit ?? "n/a"} |`);
|
|
39344
|
+
lines.push(
|
|
39345
|
+
`| Net interest margin | ${metrics.net_interest_margin ?? "n/a"} |`
|
|
39346
|
+
);
|
|
39347
|
+
lines.push(`| Efficiency ratio | ${metrics.efficiency_ratio ?? "n/a"} |`);
|
|
39348
|
+
lines.push("");
|
|
39349
|
+
lines.push("### Risk signals");
|
|
39350
|
+
lines.push("");
|
|
39351
|
+
if (data.risk_signals.length === 0) {
|
|
39352
|
+
lines.push("_No risk signals returned for this dashboard._");
|
|
39353
|
+
} else {
|
|
39354
|
+
for (const signal of data.risk_signals) {
|
|
39355
|
+
lines.push(`- ${signal}`);
|
|
39356
|
+
}
|
|
39347
39357
|
}
|
|
39348
|
-
|
|
39349
|
-
|
|
39358
|
+
lines.push("");
|
|
39359
|
+
if (data.warnings.length > 0) {
|
|
39360
|
+
lines.push("### Warnings");
|
|
39361
|
+
lines.push("");
|
|
39362
|
+
for (const warning of data.warnings) {
|
|
39363
|
+
lines.push(`- ${warning}`);
|
|
39364
|
+
}
|
|
39365
|
+
lines.push("");
|
|
39366
|
+
}
|
|
39367
|
+
lines.push("### Sources");
|
|
39368
|
+
lines.push("");
|
|
39369
|
+
for (const source of data.sources) {
|
|
39370
|
+
lines.push(`- [${source.title}](${source.url})`);
|
|
39350
39371
|
}
|
|
39351
39372
|
return lines.join("\n");
|
|
39352
39373
|
}
|
|
@@ -39355,8 +39376,9 @@ function registerChatGptBankDeepDiveTool(server) {
|
|
|
39355
39376
|
"fdic_show_bank_deep_dive",
|
|
39356
39377
|
{
|
|
39357
39378
|
title: "Show Bank Deep Dive Dashboard",
|
|
39358
|
-
description: "Use this when the user wants a scannable
|
|
39379
|
+
description: "Use this when the user wants a scannable single-institution dashboard with identity, public financial metrics, risk signals, and source links. ChatGPT renders an interactive widget; Claude and other MCP clients render the same data as a Markdown table.",
|
|
39359
39380
|
inputSchema: BankDeepDiveInputSchema,
|
|
39381
|
+
outputSchema: FdicBankDeepDiveOutputSchema,
|
|
39360
39382
|
annotations: {
|
|
39361
39383
|
readOnlyHint: true,
|
|
39362
39384
|
destructiveHint: false,
|
|
@@ -39443,7 +39465,7 @@ function registerChatGptBankDeepDiveTool(server) {
|
|
|
39443
39465
|
{
|
|
39444
39466
|
type: "text",
|
|
39445
39467
|
text: truncateIfNeeded(
|
|
39446
|
-
|
|
39468
|
+
buildDashboardMarkdown(structuredContent),
|
|
39447
39469
|
CHARACTER_LIMIT
|
|
39448
39470
|
)
|
|
39449
39471
|
}
|
|
@@ -39536,36 +39558,218 @@ function registerSchemaResources(server) {
|
|
|
39536
39558
|
}
|
|
39537
39559
|
}
|
|
39538
39560
|
|
|
39561
|
+
// src/prompts/workflows.ts
|
|
39562
|
+
var import_zod23 = require("zod");
|
|
39563
|
+
var BankDeepDiveArgs = {
|
|
39564
|
+
bank: import_zod23.z.string().min(1).describe("Bank name or FDIC Certificate Number (CERT)."),
|
|
39565
|
+
repdte: import_zod23.z.string().regex(/^\d{8}$/).optional().describe(
|
|
39566
|
+
"Optional quarter-end report date in YYYYMMDD format (0331, 0630, 0930, or 1231)."
|
|
39567
|
+
)
|
|
39568
|
+
};
|
|
39569
|
+
var FailureForensicsArgs = {
|
|
39570
|
+
bank: import_zod23.z.string().min(1).describe("Failed bank name or FDIC Certificate Number (CERT)."),
|
|
39571
|
+
lookback_quarters: import_zod23.z.string().regex(/^\d+$/).optional().describe(
|
|
39572
|
+
"Number of pre-failure quarters to reconstruct (default 12 if omitted)."
|
|
39573
|
+
)
|
|
39574
|
+
};
|
|
39575
|
+
var PortfolioSurveillanceArgs = {
|
|
39576
|
+
scope: import_zod23.z.string().min(1).describe(
|
|
39577
|
+
"Universe to screen \u2014 e.g., 'state:NC', 'asset_min:1000000,asset_max:10000000', or a comma-separated CERT list ('certs:3511,29846,...')."
|
|
39578
|
+
),
|
|
39579
|
+
repdte: import_zod23.z.string().regex(/^\d{8}$/).optional().describe("Optional quarter-end report date in YYYYMMDD format.")
|
|
39580
|
+
};
|
|
39581
|
+
var ExaminerOverlayArgs = {
|
|
39582
|
+
bank: import_zod23.z.string().min(1).describe("Bank name or FDIC Certificate Number (CERT)."),
|
|
39583
|
+
qualitative_notes: import_zod23.z.string().optional().describe(
|
|
39584
|
+
"Optional qualitative analyst inputs (management quality, governance, exam findings) to overlay onto the public proxy assessment."
|
|
39585
|
+
)
|
|
39586
|
+
};
|
|
39587
|
+
function userText(text) {
|
|
39588
|
+
return {
|
|
39589
|
+
role: "user",
|
|
39590
|
+
content: { type: "text", text }
|
|
39591
|
+
};
|
|
39592
|
+
}
|
|
39593
|
+
function registerWorkflowPrompts(server) {
|
|
39594
|
+
server.registerPrompt(
|
|
39595
|
+
"bank_deep_dive",
|
|
39596
|
+
{
|
|
39597
|
+
title: "Comprehensive Bank Deep Dive",
|
|
39598
|
+
description: "Produce a comprehensive single-institution analysis report (health, financials, peer benchmarking, credit concentration, funding profile, securities, franchise footprint, regional context).",
|
|
39599
|
+
argsSchema: BankDeepDiveArgs
|
|
39600
|
+
},
|
|
39601
|
+
({ bank, repdte }) => ({
|
|
39602
|
+
messages: [
|
|
39603
|
+
userText(
|
|
39604
|
+
[
|
|
39605
|
+
`Run a comprehensive FDIC bank deep dive for "${bank}"${repdte ? ` as of ${repdte}` : ""}.`,
|
|
39606
|
+
"",
|
|
39607
|
+
"Steps:",
|
|
39608
|
+
"1. If a CERT was not given, call fdic_search_institutions to resolve the bank to a CERT.",
|
|
39609
|
+
"2. Call fdic_analyze_bank_health and fdic_ubpr_analysis for the resolved CERT.",
|
|
39610
|
+
"3. Call fdic_peer_group_analysis to benchmark the institution against peers.",
|
|
39611
|
+
"4. Call fdic_analyze_credit_concentration, fdic_analyze_funding_profile, and fdic_analyze_securities_portfolio.",
|
|
39612
|
+
"5. Call fdic_franchise_footprint for branch/deposit geography and fdic_regional_context for the home market.",
|
|
39613
|
+
"6. Synthesize into a narrative report with: identity & footprint, health summary, financial performance, peer position, credit concentration, funding profile, securities portfolio, regional context, and a public-data caveat.",
|
|
39614
|
+
"",
|
|
39615
|
+
"All output must be grounded in tool results. Treat any CAMELS-style scoring as a public off-site analytical proxy \u2014 not an official supervisory rating. Note unit conventions ($thousands) where relevant."
|
|
39616
|
+
].join("\n")
|
|
39617
|
+
)
|
|
39618
|
+
]
|
|
39619
|
+
})
|
|
39620
|
+
);
|
|
39621
|
+
server.registerPrompt(
|
|
39622
|
+
"failure_forensics",
|
|
39623
|
+
{
|
|
39624
|
+
title: "Failed Bank Forensics",
|
|
39625
|
+
description: "Reconstruct the pre-failure financial timeline of a failed FDIC institution and identify the earliest visible warning signals.",
|
|
39626
|
+
argsSchema: FailureForensicsArgs
|
|
39627
|
+
},
|
|
39628
|
+
({ bank, lookback_quarters }) => ({
|
|
39629
|
+
messages: [
|
|
39630
|
+
userText(
|
|
39631
|
+
[
|
|
39632
|
+
`Run a failure-forensics post-mortem for "${bank}" using the FDIC tools.`,
|
|
39633
|
+
"",
|
|
39634
|
+
"Steps:",
|
|
39635
|
+
"1. Resolve the bank to a CERT via fdic_search_institutions or fdic_search.",
|
|
39636
|
+
"2. Call fdic_get_institution_failure to confirm failure date, resolution type, and cost.",
|
|
39637
|
+
`3. Call fdic_search_financials with CERT and a sort_by:REPDTE DESC ordering to pull the prior ${lookback_quarters ?? "12"} quarters before the failure date.`,
|
|
39638
|
+
"4. Call fdic_analyze_credit_concentration, fdic_analyze_funding_profile, and fdic_analyze_securities_portfolio at the latest available pre-failure quarter.",
|
|
39639
|
+
"5. Call fdic_search_history for structural-change events (mergers, charter conversions, assistance) leading up to the failure.",
|
|
39640
|
+
"6. Synthesize a forensic timeline with: failure facts, the deterioration arc (capital, asset quality, earnings, liquidity), the earliest warning signals visible in public data, and likely drivers.",
|
|
39641
|
+
"",
|
|
39642
|
+
"Highlight inflection points (e.g. quarter ROA turned negative, when noncurrent loans exceeded reserves). Reference each finding to the report date that supports it."
|
|
39643
|
+
].join("\n")
|
|
39644
|
+
)
|
|
39645
|
+
]
|
|
39646
|
+
})
|
|
39647
|
+
);
|
|
39648
|
+
server.registerPrompt(
|
|
39649
|
+
"portfolio_surveillance",
|
|
39650
|
+
{
|
|
39651
|
+
title: "Portfolio Surveillance Watchlist",
|
|
39652
|
+
description: "Screen a universe of FDIC institutions and produce a decision-ready watchlist tiered Escalate / Monitor / No Immediate Concern.",
|
|
39653
|
+
argsSchema: PortfolioSurveillanceArgs
|
|
39654
|
+
},
|
|
39655
|
+
({ scope, repdte }) => ({
|
|
39656
|
+
messages: [
|
|
39657
|
+
userText(
|
|
39658
|
+
[
|
|
39659
|
+
`Run portfolio surveillance over scope: "${scope}"${repdte ? ` as of ${repdte}` : ""}.`,
|
|
39660
|
+
"",
|
|
39661
|
+
"Steps:",
|
|
39662
|
+
"1. Build the institution roster:",
|
|
39663
|
+
" - state:<XX> \u2192 fdic_search_institutions filters STALP:<XX> AND ACTIVE:1",
|
|
39664
|
+
" - asset_min:<n>,asset_max:<n> \u2192 ASSET range",
|
|
39665
|
+
" - certs:<csv> \u2192 use the comma-separated list directly",
|
|
39666
|
+
"2. Call fdic_detect_risk_signals across the roster.",
|
|
39667
|
+
"3. Call fdic_compare_peer_health to rank by composite proxy band.",
|
|
39668
|
+
"4. For the highest-risk subset, call fdic_analyze_bank_health for full proxy assessments.",
|
|
39669
|
+
"5. Tier institutions:",
|
|
39670
|
+
" - Escalate: critical risk signals or proxy band 'unsatisfactory'.",
|
|
39671
|
+
" - Monitor: warning signals or 'fair' band, especially deteriorating trends.",
|
|
39672
|
+
" - No Immediate Concern: no critical signals, satisfactory or strong band.",
|
|
39673
|
+
"6. Produce a watchlist table per tier (CERT, name, key signals, rationale).",
|
|
39674
|
+
"",
|
|
39675
|
+
"Treat all scoring as a public off-site analytical proxy. Surface data caveats explicitly."
|
|
39676
|
+
].join("\n")
|
|
39677
|
+
)
|
|
39678
|
+
]
|
|
39679
|
+
})
|
|
39680
|
+
);
|
|
39681
|
+
server.registerPrompt(
|
|
39682
|
+
"examiner_overlay",
|
|
39683
|
+
{
|
|
39684
|
+
title: "Examiner Overlay Assessment",
|
|
39685
|
+
description: "Layer qualitative analyst/examiner inputs on top of the public CAMELS proxy and produce a blended assessment with explicit provenance.",
|
|
39686
|
+
argsSchema: ExaminerOverlayArgs
|
|
39687
|
+
},
|
|
39688
|
+
({ bank, qualitative_notes }) => ({
|
|
39689
|
+
messages: [
|
|
39690
|
+
userText(
|
|
39691
|
+
[
|
|
39692
|
+
`Produce an examiner-overlay assessment for "${bank}".`,
|
|
39693
|
+
"",
|
|
39694
|
+
"Steps:",
|
|
39695
|
+
"1. Resolve to a CERT via fdic_search_institutions if needed.",
|
|
39696
|
+
"2. Call fdic_analyze_bank_health to get the public_camels_proxy_v1 baseline (capital, asset quality, earnings, liquidity, sensitivity).",
|
|
39697
|
+
"3. Call fdic_ubpr_analysis for performance ratios and fdic_analyze_funding_profile / fdic_analyze_credit_concentration for sub-component depth.",
|
|
39698
|
+
"4. Combine the public baseline with qualitative analyst inputs:",
|
|
39699
|
+
qualitative_notes ? ` Analyst notes: ${qualitative_notes}` : " (No qualitative inputs provided \u2014 produce the public baseline and clearly mark which factors would benefit from qualitative overlay.)",
|
|
39700
|
+
"5. Produce a blended assessment with two columns labeled exactly: 'Public-data finding' and 'Examiner overlay'. Never present overlay inputs as if they came from public data.",
|
|
39701
|
+
"6. Final composite must reconcile both columns and call out any divergence.",
|
|
39702
|
+
"",
|
|
39703
|
+
"Disclaimer: this overlay is not an official CAMELS rating or confidential supervisory conclusion."
|
|
39704
|
+
].join("\n")
|
|
39705
|
+
)
|
|
39706
|
+
]
|
|
39707
|
+
})
|
|
39708
|
+
);
|
|
39709
|
+
}
|
|
39710
|
+
|
|
39539
39711
|
// src/index.ts
|
|
39540
|
-
function
|
|
39712
|
+
function resolveProfile(raw) {
|
|
39713
|
+
const tokens = (raw ?? "all").split(",").map((token) => token.trim().toLowerCase()).filter((token) => token.length > 0);
|
|
39714
|
+
const has = (token) => tokens.includes(token);
|
|
39715
|
+
const all = has("all") || tokens.length === 0;
|
|
39716
|
+
const includeChatgpt = all || has("chatgpt");
|
|
39717
|
+
return {
|
|
39718
|
+
core: all || has("core"),
|
|
39719
|
+
analysis: all || has("analysis"),
|
|
39720
|
+
chatgptCanonical: all || includeChatgpt || has("chatgpt-canonical"),
|
|
39721
|
+
chatgptAliases: all || includeChatgpt || has("chatgpt-aliases"),
|
|
39722
|
+
chatgptDeepDive: all || includeChatgpt,
|
|
39723
|
+
prompts: all || has("prompts"),
|
|
39724
|
+
resources: all || has("resources")
|
|
39725
|
+
};
|
|
39726
|
+
}
|
|
39727
|
+
function createServer(options = {}) {
|
|
39541
39728
|
const server = new import_mcp.McpServer({
|
|
39542
39729
|
name: "fdic-mcp-server",
|
|
39543
39730
|
version: VERSION
|
|
39544
39731
|
});
|
|
39545
|
-
|
|
39546
|
-
|
|
39547
|
-
|
|
39548
|
-
|
|
39549
|
-
|
|
39550
|
-
|
|
39551
|
-
|
|
39552
|
-
|
|
39553
|
-
|
|
39554
|
-
|
|
39555
|
-
|
|
39556
|
-
|
|
39557
|
-
|
|
39558
|
-
|
|
39559
|
-
|
|
39560
|
-
|
|
39561
|
-
|
|
39562
|
-
|
|
39563
|
-
|
|
39564
|
-
|
|
39565
|
-
|
|
39566
|
-
|
|
39567
|
-
|
|
39568
|
-
|
|
39732
|
+
const profile = resolveProfile(options.profile ?? process.env.FDIC_MCP_PROFILE);
|
|
39733
|
+
if (profile.core) {
|
|
39734
|
+
registerInstitutionTools(server);
|
|
39735
|
+
registerFailureTools(server);
|
|
39736
|
+
registerLocationTools(server);
|
|
39737
|
+
registerHistoryTools(server);
|
|
39738
|
+
registerFinancialTools(server);
|
|
39739
|
+
registerSodTools(server);
|
|
39740
|
+
registerDemographicsTools(server);
|
|
39741
|
+
}
|
|
39742
|
+
if (profile.analysis) {
|
|
39743
|
+
registerAnalysisTools(server);
|
|
39744
|
+
registerPeerGroupTools(server);
|
|
39745
|
+
registerBankHealthTools(server);
|
|
39746
|
+
registerPeerHealthTools(server);
|
|
39747
|
+
registerRiskSignalTools(server);
|
|
39748
|
+
registerCreditConcentrationTools(server);
|
|
39749
|
+
registerFundingProfileTools(server);
|
|
39750
|
+
registerSecuritiesPortfolioTools(server);
|
|
39751
|
+
registerUbprAnalysisTools(server);
|
|
39752
|
+
registerMarketShareAnalysisTools(server);
|
|
39753
|
+
registerFranchiseFootprintTools(server);
|
|
39754
|
+
registerHoldingCompanyProfileTools(server);
|
|
39755
|
+
registerRegionalContextTools(server);
|
|
39756
|
+
}
|
|
39757
|
+
if (profile.chatgptCanonical || profile.chatgptAliases) {
|
|
39758
|
+
registerChatGptRetrievalTools(server, {
|
|
39759
|
+
includeCanonicalNames: profile.chatgptCanonical,
|
|
39760
|
+
includeNamespacedAliases: profile.chatgptAliases
|
|
39761
|
+
});
|
|
39762
|
+
}
|
|
39763
|
+
if (profile.chatgptDeepDive) {
|
|
39764
|
+
registerChatGptBankDeepDiveTool(server);
|
|
39765
|
+
registerChatGptAppResources(server);
|
|
39766
|
+
}
|
|
39767
|
+
if (profile.resources) {
|
|
39768
|
+
registerSchemaResources(server);
|
|
39769
|
+
}
|
|
39770
|
+
if (profile.prompts) {
|
|
39771
|
+
registerWorkflowPrompts(server);
|
|
39772
|
+
}
|
|
39569
39773
|
return server;
|
|
39570
39774
|
}
|
|
39571
39775
|
async function runStdio() {
|
|
@@ -39637,23 +39841,61 @@ function sendInvalidSessionResponse(res) {
|
|
|
39637
39841
|
}
|
|
39638
39842
|
function createApp(options = {}) {
|
|
39639
39843
|
const app = (0, import_express2.default)();
|
|
39640
|
-
const serverFactory = options.serverFactory ?? createServer;
|
|
39844
|
+
const serverFactory = options.serverFactory ?? (() => createServer());
|
|
39641
39845
|
const port = options.port ?? 3e3;
|
|
39642
39846
|
const allowedOrigins = options.allowedOrigins ?? parseAllowedOrigins(void 0, port);
|
|
39643
39847
|
const sessions = /* @__PURE__ */ new Map();
|
|
39644
39848
|
const chatSessions = /* @__PURE__ */ new Map();
|
|
39645
39849
|
const sessionIdleTimeoutMs = options.sessionIdleTimeoutMs ?? DEFAULT_SESSION_IDLE_TIMEOUT_MS;
|
|
39646
39850
|
const sessionSweepIntervalMs = options.sessionSweepIntervalMs ?? DEFAULT_SESSION_SWEEP_INTERVAL_MS;
|
|
39851
|
+
const stateless = options.stateless ?? process.env.FDIC_MCP_STATELESS_HTTP === "true";
|
|
39647
39852
|
app.use(import_express2.default.json());
|
|
39648
|
-
|
|
39649
|
-
|
|
39650
|
-
|
|
39651
|
-
|
|
39652
|
-
|
|
39853
|
+
if (!stateless) {
|
|
39854
|
+
const sessionSweepTimer = setInterval(() => {
|
|
39855
|
+
void sweepIdleSessions(sessions, sessionIdleTimeoutMs, Date.now());
|
|
39856
|
+
sweepIdleChatSessions(chatSessions, sessionIdleTimeoutMs, Date.now());
|
|
39857
|
+
}, sessionSweepIntervalMs);
|
|
39858
|
+
sessionSweepTimer.unref?.();
|
|
39859
|
+
}
|
|
39653
39860
|
app.get("/health", (_req, res) => {
|
|
39654
39861
|
res.json({ status: "ok", server: "fdic-mcp-server", version: VERSION });
|
|
39655
39862
|
});
|
|
39656
39863
|
app.all("/mcp", async (req, res) => {
|
|
39864
|
+
if (stateless) {
|
|
39865
|
+
let server;
|
|
39866
|
+
let transport;
|
|
39867
|
+
try {
|
|
39868
|
+
server = serverFactory();
|
|
39869
|
+
transport = new import_streamableHttp.StreamableHTTPServerTransport({
|
|
39870
|
+
sessionIdGenerator: void 0,
|
|
39871
|
+
enableJsonResponse: true,
|
|
39872
|
+
enableDnsRebindingProtection: true,
|
|
39873
|
+
allowedOrigins
|
|
39874
|
+
});
|
|
39875
|
+
res.on("close", () => {
|
|
39876
|
+
void transport?.close().catch(() => {
|
|
39877
|
+
});
|
|
39878
|
+
void server?.close().catch(() => {
|
|
39879
|
+
});
|
|
39880
|
+
});
|
|
39881
|
+
await server.connect(transport);
|
|
39882
|
+
await transport.handleRequest(req, res, req.body);
|
|
39883
|
+
} catch (error) {
|
|
39884
|
+
console.error("MCP request error:", error);
|
|
39885
|
+
if (!res.headersSent) {
|
|
39886
|
+
res.status(500).json({
|
|
39887
|
+
jsonrpc: "2.0",
|
|
39888
|
+
error: { code: -32603, message: "Internal server error" },
|
|
39889
|
+
id: null
|
|
39890
|
+
});
|
|
39891
|
+
}
|
|
39892
|
+
await transport?.close().catch(() => {
|
|
39893
|
+
});
|
|
39894
|
+
await server?.close().catch(() => {
|
|
39895
|
+
});
|
|
39896
|
+
}
|
|
39897
|
+
return;
|
|
39898
|
+
}
|
|
39657
39899
|
const sessionIdHeader = req.headers["mcp-session-id"];
|
|
39658
39900
|
const sessionId = typeof sessionIdHeader === "string" ? sessionIdHeader : void 0;
|
|
39659
39901
|
try {
|
|
@@ -39762,5 +40004,6 @@ async function main() {
|
|
|
39762
40004
|
main,
|
|
39763
40005
|
parseAllowedOrigins,
|
|
39764
40006
|
parseHttpHost,
|
|
39765
|
-
parseHttpPort
|
|
40007
|
+
parseHttpPort,
|
|
40008
|
+
resolveProfile
|
|
39766
40009
|
});
|