fdic-mcp-server 1.2.3 → 1.2.5
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 +35 -21
- package/dist/server.js +35 -21
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -32,7 +32,7 @@ var import_types = require("@modelcontextprotocol/sdk/types.js");
|
|
|
32
32
|
var import_express = __toESM(require("express"));
|
|
33
33
|
|
|
34
34
|
// src/constants.ts
|
|
35
|
-
var VERSION = true ? "1.2.
|
|
35
|
+
var VERSION = true ? "1.2.5" : process.env.npm_package_version ?? "0.0.0-dev";
|
|
36
36
|
var FDIC_API_BASE_URL = "https://banks.data.fdic.gov/api";
|
|
37
37
|
var CHARACTER_LIMIT = 5e4;
|
|
38
38
|
var DEFAULT_FDIC_MAX_RESPONSE_BYTES = 5 * 1024 * 1024;
|
|
@@ -32802,7 +32802,9 @@ function buildAnalysisOutput(params) {
|
|
|
32802
32802
|
sort_by: params.sortBy,
|
|
32803
32803
|
sort_order: params.sortOrder,
|
|
32804
32804
|
warnings: params.warnings,
|
|
32805
|
-
insights: buildTopLevelInsights(
|
|
32805
|
+
insights: buildTopLevelInsights(
|
|
32806
|
+
params.insightComparisons ?? params.comparisons
|
|
32807
|
+
),
|
|
32806
32808
|
...buildPaginationInfo(params.analyzedCount, offset, count),
|
|
32807
32809
|
comparisons: params.comparisons
|
|
32808
32810
|
};
|
|
@@ -33093,7 +33095,7 @@ Returns concise comparison text plus structured deltas, derived metrics, and ins
|
|
|
33093
33095
|
server.server,
|
|
33094
33096
|
progressToken,
|
|
33095
33097
|
0.3,
|
|
33096
|
-
"Fetching financial time series"
|
|
33098
|
+
include_demographics ? "Fetching financial and demographic time series" : "Fetching financial time series"
|
|
33097
33099
|
);
|
|
33098
33100
|
const [financialSeriesResult, demographicsSeriesResult] = await Promise.all([
|
|
33099
33101
|
fetchSeriesRecords(
|
|
@@ -33120,14 +33122,6 @@ Returns concise comparison text plus structured deltas, derived metrics, and ins
|
|
|
33120
33122
|
...financialSeriesResult.warnings,
|
|
33121
33123
|
...demographicsSeriesResult.warnings
|
|
33122
33124
|
);
|
|
33123
|
-
if (include_demographics) {
|
|
33124
|
-
await sendProgressNotification(
|
|
33125
|
-
server.server,
|
|
33126
|
-
progressToken,
|
|
33127
|
-
0.7,
|
|
33128
|
-
"Fetching demographics time series"
|
|
33129
|
-
);
|
|
33130
|
-
}
|
|
33131
33125
|
await sendProgressNotification(
|
|
33132
33126
|
server.server,
|
|
33133
33127
|
progressToken,
|
|
@@ -33153,7 +33147,7 @@ Returns concise comparison text plus structured deltas, derived metrics, and ins
|
|
|
33153
33147
|
server.server,
|
|
33154
33148
|
progressToken,
|
|
33155
33149
|
0.3,
|
|
33156
|
-
"Fetching financial snapshots"
|
|
33150
|
+
include_demographics ? "Fetching financial and demographic snapshots" : "Fetching financial snapshots"
|
|
33157
33151
|
);
|
|
33158
33152
|
const [financialSnapshotsResult, demographicSnapshotsResult] = await Promise.all([
|
|
33159
33153
|
fetchBatchedRecordsForDates(
|
|
@@ -33178,14 +33172,6 @@ Returns concise comparison text plus structured deltas, derived metrics, and ins
|
|
|
33178
33172
|
...financialSnapshotsResult.warnings,
|
|
33179
33173
|
...demographicSnapshotsResult.warnings
|
|
33180
33174
|
);
|
|
33181
|
-
if (include_demographics) {
|
|
33182
|
-
await sendProgressNotification(
|
|
33183
|
-
server.server,
|
|
33184
|
-
progressToken,
|
|
33185
|
-
0.7,
|
|
33186
|
-
"Fetching demographic snapshots"
|
|
33187
|
-
);
|
|
33188
|
-
}
|
|
33189
33175
|
await sendProgressNotification(
|
|
33190
33176
|
server.server,
|
|
33191
33177
|
progressToken,
|
|
@@ -33230,6 +33216,7 @@ Returns concise comparison text plus structured deltas, derived metrics, and ins
|
|
|
33230
33216
|
sortOrder: sort_order,
|
|
33231
33217
|
warnings,
|
|
33232
33218
|
comparisons: ranked,
|
|
33219
|
+
insightComparisons: sortedComparisons,
|
|
33233
33220
|
limitCount: ranked.length
|
|
33234
33221
|
});
|
|
33235
33222
|
const text = truncateIfNeeded(
|
|
@@ -33983,6 +33970,8 @@ function parseAllowedOrigins(rawOrigins, port) {
|
|
|
33983
33970
|
`https://127.0.0.1:${port}`
|
|
33984
33971
|
];
|
|
33985
33972
|
}
|
|
33973
|
+
var DEFAULT_SESSION_IDLE_TIMEOUT_MS = 30 * 60 * 1e3;
|
|
33974
|
+
var DEFAULT_SESSION_SWEEP_INTERVAL_MS = 5 * 60 * 1e3;
|
|
33986
33975
|
async function closeSession(sessions, sessionId) {
|
|
33987
33976
|
const session = sessions.get(sessionId);
|
|
33988
33977
|
if (!session) {
|
|
@@ -33994,6 +33983,20 @@ async function closeSession(sessions, sessionId) {
|
|
|
33994
33983
|
await session.transport.close().catch(() => {
|
|
33995
33984
|
});
|
|
33996
33985
|
}
|
|
33986
|
+
function touchSession(session, now) {
|
|
33987
|
+
session.lastActivityAt = now;
|
|
33988
|
+
}
|
|
33989
|
+
async function sweepIdleSessions(sessions, idleTimeoutMs, now) {
|
|
33990
|
+
const expiredSessionIds = [];
|
|
33991
|
+
for (const [sessionId, session] of sessions.entries()) {
|
|
33992
|
+
if (now - session.lastActivityAt >= idleTimeoutMs) {
|
|
33993
|
+
expiredSessionIds.push(sessionId);
|
|
33994
|
+
}
|
|
33995
|
+
}
|
|
33996
|
+
await Promise.all(
|
|
33997
|
+
expiredSessionIds.map((sessionId) => closeSession(sessions, sessionId))
|
|
33998
|
+
);
|
|
33999
|
+
}
|
|
33997
34000
|
function sendInvalidSessionResponse(res) {
|
|
33998
34001
|
res.status(400).json({
|
|
33999
34002
|
jsonrpc: "2.0",
|
|
@@ -34009,7 +34012,13 @@ function createApp(options = {}) {
|
|
|
34009
34012
|
const port = options.port ?? 3e3;
|
|
34010
34013
|
const allowedOrigins = options.allowedOrigins ?? parseAllowedOrigins(void 0, port);
|
|
34011
34014
|
const sessions = /* @__PURE__ */ new Map();
|
|
34015
|
+
const sessionIdleTimeoutMs = options.sessionIdleTimeoutMs ?? DEFAULT_SESSION_IDLE_TIMEOUT_MS;
|
|
34016
|
+
const sessionSweepIntervalMs = options.sessionSweepIntervalMs ?? DEFAULT_SESSION_SWEEP_INTERVAL_MS;
|
|
34012
34017
|
app.use(import_express.default.json());
|
|
34018
|
+
const sessionSweepTimer = setInterval(() => {
|
|
34019
|
+
void sweepIdleSessions(sessions, sessionIdleTimeoutMs, Date.now());
|
|
34020
|
+
}, sessionSweepIntervalMs);
|
|
34021
|
+
sessionSweepTimer.unref?.();
|
|
34013
34022
|
app.get("/health", (_req, res) => {
|
|
34014
34023
|
res.json({ status: "ok", server: "fdic-mcp-server", version: VERSION });
|
|
34015
34024
|
});
|
|
@@ -34030,6 +34039,7 @@ function createApp(options = {}) {
|
|
|
34030
34039
|
});
|
|
34031
34040
|
return;
|
|
34032
34041
|
}
|
|
34042
|
+
touchSession(session, Date.now());
|
|
34033
34043
|
await session.transport.handleRequest(req, res, req.body);
|
|
34034
34044
|
if (req.method === "DELETE") {
|
|
34035
34045
|
await closeSession(sessions, sessionId);
|
|
@@ -34047,7 +34057,11 @@ function createApp(options = {}) {
|
|
|
34047
34057
|
enableDnsRebindingProtection: true,
|
|
34048
34058
|
allowedOrigins,
|
|
34049
34059
|
onsessioninitialized: (newSessionId) => {
|
|
34050
|
-
sessions.set(newSessionId, {
|
|
34060
|
+
sessions.set(newSessionId, {
|
|
34061
|
+
server,
|
|
34062
|
+
transport,
|
|
34063
|
+
lastActivityAt: Date.now()
|
|
34064
|
+
});
|
|
34051
34065
|
}
|
|
34052
34066
|
});
|
|
34053
34067
|
transport.onclose = () => {
|
package/dist/server.js
CHANGED
|
@@ -46,7 +46,7 @@ var import_types = require("@modelcontextprotocol/sdk/types.js");
|
|
|
46
46
|
var import_express = __toESM(require("express"));
|
|
47
47
|
|
|
48
48
|
// src/constants.ts
|
|
49
|
-
var VERSION = true ? "1.2.
|
|
49
|
+
var VERSION = true ? "1.2.5" : process.env.npm_package_version ?? "0.0.0-dev";
|
|
50
50
|
var FDIC_API_BASE_URL = "https://banks.data.fdic.gov/api";
|
|
51
51
|
var CHARACTER_LIMIT = 5e4;
|
|
52
52
|
var DEFAULT_FDIC_MAX_RESPONSE_BYTES = 5 * 1024 * 1024;
|
|
@@ -32816,7 +32816,9 @@ function buildAnalysisOutput(params) {
|
|
|
32816
32816
|
sort_by: params.sortBy,
|
|
32817
32817
|
sort_order: params.sortOrder,
|
|
32818
32818
|
warnings: params.warnings,
|
|
32819
|
-
insights: buildTopLevelInsights(
|
|
32819
|
+
insights: buildTopLevelInsights(
|
|
32820
|
+
params.insightComparisons ?? params.comparisons
|
|
32821
|
+
),
|
|
32820
32822
|
...buildPaginationInfo(params.analyzedCount, offset, count),
|
|
32821
32823
|
comparisons: params.comparisons
|
|
32822
32824
|
};
|
|
@@ -33107,7 +33109,7 @@ Returns concise comparison text plus structured deltas, derived metrics, and ins
|
|
|
33107
33109
|
server.server,
|
|
33108
33110
|
progressToken,
|
|
33109
33111
|
0.3,
|
|
33110
|
-
"Fetching financial time series"
|
|
33112
|
+
include_demographics ? "Fetching financial and demographic time series" : "Fetching financial time series"
|
|
33111
33113
|
);
|
|
33112
33114
|
const [financialSeriesResult, demographicsSeriesResult] = await Promise.all([
|
|
33113
33115
|
fetchSeriesRecords(
|
|
@@ -33134,14 +33136,6 @@ Returns concise comparison text plus structured deltas, derived metrics, and ins
|
|
|
33134
33136
|
...financialSeriesResult.warnings,
|
|
33135
33137
|
...demographicsSeriesResult.warnings
|
|
33136
33138
|
);
|
|
33137
|
-
if (include_demographics) {
|
|
33138
|
-
await sendProgressNotification(
|
|
33139
|
-
server.server,
|
|
33140
|
-
progressToken,
|
|
33141
|
-
0.7,
|
|
33142
|
-
"Fetching demographics time series"
|
|
33143
|
-
);
|
|
33144
|
-
}
|
|
33145
33139
|
await sendProgressNotification(
|
|
33146
33140
|
server.server,
|
|
33147
33141
|
progressToken,
|
|
@@ -33167,7 +33161,7 @@ Returns concise comparison text plus structured deltas, derived metrics, and ins
|
|
|
33167
33161
|
server.server,
|
|
33168
33162
|
progressToken,
|
|
33169
33163
|
0.3,
|
|
33170
|
-
"Fetching financial snapshots"
|
|
33164
|
+
include_demographics ? "Fetching financial and demographic snapshots" : "Fetching financial snapshots"
|
|
33171
33165
|
);
|
|
33172
33166
|
const [financialSnapshotsResult, demographicSnapshotsResult] = await Promise.all([
|
|
33173
33167
|
fetchBatchedRecordsForDates(
|
|
@@ -33192,14 +33186,6 @@ Returns concise comparison text plus structured deltas, derived metrics, and ins
|
|
|
33192
33186
|
...financialSnapshotsResult.warnings,
|
|
33193
33187
|
...demographicSnapshotsResult.warnings
|
|
33194
33188
|
);
|
|
33195
|
-
if (include_demographics) {
|
|
33196
|
-
await sendProgressNotification(
|
|
33197
|
-
server.server,
|
|
33198
|
-
progressToken,
|
|
33199
|
-
0.7,
|
|
33200
|
-
"Fetching demographic snapshots"
|
|
33201
|
-
);
|
|
33202
|
-
}
|
|
33203
33189
|
await sendProgressNotification(
|
|
33204
33190
|
server.server,
|
|
33205
33191
|
progressToken,
|
|
@@ -33244,6 +33230,7 @@ Returns concise comparison text plus structured deltas, derived metrics, and ins
|
|
|
33244
33230
|
sortOrder: sort_order,
|
|
33245
33231
|
warnings,
|
|
33246
33232
|
comparisons: ranked,
|
|
33233
|
+
insightComparisons: sortedComparisons,
|
|
33247
33234
|
limitCount: ranked.length
|
|
33248
33235
|
});
|
|
33249
33236
|
const text = truncateIfNeeded(
|
|
@@ -33997,6 +33984,8 @@ function parseAllowedOrigins(rawOrigins, port) {
|
|
|
33997
33984
|
`https://127.0.0.1:${port}`
|
|
33998
33985
|
];
|
|
33999
33986
|
}
|
|
33987
|
+
var DEFAULT_SESSION_IDLE_TIMEOUT_MS = 30 * 60 * 1e3;
|
|
33988
|
+
var DEFAULT_SESSION_SWEEP_INTERVAL_MS = 5 * 60 * 1e3;
|
|
34000
33989
|
async function closeSession(sessions, sessionId) {
|
|
34001
33990
|
const session = sessions.get(sessionId);
|
|
34002
33991
|
if (!session) {
|
|
@@ -34008,6 +33997,20 @@ async function closeSession(sessions, sessionId) {
|
|
|
34008
33997
|
await session.transport.close().catch(() => {
|
|
34009
33998
|
});
|
|
34010
33999
|
}
|
|
34000
|
+
function touchSession(session, now) {
|
|
34001
|
+
session.lastActivityAt = now;
|
|
34002
|
+
}
|
|
34003
|
+
async function sweepIdleSessions(sessions, idleTimeoutMs, now) {
|
|
34004
|
+
const expiredSessionIds = [];
|
|
34005
|
+
for (const [sessionId, session] of sessions.entries()) {
|
|
34006
|
+
if (now - session.lastActivityAt >= idleTimeoutMs) {
|
|
34007
|
+
expiredSessionIds.push(sessionId);
|
|
34008
|
+
}
|
|
34009
|
+
}
|
|
34010
|
+
await Promise.all(
|
|
34011
|
+
expiredSessionIds.map((sessionId) => closeSession(sessions, sessionId))
|
|
34012
|
+
);
|
|
34013
|
+
}
|
|
34011
34014
|
function sendInvalidSessionResponse(res) {
|
|
34012
34015
|
res.status(400).json({
|
|
34013
34016
|
jsonrpc: "2.0",
|
|
@@ -34023,7 +34026,13 @@ function createApp(options = {}) {
|
|
|
34023
34026
|
const port = options.port ?? 3e3;
|
|
34024
34027
|
const allowedOrigins = options.allowedOrigins ?? parseAllowedOrigins(void 0, port);
|
|
34025
34028
|
const sessions = /* @__PURE__ */ new Map();
|
|
34029
|
+
const sessionIdleTimeoutMs = options.sessionIdleTimeoutMs ?? DEFAULT_SESSION_IDLE_TIMEOUT_MS;
|
|
34030
|
+
const sessionSweepIntervalMs = options.sessionSweepIntervalMs ?? DEFAULT_SESSION_SWEEP_INTERVAL_MS;
|
|
34026
34031
|
app.use(import_express.default.json());
|
|
34032
|
+
const sessionSweepTimer = setInterval(() => {
|
|
34033
|
+
void sweepIdleSessions(sessions, sessionIdleTimeoutMs, Date.now());
|
|
34034
|
+
}, sessionSweepIntervalMs);
|
|
34035
|
+
sessionSweepTimer.unref?.();
|
|
34027
34036
|
app.get("/health", (_req, res) => {
|
|
34028
34037
|
res.json({ status: "ok", server: "fdic-mcp-server", version: VERSION });
|
|
34029
34038
|
});
|
|
@@ -34044,6 +34053,7 @@ function createApp(options = {}) {
|
|
|
34044
34053
|
});
|
|
34045
34054
|
return;
|
|
34046
34055
|
}
|
|
34056
|
+
touchSession(session, Date.now());
|
|
34047
34057
|
await session.transport.handleRequest(req, res, req.body);
|
|
34048
34058
|
if (req.method === "DELETE") {
|
|
34049
34059
|
await closeSession(sessions, sessionId);
|
|
@@ -34061,7 +34071,11 @@ function createApp(options = {}) {
|
|
|
34061
34071
|
enableDnsRebindingProtection: true,
|
|
34062
34072
|
allowedOrigins,
|
|
34063
34073
|
onsessioninitialized: (newSessionId) => {
|
|
34064
|
-
sessions.set(newSessionId, {
|
|
34074
|
+
sessions.set(newSessionId, {
|
|
34075
|
+
server,
|
|
34076
|
+
transport,
|
|
34077
|
+
lastActivityAt: Date.now()
|
|
34078
|
+
});
|
|
34065
34079
|
}
|
|
34066
34080
|
});
|
|
34067
34081
|
transport.onclose = () => {
|