@fre4x/fred 1.1.1 → 1.1.2

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 (3) hide show
  1. package/README.md +8 -8
  2. package/dist/index.js +127 -187
  3. package/package.json +7 -7
package/README.md CHANGED
@@ -10,14 +10,14 @@ The Federal Reserve publishes the data that governments and institutions use to
10
10
 
11
11
  | Tool | What it reaches |
12
12
  |------|----------------|
13
- | `search_series` | Full-text search across all FRED series |
14
- | `get_series_info` | Metadata for a series — units, frequency, range, last update |
15
- | `get_series_data` | Observation time-series for any series (e.g. `GDP`, `UNRATE`, `CPIAUCSL`) |
16
- | `get_category_series` | All series under a given FRED category |
17
- | `get_releases` | Index of all FRED data releases |
18
- | `get_release_series` | Series belonging to a specific release |
19
- | `get_sources` | All primary data sources in FRED |
20
- | `get_source` | Details for one source |
13
+ | `fred_search_series` | Full-text search across all FRED series |
14
+ | `fred_get_series_info` | Metadata for a series — units, frequency, range, last update |
15
+ | `fred_get_series_data` | Observation time-series for any series (e.g. `GDP`, `UNRATE`, `CPIAUCSL`) |
16
+ | `fred_get_category_series` | All series under a given FRED category |
17
+ | `fred_get_releases` | Index of all FRED data releases |
18
+ | `fred_get_release_series` | Series belonging to a specific release |
19
+ | `fred_get_sources` | All primary data sources in FRED |
20
+ | `fred_get_source` | Details for one source |
21
21
 
22
22
  All list tools support pagination via `limit` / `offset`.
23
23
 
package/dist/index.js CHANGED
@@ -7065,9 +7065,9 @@ var require_combined_stream = __commonJS({
7065
7065
  }
7066
7066
  });
7067
7067
 
