@fre4x/fred 1.0.43 → 1.0.46

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.
Files changed (2) hide show
  1. package/dist/index.js +112 -12
  2. package/package.json +3 -2
package/dist/index.js CHANGED
@@ -18436,6 +18436,30 @@ var require_follow_redirects = __commonJS({
18436
18436
  });
18437
18437
 
18438
18438
  // ../packages/shared/dist/errors.js
18439
+ function createApiError(message, statusCode) {
18440
+ let hint = "Check your network connection and retry.";
18441
+ if (statusCode === 429) {
18442
+ hint = "Rate limit exceeded. Suggestion: Wait for 60 seconds (Exponential Backoff) before retrying or reduce concurrent calls.";
18443
+ } else if (statusCode === 401 || statusCode === 403) {
18444
+ hint = "Authentication failed. Suggestion: Verify your API key or token in the environment configuration.";
18445
+ } else if (statusCode && statusCode >= 500) {
18446
+ hint = "Upstream service is having issues. Suggestion: This is a temporary external error. Try again in a few minutes.";
18447
+ } else if (statusCode === 404) {
18448
+ hint = "The requested resource was not found. Suggestion: Check if the ID or Ticker is correct, or search for it first.";
18449
+ }
18450
+ const detail = statusCode ? ` (HTTP ${statusCode})` : "";
18451
+ return {
18452
+ isError: true,
18453
+ content: [
18454
+ {
18455
+ type: "text",
18456
+ text: `API Error${detail}: ${message}
18457
+
18458
+ **Next Action**: ${hint}`
18459
+ }
18460
+ ]
18461
+ };
18462
+ }
18439
18463
  function createNotFoundError(resource) {
18440
18464
  return {
18441
18465
  isError: true,
@@ -45951,6 +45975,7 @@ var MOCK_FIXTURES = {
45951
45975
  ]
45952
45976
  },
45953
45977
  getSeriesInfo: {
45978
+ series_id: "GDP",
45954
45979
  realtime_start: "2023-01-01",
45955
45980
  realtime_end: "2023-01-01",
45956
45981
  seriess: [
@@ -45974,6 +45999,7 @@ var MOCK_FIXTURES = {
45974
45999
  ]
45975
46000
  },
45976
46001
  getSeriesObservations: {
46002
+ series_id: "GDP",
45977
46003
  realtime_start: "2023-01-01",
45978
46004
  realtime_end: "2023-01-01",
45979
46005
  observation_start: "1947-01-01",
@@ -46002,6 +46028,7 @@ var MOCK_FIXTURES = {
46002
46028
  ]
46003
46029
  },
46004
46030
  getCategorySeries: {
46031
+ category_id: 125,
46005
46032
  realtime_start: "2023-01-01",
46006
46033
  realtime_end: "2023-01-01",
46007
46034
  order_by: "popularity",
@@ -46048,6 +46075,7 @@ var MOCK_FIXTURES = {
46048
46075
  ]
46049
46076
  },
46050
46077
  getReleaseSeries: {
46078
+ release_id: 53,
46051
46079
  realtime_start: "2023-01-01",
46052
46080
  realtime_end: "2023-01-01",
46053
46081
  order_by: "series_id",
@@ -46093,6 +46121,7 @@ var MOCK_FIXTURES = {
46093
46121
  ]
46094
46122
  },
46095
46123
  getSource: {
46124
+ source_id: 1,
46096
46125
  realtime_start: "2023-01-01",
46097
46126
  realtime_end: "2023-01-01",
46098
46127
  sources: [
@@ -46119,6 +46148,46 @@ function getClient() {
46119
46148
  }
46120
46149
  return clientInstance;
46121
46150
  }
46151
+ function extractErrorMessage(err) {
46152
+ if (typeof err !== "object" || err === null) {
46153
+ return String(err);
46154
+ }
46155
+ const error48 = err;
46156
+ const responseData = error48.response?.data;
46157
+ if (typeof responseData === "string" && responseData.trim()) {
46158
+ return responseData.trim();
46159
+ }
46160
+ if (responseData && typeof responseData === "object") {
46161
+ const data = responseData;
46162
+ const nestedMessage = data.error_message ?? data.message ?? data.error ?? data.detail;
46163
+ if (nestedMessage !== void 0 && nestedMessage !== null) {
46164
+ return String(nestedMessage);
46165
+ }
46166
+ }
46167
+ if (error48.message !== void 0 && error48.message !== null) {
46168
+ return String(error48.message);
46169
+ }
46170
+ return "Request failed.";
46171
+ }
46172
+ function handleFredError(err) {
46173
+ if (typeof err === "object" && err !== null) {
46174
+ const error48 = err;
46175
+ const status = Number(
46176
+ error48.response?.status ?? error48.status ?? error48.statusCode ?? 0
46177
+ );
46178
+ const message = extractErrorMessage(err);
46179
+ if (status === 404) {
46180
+ return createNotFoundError(message);
46181
+ }
46182
+ if (status === 429) {
46183
+ return createApiError(`${message} Please try again later.`, 429);
46184
+ }
46185
+ if (status === 401 || status === 403 || status >= 500) {
46186
+ return createApiError(message, status);
46187
+ }
46188
+ }
46189
+ return createInternalError(err);
46190
+ }
46122
46191
  function formatSeriesList(seriess, total, offset) {
46123
46192
  if (!seriess || seriess.length === 0) return "No series found.";
46124
46193
  const rows = seriess.map(
@@ -46203,7 +46272,7 @@ server.registerTool(
46203
46272
  const text = formatSeriesList(res.seriess, res.count, offset);
46204
46273
  return { content: [{ type: "text", text: truncateToLimit(text) }] };
46205
46274
  } catch (err) {
46206
- return createInternalError(err);
46275
+ return handleFredError(err);
46207
46276
  }
46208
46277
  }
46209
46278
  );
@@ -46225,6 +46294,11 @@ server.registerTool(
46225
46294
  try {
46226
46295
  if (IS_MOCK) {
46227
46296
  const res2 = MOCK_FIXTURES.getSeriesInfo;
46297
+ if (res2.series_id !== series_id) {
46298
+ return createNotFoundError(
46299
+ `Series '${series_id}' not found.`
46300
+ );
46301
+ }
46228
46302
  const text2 = formatSeriesInfo(res2.seriess[0]);
46229
46303
  return { content: [{ type: "text", text: text2 }] };
46230
46304
  }
@@ -46236,7 +46310,7 @@ server.registerTool(
46236
46310
  const text = formatSeriesInfo(res.seriess[0]);
46237
46311
  return { content: [{ type: "text", text }] };
46238
46312
  } catch (err) {
46239
- return createInternalError(err);
46313
+ return handleFredError(err);
46240
46314
  }
46241
46315
  }
46242
46316
  );
@@ -46259,6 +46333,11 @@ server.registerTool(
46259
46333
  try {
46260
46334
  if (IS_MOCK) {
46261
46335
  const res2 = MOCK_FIXTURES.getSeriesObservations;
46336
+ if (res2.series_id !== series_id) {
46337
+ return createNotFoundError(
46338
+ `No data found for series '${series_id}'.`
46339
+ );
46340
+ }
46262
46341
  const text2 = formatObservations(
46263
46342
  res2.observations,
46264
46343
  res2.count,
@@ -46286,7 +46365,7 @@ server.registerTool(
46286
46365
  );
46287
46366
  return { content: [{ type: "text", text: truncateToLimit(text) }] };
46288
46367
  } catch (err) {
46289
- return createInternalError(err);
46368
+ return handleFredError(err);
46290
46369
  }
46291
46370
  }
46292
46371
  );
@@ -46309,6 +46388,11 @@ server.registerTool(
46309
46388
  try {
46310
46389
  if (IS_MOCK) {
46311
46390
  const res2 = MOCK_FIXTURES.getCategorySeries;
46391
+ if (res2.category_id !== category_id) {
46392
+ return createNotFoundError(
46393
+ `Category '${category_id}' not found.`
46394
+ );
46395
+ }
46312
46396
  const text2 = formatSeriesList(res2.seriess, res2.count, offset);
46313
46397
  return {
46314
46398
  content: [{ type: "text", text: truncateToLimit(text2) }]
@@ -46323,7 +46407,7 @@ server.registerTool(
46323
46407
  const text = formatSeriesList(res.seriess, res.count, offset);
46324
46408
  return { content: [{ type: "text", text: truncateToLimit(text) }] };
46325
46409
  } catch (err) {
46326
- return createInternalError(err);
46410
+ return handleFredError(err);
46327
46411
  }
46328
46412
  }
46329
46413
  );
@@ -46353,7 +46437,7 @@ server.registerTool(
46353
46437
  const text = formatReleases(res.releases, res.count);
46354
46438
  return { content: [{ type: "text", text: truncateToLimit(text) }] };
46355
46439
  } catch (err) {
46356
- return createInternalError(err);
46440
+ return handleFredError(err);
46357
46441
  }
46358
46442
  }
46359
46443
  );
@@ -46376,6 +46460,11 @@ server.registerTool(
46376
46460
  try {
46377
46461
  if (IS_MOCK) {
46378
46462
  const res2 = MOCK_FIXTURES.getReleaseSeries;
46463
+ if (res2.release_id !== release_id) {
46464
+ return createNotFoundError(
46465
+ `Release '${release_id}' not found.`
46466
+ );
46467
+ }
46379
46468
  const text2 = formatSeriesList(res2.seriess, res2.count, offset);
46380
46469
  return {
46381
46470
  content: [{ type: "text", text: truncateToLimit(text2) }]
@@ -46390,7 +46479,7 @@ server.registerTool(
46390
46479
  const text = formatSeriesList(res.seriess, res.count, offset);
46391
46480
  return { content: [{ type: "text", text: truncateToLimit(text) }] };
46392
46481
  } catch (err) {
46393
- return createInternalError(err);
46482
+ return handleFredError(err);
46394
46483
  }
46395
46484
  }
46396
46485
  );
@@ -46437,7 +46526,7 @@ server.registerTool(
46437
46526
  );
46438
46527
  return { content: [{ type: "text", text: truncateToLimit(text) }] };
46439
46528
  } catch (err) {
46440
- return createInternalError(err);
46529
+ return handleFredError(err);
46441
46530
  }
46442
46531
  }
46443
46532
  );
@@ -46459,6 +46548,11 @@ server.registerTool(
46459
46548
  try {
46460
46549
  if (IS_MOCK) {
46461
46550
  const res2 = MOCK_FIXTURES.getSource;
46551
+ if (res2.source_id !== source_id) {
46552
+ return createNotFoundError(
46553
+ `Source '${source_id}' not found.`
46554
+ );
46555
+ }
46462
46556
  const s2 = res2.sources[0];
46463
46557
  const text2 = [
46464
46558
  `## Source: ${s2.name} (ID: ${s2.id})`,
@@ -46482,7 +46576,7 @@ server.registerTool(
46482
46576
  ].filter(Boolean).join("\n");
46483
46577
  return { content: [{ type: "text", text }] };
46484
46578
  } catch (err) {
46485
- return createInternalError(err);
46579
+ return handleFredError(err);
46486
46580
  }
46487
46581
  }
46488
46582
  );
@@ -46490,10 +46584,16 @@ async function main() {
46490
46584
  const transport = new StdioServerTransport();
46491
46585
  await server.connect(transport);
46492
46586
  }
46493
- main().catch((err) => {
46494
- console.error("Fatal error:", err);
46495
- process.exit(1);
46496
- });
46587
+ if (process.env.NODE_ENV !== "test") {
46588
+ main().catch((err) => {
46589
+ console.error("Fatal error:", err);
46590
+ process.exit(1);
46591
+ });
46592
+ }
46593
+ export {
46594
+ handleFredError,
46595
+ server
46596
+ };
46497
46597
  /*! Bundled license information:
46498
46598
 
46499
46599
  mime-db/index.js:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fre4x/fred",
3
- "version": "1.0.43",
3
+ "version": "1.0.46",
4
4
  "description": "A FRED economic data MCP server for LLMs.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -11,11 +11,12 @@
11
11
  "dist"
12
12
  ],
13
13
  "scripts": {
14
- "build": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\" && npx esbuild src/index.ts --bundle --outfile=dist/index.js --platform=node --format=esm --banner:js=\"import{createRequire}from'module';const require=createRequire(import.meta.url);\"",
14
+ "build": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\" && npx esbuild src/index.ts --bundle --outfile=dist/index.js --platform=node --format=esm --banner:js=\"import{createRequire}from'module';const require=createRequire(import.meta.url);\" && node -e \"const fs=require('fs');const p='dist/index.js';const c=fs.readFileSync(p,'utf8');const next=c.startsWith('#!/usr/bin/env node')?c:'#!/usr/bin/env node\\n'+c;fs.writeFileSync(p,next);fs.chmodSync(p,0o755);\"",
15
15
  "typecheck": "cross-env NODE_OPTIONS=--max-old-space-size=4096 tsc --noEmit",
16
16
  "start": "node dist/index.js",
17
17
  "dev": "tsx src/index.ts",
18
18
  "watch": "tsc -w",
19
+ "inspector": "cross-env MOCK=true npx @modelcontextprotocol/inspector node dist/index.js",
19
20
  "test": "vitest run --passWithNoTests --exclude dist"
20
21
  },
21
22
  "keywords": [