7068
- // ../node_modules/form-data/node_modules/mime-types/node_modules/mime-db/db.json
7068
+ // ../node_modules/form-data/node_modules/mime-db/db.json
7069
7069
  var require_db = __commonJS({
7070
- "../node_modules/form-data/node_modules/mime-types/node_modules/mime-db/db.json"(exports, module) {
7070
+ "../node_modules/form-data/node_modules/mime-db/db.json"(exports, module) {
7071
7071
  module.exports = {
7072
7072
  "application/1d-interleaved-parityfec": {
7073
7073
  source: "iana"
@@ -15590,9 +15590,9 @@ var require_db = __commonJS({
15590
15590
  }
15591
15591
  });
15592
15592
 
15593
- // ../node_modules/form-data/node_modules/mime-types/node_modules/mime-db/index.js
15593
+ // ../node_modules/form-data/node_modules/mime-db/index.js
15594
15594
  var require_mime_db = __commonJS({
15595
- "../node_modules/form-data/node_modules/mime-types/node_modules/mime-db/index.js"(exports, module) {
15595
+ "../node_modules/form-data/node_modules/mime-db/index.js"(exports, module) {
15596
15596
  module.exports = require_db();
15597
15597
  }
15598
15598
  });
@@ -16764,7 +16764,7 @@ var require_form_data = __commonJS({
16764
16764
  var path = __require("path");
16765
16765
  var http3 = __require("http");
16766
16766
  var https3 = __require("https");
16767
- var parseUrl = __require("url").parse;
16767
+ var parseUrl2 = __require("url").parse;
16768
16768
  var fs = __require("fs");
16769
16769
  var Stream = __require("stream").Stream;
16770
16770
  var crypto2 = __require("crypto");
@@ -17017,7 +17017,7 @@ var require_form_data = __commonJS({
17017
17017
  var options;
17018
17018
  var defaults2 = { method: "post" };
17019
17019
  if (typeof params === "string") {
17020
- params = parseUrl(params);
17020
+ params = parseUrl2(params);
17021
17021
  options = populate({
17022
17022
  port: params.port,
17023
17023
  path: params.pathname,
@@ -17074,76 +17074,6 @@ var require_form_data = __commonJS({
17074
17074
  }
17075
17075
  });
17076
17076
 
17077
- // ../node_modules/proxy-from-env/index.js
17078
- var require_proxy_from_env = __commonJS({
17079
- "../node_modules/proxy-from-env/index.js"(exports) {
17080
- "use strict";
17081
- var parseUrl = __require("url").parse;
17082
- var DEFAULT_PORTS = {
17083
- ftp: 21,
17084
- gopher: 70,
17085
- http: 80,
17086
- https: 443,
17087
- ws: 80,
17088
- wss: 443
17089
- };
17090
- var stringEndsWith = String.prototype.endsWith || function(s) {
17091
- return s.length <= this.length && this.indexOf(s, this.length - s.length) !== -1;
17092
- };
17093
- function getProxyForUrl(url3) {
17094
- var parsedUrl = typeof url3 === "string" ? parseUrl(url3) : url3 || {};
17095
- var proto = parsedUrl.protocol;
17096
- var hostname3 = parsedUrl.host;
17097
- var port = parsedUrl.port;
17098
- if (typeof hostname3 !== "string" || !hostname3 || typeof proto !== "string") {
17099
- return "";
17100
- }
17101
- proto = proto.split(":", 1)[0];
17102
- hostname3 = hostname3.replace(/:\d*$/, "");
17103
- port = parseInt(port) || DEFAULT_PORTS[proto] || 0;
17104
- if (!shouldProxy(hostname3, port)) {
17105
- return "";
17106
- }
17107
- var proxy = getEnv("npm_config_" + proto + "_proxy") || getEnv(proto + "_proxy") || getEnv("npm_config_proxy") || getEnv("all_proxy");
17108
- if (proxy && proxy.indexOf("://") === -1) {
17109
- proxy = proto + "://" + proxy;
17110
- }
17111
- return proxy;
17112
- }
17113
- function shouldProxy(hostname3, port) {
17114
- var NO_PROXY = (getEnv("npm_config_no_proxy") || getEnv("no_proxy")).toLowerCase();
17115
- if (!NO_PROXY) {
17116
- return true;
17117
- }
17118
- if (NO_PROXY === "*") {
17119
- return false;
17120
- }
17121
- return NO_PROXY.split(/[,\s]/).every(function(proxy) {
17122
- if (!proxy) {
17123
- return true;
17124
- }
17125
- var parsedProxy = proxy.match(/^(.+):(\d+)$/);
17126
- var parsedProxyHostname = parsedProxy ? parsedProxy[1] : proxy;
17127
- var parsedProxyPort = parsedProxy ? parseInt(parsedProxy[2]) : 0;
17128
- if (parsedProxyPort && parsedProxyPort !== port) {
17129
- return true;
17130
- }
17131
- if (!/^[.*]/.test(parsedProxyHostname)) {
17132
- return hostname3 !== parsedProxyHostname;
17133
- }
17134
- if (parsedProxyHostname.charAt(0) === "*") {
17135
- parsedProxyHostname = parsedProxyHostname.slice(1);
17136
- }
17137
- return !stringEndsWith.call(hostname3, parsedProxyHostname);
17138
- });
17139
- }
17140
- function getEnv(key) {
17141
- return process.env[key.toLowerCase()] || process.env[key.toUpperCase()] || "";
17142
- }
17143
- exports.getProxyForUrl = getProxyForUrl;
17144
- }
17145
- });
17146
-
17147
17077
  // ../node_modules/ms/index.js
17148
17078
  var require_ms = __commonJS({
17149
17079
  "../node_modules/ms/index.js"(exports, module) {
@@ -18261,7 +18191,7 @@ var require_follow_redirects = __commonJS({
18261
18191
  removeMatchingHeaders(/^content-/i, this._options.headers);
18262
18192
  }
18263
18193
  var currentHostHeader = removeMatchingHeaders(/^host$/i, this._options.headers);
18264
- var currentUrlParts = parseUrl(this._currentUrl);
18194
+ var currentUrlParts = parseUrl2(this._currentUrl);
18265
18195
  var currentHost = currentHostHeader || currentUrlParts.host;
18266
18196
  var currentUrl = /^\w+:/.test(location) ? this._currentUrl : url3.format(Object.assign(currentUrlParts, { host: currentHost }));
18267
18197
  var redirectUrl = resolveUrl(location, currentUrl);
@@ -18300,7 +18230,7 @@ var require_follow_redirects = __commonJS({
18300
18230
  if (isURL(input)) {
18301
18231
  input = spreadUrlObject(input);
18302
18232
  } else if (isString2(input)) {
18303
- input = spreadUrlObject(parseUrl(input));
18233
+ input = spreadUrlObject(parseUrl2(input));
18304
18234
  } else {
18305
18235
  callback = options;
18306
18236
  options = validateUrl(input);
@@ -18336,7 +18266,7 @@ var require_follow_redirects = __commonJS({
18336
18266
  }
18337
18267
  function noop2() {
18338
18268
  }
18339
- function parseUrl(input) {
18269
+ function parseUrl2(input) {
18340
18270
  var parsed;
18341
18271
  if (useNativeURL) {
18342
18272
  parsed = new URL2(input);
@@ -18349,7 +18279,7 @@ var require_follow_redirects = __commonJS({
18349
18279
  return parsed;
18350
18280
  }
18351
18281
  function resolveUrl(relative, base) {
18352
- return useNativeURL ? new URL2(relative, base) : parseUrl(url3.resolve(base, relative));
18282
+ return useNativeURL ? new URL2(relative, base) : parseUrl2(url3.resolve(base, relative));
18353
18283
  }
18354
18284
  function validateUrl(input) {
18355
18285
  if (/^\[/.test(input.hostname) && !/^\[[:0-9a-f]+\]$/i.test(input.hostname)) {
@@ -18438,26 +18368,22 @@ var require_follow_redirects = __commonJS({
18438
18368
  // ../packages/shared/dist/errors.js
18439
18369
  function createApiError(message, statusCode) {
18440
18370
  let hint = "Check your network connection and retry.";
18441
- let type = "Service Error";
18442
18371
  if (statusCode === 429) {
18443
- type = "Rate Limit";
18444
- hint = "Request volume is too high. Suggestion: Wait briefly before retrying or reduce concurrent calls.";
18372
+ hint = "Rate limit exceeded. Suggestion: Wait for 60 seconds (Exponential Backoff) before retrying or reduce concurrent calls.";
18445
18373
  } else if (statusCode === 401 || statusCode === 403) {
18446
- type = "Authentication Error";
18447
- hint = "The request could not be authorized. Suggestion: Verify your API key or token in the environment configuration.";
18374
+ hint = "Authentication failed. Suggestion: Verify your API key or token in the environment configuration.";
18448
18375
  } else if (statusCode && statusCode >= 500) {
18449
- type = "Upstream Error";
18450
- hint = "The remote service is experiencing temporary issues. Suggestion: Try again in a few minutes.";
18376
+ hint = "Upstream service is having issues. Suggestion: This is a temporary external error. Try again in a few minutes.";
18451
18377
  } else if (statusCode === 404) {
18452
- type = "Not Found";
18453
- hint = "The requested information could not be found. Suggestion: Check if the ID, Ticker, or query parameters are correct.";
18378
+ hint = "The requested resource was not found. Suggestion: Check if the ID or Ticker is correct, or search for it first.";
18454
18379
  }
18380
+ const detail = statusCode ? ` (HTTP ${statusCode})` : "";
18455
18381
  return {
18456
18382
  isError: true,
18457
18383
  content: [
18458
18384
  {
18459
18385
  type: "text",
18460
- text: `${type}: ${message}
18386
+ text: `API Error${detail}: ${message}
18461
18387
 
18462
18388
  **Next Action**: ${hint}`
18463
18389
  }
@@ -32521,8 +32447,7 @@ config(en_default());
32521
32447
  var zod_default = external_exports;
32522
32448
 
32523
32449
  // ../packages/shared/dist/pagination.js
32524
- var zodCompat = zod_exports;
32525
- var z2 = zodCompat.z ?? zodCompat.default?.z ?? zodCompat.default ?? zodCompat;
32450
+ var z2 = external_exports || zod_default || zod_exports;
32526
32451
  var paginationSchema = z2.object({
32527
32452
  limit: z2.number().int().min(1).max(100).default(20).describe("Maximum results to return (1\u2013100, default 20)"),
32528
32453
  offset: z2.number().int().min(0).default(0).describe("Number of results to skip for pagination (default 0)")
@@ -32540,14 +32465,6 @@ function applyPagination(items, params) {
32540
32465
  };
32541
32466
  }
32542
32467
 
32543
- // ../packages/shared/dist/package.js
32544
- import { createRequire as createJsonRequire } from "node:module";
32545
- function getPackageVersion(moduleUrl) {
32546
- const require2 = createJsonRequire(moduleUrl);
32547
- const packageJson = require2("../package.json");
32548
- return packageJson.version ?? "0.0.0";
32549
- }
32550
-
32551
32468
  // ../node_modules/zod/v3/helpers/util.js
32552
32469
  var util;
32553
32470
  (function(util4) {
@@ -43134,7 +43051,7 @@ function normalizeValue(value) {
43134
43051
  if (value === false || value == null) {
43135
43052
  return value;
43136
43053
  }
43137
- return utils_default.isArray(value) ? value.map(normalizeValue) : String(value);
43054
+ return utils_default.isArray(value) ? value.map(normalizeValue) : String(value).replace(/[\r\n]+$/, "");
43138
43055
  }
43139
43056
  function parseTokens(str) {
43140
43057
  const tokens = /* @__PURE__ */ Object.create(null);
@@ -43438,8 +43355,74 @@ function buildFullPath(baseURL, requestedURL, allowAbsoluteUrls) {
43438
43355
  return requestedURL;
43439
43356
  }
43440
43357
 
43358
+ // ../node_modules/proxy-from-env/index.js
43359
+ var DEFAULT_PORTS = {
43360
+ ftp: 21,
43361
+ gopher: 70,
43362
+ http: 80,
43363
+ https: 443,
43364
+ ws: 80,
43365
+ wss: 443
43366
+ };
43367
+ function parseUrl(urlString) {
43368
+ try {
43369
+ return new URL(urlString);
43370
+ } catch {
43371
+ return null;
43372
+ }
43373
+ }
43374
+ function getProxyForUrl(url3) {
43375
+ var parsedUrl = (typeof url3 === "string" ? parseUrl(url3) : url3) || {};
43376
+ var proto = parsedUrl.protocol;
43377
+ var hostname3 = parsedUrl.host;
43378
+ var port = parsedUrl.port;
43379
+ if (typeof hostname3 !== "string" || !hostname3 || typeof proto !== "string") {
43380
+ return "";
43381
+ }
43382
+ proto = proto.split(":", 1)[0];
43383
+ hostname3 = hostname3.replace(/:\d*$/, "");
43384
+ port = parseInt(port) || DEFAULT_PORTS[proto] || 0;
43385
+ if (!shouldProxy(hostname3, port)) {
43386
+ return "";
43387
+ }
43388
+ var proxy = getEnv(proto + "_proxy") || getEnv("all_proxy");
43389
+ if (proxy && proxy.indexOf("://") === -1) {
43390
+ proxy = proto + "://" + proxy;
43391
+ }
43392
+ return proxy;
43393
+ }
43394
+ function shouldProxy(hostname3, port) {
43395
+ var NO_PROXY = getEnv("no_proxy").toLowerCase();
43396
+ if (!NO_PROXY) {
43397
+ return true;
43398
+ }
43399
+ if (NO_PROXY === "*") {
43400
+ return false;
43401
+ }
43402
+ return NO_PROXY.split(/[,\s]/).every(function(proxy) {
43403
+ if (!proxy) {
43404
+ return true;
43405
+ }
43406
+ var parsedProxy = proxy.match(/^(.+):(\d+)$/);
43407
+ var parsedProxyHostname = parsedProxy ? parsedProxy[1] : proxy;
43408
+ var parsedProxyPort = parsedProxy ? parseInt(parsedProxy[2]) : 0;
43409
+ if (parsedProxyPort && parsedProxyPort !== port) {
43410
+ return true;
43411
+ }
43412
+ if (!/^[.*]/.test(parsedProxyHostname)) {
43413
+ return hostname3 !== parsedProxyHostname;
43414
+ }
43415
+ if (parsedProxyHostname.charAt(0) === "*") {
43416
+ parsedProxyHostname = parsedProxyHostname.slice(1);
43417
+ }
43418
+ return !hostname3.endsWith(parsedProxyHostname);
43419
+ });
43420
+ }
43421
+ function getEnv(key) {
43422
+ return process.env[key.toLowerCase()] || process.env[key.toUpperCase()] || "";
43423
+ }
43424
+
43441
43425
  // ../node_modules/axios/lib/adapters/http.js
43442
- var import_proxy_from_env = __toESM(require_proxy_from_env(), 1);
43443
43426
  var import_follow_redirects = __toESM(require_follow_redirects(), 1);
43444
43427
  import http from "http";
43445
43428
  import https from "https";
@@ -43448,7 +43431,7 @@ import util3 from "util";
43448
43431
  import zlib from "zlib";
43449
43432
 
43450
43433
  // ../node_modules/axios/lib/env/data.js
43451
- var VERSION = "1.13.6";
43434
+ var VERSION = "1.14.0";
43452
43435
 
43453
43436
  // ../node_modules/axios/lib/helpers/parseProtocol.js
43454
43437
  function parseProtocol(url3) {
@@ -43969,6 +43952,9 @@ var Http2Sessions = class {
43969
43952
  } else {
43970
43953
  entries.splice(i, 1);
43971
43954
  }
43955
+ if (!session.closed) {
43956
+ session.close();
43957
+ }
43972
43958
  return;
43973
43959
  }
43974
43960
  }
@@ -44014,7 +44000,7 @@ function dispatchBeforeRedirect(options, responseDetails) {
44014
44000
  function setProxy(options, configProxy, location) {
44015
44001
  let proxy = configProxy;
44016
44002
  if (!proxy && proxy !== false) {
44017
- const proxyUrl = import_proxy_from_env.default.getProxyForUrl(location);
44003
+ const proxyUrl = getProxyForUrl(location);
44018
44004
  if (proxyUrl) {
44019
44005
  proxy = new URL(proxyUrl);
44020
44006
  }
@@ -45060,14 +45046,16 @@ var factory = (env) => {
45060
45046
  const encodeText = isFetchSupported && (typeof TextEncoder2 === "function" ? /* @__PURE__ */ ((encoder) => (str) => encoder.encode(str))(new TextEncoder2()) : async (str) => new Uint8Array(await new Request(str).arrayBuffer()));
45061
45047
  const supportsRequestStream = isRequestSupported && isReadableStreamSupported && test(() => {
45062
45048
  let duplexAccessed = false;
45049
+ const body = new ReadableStream2();
45063
45050
  const hasContentType = new Request(platform_default.origin, {
45064
- body: new ReadableStream2(),
45051
+ body,
45065
45052
  method: "POST",
45066
45053
  get duplex() {
45067
45054
  duplexAccessed = true;
45068
45055
  return "half";
45069
45056
  }
45070
45057
  }).headers.has("Content-Type");
45058
+ body.cancel();
45071
45059
  return duplexAccessed && !hasContentType;
45072
45060
  });
45073
45061
  const supportsResponseStream = isResponseSupported && isReadableStreamSupported && test(() => utils_default.isReadableStream(new Response("").body));
@@ -45853,30 +45841,20 @@ var {
45853
45841
  // src/api.ts
45854
45842
  var FRED_BASE_URL = "https://api.stlouisfed.org/fred";
45855
45843
  var httpsAgent = new https2.Agent({ keepAlive: true });
45856
- function getApiKey() {
45857
- const key = process.env.FRED_API_KEY;
45858
- if (!key) {
45859
- throw new Error(
45860
- "FRED_API_KEY environment variable not set. Please set it to use this server."
45861
- );
45862
- }
45863
- return key;
45864
- }
45865
- function buildRequestParams(params) {
45866
- const filteredEntries = Object.entries(params).filter(
45867
- ([, value]) => value !== void 0
45868
- );
45869
- return Object.fromEntries([
45870
- ...filteredEntries,
45871
- ["api_key", getApiKey()],
45872
- ["file_type", "json"]
45873
- ]);
45874
- }
45875
45844
  var FredApiClient = class {
45876
45845
  client;
45846
+ apiKey;
45877
45847
  constructor() {
45848
+ const key = process.env.FRED_API_KEY;
45849
+ if (!key) {
45850
+ throw new Error(
45851
+ "FRED_API_KEY environment variable not set. Please set it to use this server."
45852
+ );
45853
+ }
45854
+ this.apiKey = key;
45878
45855
  this.client = axios_default.create({
45879
45856
  baseURL: FRED_BASE_URL,
45857
+ params: { api_key: this.apiKey, file_type: "json" },
45880
45858
  httpsAgent
45881
45859
  });
45882
45860
  }
@@ -45884,13 +45862,13 @@ var FredApiClient = class {
45884
45862
  const { data } = await this.client.get(
45885
45863
  "/series/search",
45886
45864
  {
45887
- params: buildRequestParams({
45865
+ params: {
45888
45866
  search_text: query,
45889
45867
  limit,
45890
45868
  offset,
45891
45869
  order_by: "popularity",
45892
45870
  sort_order: "desc"
45893
- })
45871
+ }
45894
45872
  }
45895
45873
  );
45896
45874
  return data;
@@ -45899,7 +45877,7 @@ var FredApiClient = class {
45899
45877
  const { data } = await this.client.get(
45900
45878
  "/series",
45901
45879
  {
45902
- params: buildRequestParams({ series_id: seriesId })
45880
+ params: { series_id: seriesId }
45903
45881
  }
45904
45882
  );
45905
45883
  return data;
@@ -45908,12 +45886,12 @@ var FredApiClient = class {
45908
45886
  const { data } = await this.client.get(
45909
45887
  "/series/observations",
45910
45888
  {
45911
- params: buildRequestParams({
45889
+ params: {
45912
45890
  series_id: seriesId,
45913
45891
  limit,
45914
45892
  offset,
45915
45893
  sort_order: "desc"
45916
- })
45894
+ }
45917
45895
  }
45918
45896
  );
45919
45897
  return data;
@@ -45922,13 +45900,13 @@ var FredApiClient = class {
45922
45900
  const { data } = await this.client.get(
45923
45901
  "/category/series",
45924
45902
  {
45925
- params: buildRequestParams({
45903
+ params: {
45926
45904
  category_id: categoryId,
45927
45905
  limit,
45928
45906
  offset,
45929
45907
  order_by: "popularity",
45930
45908
  sort_order: "desc"
45931
- })
45909
+ }
45932
45910
  }
45933
45911
  );
45934
45912
  return data;
@@ -45937,12 +45915,7 @@ var FredApiClient = class {
45937
45915
  const { data } = await this.client.get(
45938
45916
  "/releases",
45939
45917
  {
45940
- params: buildRequestParams({
45941
- limit,
45942
- offset,
45943
- order_by: "release_id",
45944
- sort_order: "desc"
45945
- })
45918
+ params: { limit, offset }
45946
45919
  }
45947
45920
  );
45948
45921
  return data;
@@ -45951,31 +45924,20 @@ var FredApiClient = class {
45951
45924
  const { data } = await this.client.get(
45952
45925
  "/release/series",
45953
45926
  {
45954
- params: buildRequestParams({
45955
- release_id: releaseId,
45956
- limit,
45957
- offset,
45958
- order_by: "popularity",
45959
- sort_order: "desc"
45960
- })
45927
+ params: { release_id: releaseId, limit, offset }
45961
45928
  }
45962
45929
  );
45963
45930
  return data;
45964
45931
  }
45965
45932
  async getSources() {
45966
- const { data } = await this.client.get(
45967
- "/sources",
45968
- {
45969
- params: buildRequestParams({})
45970
- }
45971
- );
45933
+ const { data } = await this.client.get("/sources");
45972
45934
  return data;
45973
45935
  }
45974
45936
  async getSource(sourceId) {
45975
45937
  const { data } = await this.client.get(
45976
45938
  "/source",
45977
45939
  {
45978
- params: buildRequestParams({ source_id: sourceId })
45940
+ params: { source_id: sourceId }
45979
45941
  }
45980
45942
  );
45981
45943
  return data;
@@ -46176,10 +46138,9 @@ var MOCK_FIXTURES = {
46176
46138
  };
46177
46139
 
46178
46140
  // src/index.ts
46179
- var PACKAGE_VERSION = getPackageVersion(import.meta.url);
46180
46141
  var server = new McpServer({
46181
46142
  name: "fred-mcp-server",
46182
- version: PACKAGE_VERSION
46143
+ version: "1.0.0"
46183
46144
  });
46184
46145
  var clientInstance = null;
46185
46146
  function getClient() {
@@ -46189,36 +46150,25 @@ function getClient() {
46189
46150
  return clientInstance;
46190
46151
  }
46191
46152
  function extractErrorMessage(err) {
46192
- const sanitize = (value) => {
46193
- const apiKey = process.env.FRED_API_KEY;
46194
- let sanitized = value.replace(
46195
- /([?&]api_key=)[^&\s]+/gi,
46196
- "$1[REDACTED]"
46197
- );
46198
- if (apiKey) {
46199
- sanitized = sanitized.split(apiKey).join("[REDACTED]");
46200
- }
46201
- return sanitized;
46202
- };
46203
46153
  if (typeof err !== "object" || err === null) {
46204
- return sanitize(String(err));
46154
+ return String(err);
46205
46155
  }
46206
46156
  const error48 = err;
46207
46157
  const responseData = error48.response?.data;
46208
46158
  if (typeof responseData === "string" && responseData.trim()) {
46209
- return sanitize(responseData.trim());
46159
+ return responseData.trim();
46210
46160
  }
46211
46161
  if (responseData && typeof responseData === "object") {
46212
46162
  const data = responseData;
46213
46163
  const nestedMessage = data.error_message ?? data.message ?? data.error ?? data.detail;
46214
46164
  if (nestedMessage !== void 0 && nestedMessage !== null) {
46215
- return sanitize(String(nestedMessage));
46165
+ return String(nestedMessage);
46216
46166
  }
46217
46167
  }
46218
46168
  if (error48.message !== void 0 && error48.message !== null) {
46219
- return sanitize(String(error48.message));
46169
+ return String(error48.message);
46220
46170
  }
46221
- return sanitize("Request failed.");
46171
+ return "Request failed.";
46222
46172
  }
46223
46173
  function handleFredError(err) {
46224
46174
  if (typeof err === "object" && err !== null) {
@@ -46295,7 +46245,7 @@ function formatSources(sources, total, offset, limit) {
46295
46245
  ` + rows.join("\n") + formatPaginationFooter(offset, limit, total);
46296
46246
  }
46297
46247
  server.registerTool(
46298
- "search_series",
46248
+ "fred_search_series",
46299
46249
  {
46300
46250
  title: "Search FRED Series",
46301
46251
  description: "Search FRED economic data series by text query.",
@@ -46328,7 +46278,7 @@ server.registerTool(
46328
46278
  }
46329
46279
  );
46330
46280
  server.registerTool(
46331
- "get_series_info",
46281
+ "fred_get_series_info",
46332
46282
  {
46333
46283
  title: "Get FRED Series Info",
46334
46284
  description: "Get metadata for a specific FRED series.",
@@ -46366,7 +46316,7 @@ server.registerTool(
46366
46316
  }
46367
46317
  );
46368
46318
  server.registerTool(
46369
- "get_series_data",
46319
+ "fred_get_series_data",
46370
46320
  {
46371
46321
  title: "Get FRED Series Data",
46372
46322
  description: "Get observation data points for a specific FRED series.",
@@ -46421,7 +46371,7 @@ server.registerTool(
46421
46371
  }
46422
46372
  );
46423
46373
  server.registerTool(
46424
- "get_category_series",
46374
+ "fred_get_category_series",
46425
46375
  {
46426
46376
  title: "Get FRED Category Series",
46427
46377
  description: "Get series belonging to a specific FRED category.",
@@ -46455,11 +46405,6 @@ server.registerTool(
46455
46405
  limit,
46456
46406
  offset
46457
46407
  );
46458
- if (!res.seriess || res.seriess.length === 0) {
46459
- return createNotFoundError(
46460
- `Category '${category_id}' not found.`
46461
- );
46462
- }
46463
46408
  const text = formatSeriesList(res.seriess, res.count, offset);
46464
46409
  return { content: [{ type: "text", text: truncateToLimit(text) }] };
46465
46410
  } catch (err) {
@@ -46468,7 +46413,7 @@ server.registerTool(
46468
46413
  }
46469
46414
  );
46470
46415
  server.registerTool(
46471
- "get_releases",
46416
+ "fred_get_releases",
46472
46417
  {
46473
46418
  title: "Get FRED Releases",
46474
46419
  description: "Get all economic data releases from FRED.",
@@ -46498,7 +46443,7 @@ server.registerTool(
46498
46443
  }
46499
46444
  );
46500
46445
  server.registerTool(
46501
- "get_release_series",
46446
+ "fred_get_release_series",
46502
46447
  {
46503
46448
  title: "Get FRED Release Series",
46504
46449
  description: "Get series belonging to a specific FRED release.",
@@ -46532,11 +46477,6 @@ server.registerTool(
46532
46477
  limit,
46533
46478
  offset
46534
46479
  );
46535
- if (!res.seriess || res.seriess.length === 0) {
46536
- return createNotFoundError(
46537
- `Release '${release_id}' not found.`
46538
- );
46539
- }
46540
46480
  const text = formatSeriesList(res.seriess, res.count, offset);
46541
46481
  return { content: [{ type: "text", text: truncateToLimit(text) }] };
46542
46482
  } catch (err) {
@@ -46545,7 +46485,7 @@ server.registerTool(
46545
46485
  }
46546
46486
  );
46547
46487
  server.registerTool(
46548
- "get_sources",
46488
+ "fred_get_sources",
46549
46489
  {
46550
46490
  title: "Get FRED Sources",
46551
46491
  description: "Get all data sources available in FRED.",
@@ -46592,7 +46532,7 @@ server.registerTool(
46592
46532
  }
46593
46533
  );
46594
46534
  server.registerTool(
46595
- "get_source",
46535
+ "fred_get_source",
46596
46536
  {
46597
46537
  title: "Get FRED Source",
46598
46538
  description: "Get details for a specific FRED data source.",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fre4x/fred",
3
- "version": "1.1.1",
3
+ "version": "1.1.2",
4
4
  "description": "A FRED economic data MCP server for LLMs.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -11,13 +11,13 @@
11
11
  "dist"
12
12
  ],
13
13
  "scripts": {
14
- "build": "node ../scripts/build-package.mjs",
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": "npm run build && node ../scripts/run-official-inspector.mjs node dist/index.js",
20
- "test": "node ../scripts/run-vitest.mjs run --passWithNoTests --exclude dist"
19
+ "inspector": "node ../scripts/run-official-inspector.mjs node dist/index.js",
20
+ "test": "vitest run --passWithNoTests --exclude dist"
21
21
  },
22
22
  "keywords": [
23
23
  "mcp",
@@ -29,12 +29,12 @@
29
29
  "author": "fritzprix",
30
30
  "license": "MIT",
31
31
  "dependencies": {
32
- "@modelcontextprotocol/sdk": "^1.27.1",
32
+ "@modelcontextprotocol/sdk": "^1.26.0",
33
33
  "axios": "^1.13.5",
34
- "zod": "^4.3.6"
34
+ "zod": "^4.0.0"
35
35
  },
36
36
  "devDependencies": {
37
- "@types/node": "^25.3.5",
37
+ "@types/node": "^25.3.0",
38
38
  "tsx": "^4.21.0",
39
39
  "typescript": "^5.9.3",
40
40
  "vitest": "^4.0.18"