@frontmcp/adapters 1.5.4 → 1.5.6

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/esm/index.mjs CHANGED
@@ -10,10 +10,11 @@ var __decorateClass = (decorators, target, key, kind) => {
10
10
  };
11
11
 
12
12
  // libs/adapters/src/openapi/openapi.adapter.ts
13
- import { OpenAPIToolGenerator } from "mcp-from-openapi";
13
+ import { normalizeSsrfOptions as normalizeSsrfOptions2, OpenAPIToolGenerator } from "mcp-from-openapi";
14
14
  import { Adapter, DynamicAdapter } from "@frontmcp/sdk";
15
15
 
16
16
  // libs/adapters/src/openapi/openapi-spec-poller.ts
17
+ import { normalizeSsrfOptions, safeFetch } from "mcp-from-openapi";
17
18
  import { sha256Hex } from "@frontmcp/utils";
18
19
 
19
20
  // libs/adapters/src/openapi/openapi.errors.ts
@@ -39,6 +40,8 @@ var OpenApiSpecPoller = class {
39
40
  retry;
40
41
  unhealthyThreshold;
41
42
  headers;
43
+ ssrf;
44
+ followRedirects;
42
45
  callbacks;
43
46
  intervalTimer = null;
44
47
  lastHash = null;
@@ -56,6 +59,8 @@ var OpenApiSpecPoller = class {
56
59
  this.retry = { ...DEFAULT_RETRY, ...options.retry };
57
60
  this.unhealthyThreshold = options.unhealthyThreshold ?? 3;
58
61
  this.headers = options.headers ?? {};
62
+ this.ssrf = options.ssrf ?? normalizeSsrfOptions(void 0);
63
+ this.followRedirects = options.followRedirects ?? false;
59
64
  this.callbacks = callbacks;
60
65
  }
61
66
  /**
@@ -143,35 +148,31 @@ var OpenApiSpecPoller = class {
143
148
  headers["If-Modified-Since"] = this.lastModified;
144
149
  }
145
150
  }
146
- const controller = new AbortController();
147
- const timeout = setTimeout(() => controller.abort(), this.fetchTimeoutMs);
148
- try {
149
- const response = await fetch(this.url, {
150
- headers,
151
- signal: controller.signal
152
- });
153
- if (response.status === 304) {
154
- this.callbacks.onUnchanged?.();
155
- return;
156
- }
157
- if (!response.ok) {
158
- throw new OpenAPIFetchError(this.url, response.status, response.statusText);
159
- }
160
- const etag = response.headers.get("etag");
161
- const lastModified = response.headers.get("last-modified");
162
- if (etag) this.lastEtag = etag;
163
- if (lastModified) this.lastModified = lastModified;
164
- const body = await response.text();
165
- const hash = sha256Hex(body);
166
- if (this.lastHash && this.lastHash === hash) {
167
- this.callbacks.onUnchanged?.();
168
- return;
169
- }
170
- this.lastHash = hash;
171
- this.callbacks.onChanged?.(body, hash);
172
- } finally {
173
- clearTimeout(timeout);
174
- }
151
+ const response = await safeFetch(this.url, {
152
+ headers,
153
+ timeoutMs: this.fetchTimeoutMs,
154
+ followRedirects: this.followRedirects,
155
+ ssrf: this.ssrf
156
+ });
157
+ if (response.status === 304) {
158
+ this.callbacks.onUnchanged?.();
159
+ return;
160
+ }
161
+ if (!response.ok) {
162
+ throw new OpenAPIFetchError(this.url, response.status, response.statusText);
163
+ }
164
+ const etag = response.headers.get("etag");
165
+ const lastModified = response.headers.get("last-modified");
166
+ if (etag) this.lastEtag = etag;
167
+ if (lastModified) this.lastModified = lastModified;
168
+ const body = await response.text();
169
+ const hash = sha256Hex(body);
170
+ if (this.lastHash && this.lastHash === hash) {
171
+ this.callbacks.onUnchanged?.();
172
+ return;
173
+ }
174
+ this.lastHash = hash;
175
+ this.callbacks.onChanged?.(body, hash);
175
176
  }
176
177
  /**
177
178
  * Dispose the poller and release resources.
@@ -1741,7 +1742,12 @@ ${this.formatSchemaAsSummary(schema)}`;
1741
1742
  if (this.poller) return;
1742
1743
  const polling = this.options.polling;
1743
1744
  if (!polling?.enabled || !("url" in this.options)) return;
1744
- this.poller = new OpenApiSpecPoller(this.options.url, polling, {
1745
+ const pollingOptions = {
1746
+ ...polling,
1747
+ ssrf: normalizeSsrfOptions2(this.resolveRefResolution()),
1748
+ followRedirects: this.options.loadOptions?.followRedirects ?? false
1749
+ };
1750
+ this.poller = new OpenApiSpecPoller(this.options.url, pollingOptions, {
1745
1751
  onChanged: (_spec, _hash) => {
1746
1752
  this.rebuildChain = this.rebuildChain.then(async () => {
1747
1753
  const previousGenerator = this.generator;
@@ -10,10 +10,11 @@ var __decorateClass = (decorators, target, key, kind) => {
10
10
  };
11
11
 
12
12
  // libs/adapters/src/openapi/openapi.adapter.ts
13
- import { OpenAPIToolGenerator } from "mcp-from-openapi";
13
+ import { normalizeSsrfOptions as normalizeSsrfOptions2, OpenAPIToolGenerator } from "mcp-from-openapi";
14
14
  import { Adapter, DynamicAdapter } from "@frontmcp/sdk";
15
15
 
16
16
  // libs/adapters/src/openapi/openapi-spec-poller.ts
17
+ import { normalizeSsrfOptions, safeFetch } from "mcp-from-openapi";
17
18
  import { sha256Hex } from "@frontmcp/utils";
18
19
 
19
20
  // libs/adapters/src/openapi/openapi.errors.ts
@@ -39,6 +40,8 @@ var OpenApiSpecPoller = class {
39
40
  retry;
40
41
  unhealthyThreshold;
41
42
  headers;
43
+ ssrf;
44
+ followRedirects;
42
45
  callbacks;
43
46
  intervalTimer = null;
44
47
  lastHash = null;
@@ -56,6 +59,8 @@ var OpenApiSpecPoller = class {
56
59
  this.retry = { ...DEFAULT_RETRY, ...options.retry };
57
60
  this.unhealthyThreshold = options.unhealthyThreshold ?? 3;
58
61
  this.headers = options.headers ?? {};
62
+ this.ssrf = options.ssrf ?? normalizeSsrfOptions(void 0);
63
+ this.followRedirects = options.followRedirects ?? false;
59
64
  this.callbacks = callbacks;
60
65
  }
61
66
  /**
@@ -143,35 +148,31 @@ var OpenApiSpecPoller = class {
143
148
  headers["If-Modified-Since"] = this.lastModified;
144
149
  }
145
150
  }
146
- const controller = new AbortController();
147
- const timeout = setTimeout(() => controller.abort(), this.fetchTimeoutMs);
148
- try {
149
- const response = await fetch(this.url, {
150
- headers,
151
- signal: controller.signal
152
- });
153
- if (response.status === 304) {
154
- this.callbacks.onUnchanged?.();
155
- return;
156
- }
157
- if (!response.ok) {
158
- throw new OpenAPIFetchError(this.url, response.status, response.statusText);
159
- }
160
- const etag = response.headers.get("etag");
161
- const lastModified = response.headers.get("last-modified");
162
- if (etag) this.lastEtag = etag;
163
- if (lastModified) this.lastModified = lastModified;
164
- const body = await response.text();
165
- const hash = sha256Hex(body);
166
- if (this.lastHash && this.lastHash === hash) {
167
- this.callbacks.onUnchanged?.();
168
- return;
169
- }
170
- this.lastHash = hash;
171
- this.callbacks.onChanged?.(body, hash);
172
- } finally {
173
- clearTimeout(timeout);
174
- }
151
+ const response = await safeFetch(this.url, {
152
+ headers,
153
+ timeoutMs: this.fetchTimeoutMs,
154
+ followRedirects: this.followRedirects,
155
+ ssrf: this.ssrf
156
+ });
157
+ if (response.status === 304) {
158
+ this.callbacks.onUnchanged?.();
159
+ return;
160
+ }
161
+ if (!response.ok) {
162
+ throw new OpenAPIFetchError(this.url, response.status, response.statusText);
163
+ }
164
+ const etag = response.headers.get("etag");
165
+ const lastModified = response.headers.get("last-modified");
166
+ if (etag) this.lastEtag = etag;
167
+ if (lastModified) this.lastModified = lastModified;
168
+ const body = await response.text();
169
+ const hash = sha256Hex(body);
170
+ if (this.lastHash && this.lastHash === hash) {
171
+ this.callbacks.onUnchanged?.();
172
+ return;
173
+ }
174
+ this.lastHash = hash;
175
+ this.callbacks.onChanged?.(body, hash);
175
176
  }
176
177
  /**
177
178
  * Dispose the poller and release resources.
@@ -1741,7 +1742,12 @@ ${this.formatSchemaAsSummary(schema)}`;
1741
1742
  if (this.poller) return;
1742
1743
  const polling = this.options.polling;
1743
1744
  if (!polling?.enabled || !("url" in this.options)) return;
1744
- this.poller = new OpenApiSpecPoller(this.options.url, polling, {
1745
+ const pollingOptions = {
1746
+ ...polling,
1747
+ ssrf: normalizeSsrfOptions2(this.resolveRefResolution()),
1748
+ followRedirects: this.options.loadOptions?.followRedirects ?? false
1749
+ };
1750
+ this.poller = new OpenApiSpecPoller(this.options.url, pollingOptions, {
1745
1751
  onChanged: (_spec, _hash) => {
1746
1752
  this.rebuildChain = this.rebuildChain.then(async () => {
1747
1753
  const previousGenerator = this.generator;
package/esm/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@frontmcp/adapters",
3
- "version": "1.5.4",
3
+ "version": "1.5.6",
4
4
  "description": "Adapters for the FrontMCP framework",
5
5
  "author": "AgentFront <info@agentfront.dev>",
6
6
  "homepage": "https://docs.agentfront.dev",
@@ -64,15 +64,15 @@
64
64
  "node": ">=24.0.0"
65
65
  },
66
66
  "dependencies": {
67
- "@frontmcp/auth": "1.5.4",
68
- "@frontmcp/di": "1.5.4",
69
- "@frontmcp/sdk": "1.5.4",
70
- "@frontmcp/utils": "1.5.4",
67
+ "@frontmcp/auth": "1.5.6",
68
+ "@frontmcp/di": "1.5.6",
69
+ "@frontmcp/sdk": "1.5.6",
70
+ "@frontmcp/utils": "1.5.6",
71
71
  "js-yaml": "^4.1.0",
72
- "mcp-from-openapi": "2.5.0",
72
+ "mcp-from-openapi": "2.5.1",
73
73
  "openapi-types": "^12.1.3"
74
74
  },
75
75
  "peerDependencies": {
76
- "@frontmcp/lazy-zod": "1.5.4"
76
+ "@frontmcp/lazy-zod": "1.5.6"
77
77
  }
78
78
  }
package/index.js CHANGED
@@ -45,10 +45,11 @@ __export(index_exports, {
45
45
  module.exports = __toCommonJS(index_exports);
46
46
 
47
47
  // libs/adapters/src/openapi/openapi.adapter.ts
48
- var import_mcp_from_openapi2 = require("mcp-from-openapi");
48
+ var import_mcp_from_openapi3 = require("mcp-from-openapi");
49
49
  var import_sdk4 = require("@frontmcp/sdk");
50
50
 
51
51
  // libs/adapters/src/openapi/openapi-spec-poller.ts
52
+ var import_mcp_from_openapi = require("mcp-from-openapi");
52
53
  var import_utils = require("@frontmcp/utils");
53
54
 
54
55
  // libs/adapters/src/openapi/openapi.errors.ts
@@ -74,6 +75,8 @@ var OpenApiSpecPoller = class {
74
75
  retry;
75
76
  unhealthyThreshold;
76
77
  headers;
78
+ ssrf;
79
+ followRedirects;
77
80
  callbacks;
78
81
  intervalTimer = null;
79
82
  lastHash = null;
@@ -91,6 +94,8 @@ var OpenApiSpecPoller = class {
91
94
  this.retry = { ...DEFAULT_RETRY, ...options.retry };
92
95
  this.unhealthyThreshold = options.unhealthyThreshold ?? 3;
93
96
  this.headers = options.headers ?? {};
97
+ this.ssrf = options.ssrf ?? (0, import_mcp_from_openapi.normalizeSsrfOptions)(void 0);
98
+ this.followRedirects = options.followRedirects ?? false;
94
99
  this.callbacks = callbacks;
95
100
  }
96
101
  /**
@@ -178,35 +183,31 @@ var OpenApiSpecPoller = class {
178
183
  headers["If-Modified-Since"] = this.lastModified;
179
184
  }
180
185
  }
181
- const controller = new AbortController();
182
- const timeout = setTimeout(() => controller.abort(), this.fetchTimeoutMs);
183
- try {
184
- const response = await fetch(this.url, {
185
- headers,
186
- signal: controller.signal
187
- });
188
- if (response.status === 304) {
189
- this.callbacks.onUnchanged?.();
190
- return;
191
- }
192
- if (!response.ok) {
193
- throw new OpenAPIFetchError(this.url, response.status, response.statusText);
194
- }
195
- const etag = response.headers.get("etag");
196
- const lastModified = response.headers.get("last-modified");
197
- if (etag) this.lastEtag = etag;
198
- if (lastModified) this.lastModified = lastModified;
199
- const body = await response.text();
200
- const hash = (0, import_utils.sha256Hex)(body);
201
- if (this.lastHash && this.lastHash === hash) {
202
- this.callbacks.onUnchanged?.();
203
- return;
204
- }
205
- this.lastHash = hash;
206
- this.callbacks.onChanged?.(body, hash);
207
- } finally {
208
- clearTimeout(timeout);
209
- }
186
+ const response = await (0, import_mcp_from_openapi.safeFetch)(this.url, {
187
+ headers,
188
+ timeoutMs: this.fetchTimeoutMs,
189
+ followRedirects: this.followRedirects,
190
+ ssrf: this.ssrf
191
+ });
192
+ if (response.status === 304) {
193
+ this.callbacks.onUnchanged?.();
194
+ return;
195
+ }
196
+ if (!response.ok) {
197
+ throw new OpenAPIFetchError(this.url, response.status, response.statusText);
198
+ }
199
+ const etag = response.headers.get("etag");
200
+ const lastModified = response.headers.get("last-modified");
201
+ if (etag) this.lastEtag = etag;
202
+ if (lastModified) this.lastModified = lastModified;
203
+ const body = await response.text();
204
+ const hash = (0, import_utils.sha256Hex)(body);
205
+ if (this.lastHash && this.lastHash === hash) {
206
+ this.callbacks.onUnchanged?.();
207
+ return;
208
+ }
209
+ this.lastHash = hash;
210
+ this.callbacks.onChanged?.(body, hash);
210
211
  }
211
212
  /**
212
213
  * Dispose the poller and release resources.
@@ -217,13 +218,13 @@ var OpenApiSpecPoller = class {
217
218
  };
218
219
 
219
220
  // libs/adapters/src/openapi/openapi.security.ts
220
- var import_mcp_from_openapi = require("mcp-from-openapi");
221
+ var import_mcp_from_openapi2 = require("mcp-from-openapi");
221
222
  async function createSecurityContextFromAuth(tool2, ctx, options) {
222
223
  if (options.securityResolver) {
223
224
  return await options.securityResolver(tool2, ctx);
224
225
  }
225
226
  if (options.authProviderMapper) {
226
- const context = (0, import_mcp_from_openapi.createSecurityContext)({});
227
+ const context = (0, import_mcp_from_openapi2.createSecurityContext)({});
227
228
  const securitySchemes = /* @__PURE__ */ new Set();
228
229
  for (const mapper of tool2.mapper) {
229
230
  if (mapper.security?.scheme) {
@@ -287,9 +288,9 @@ async function createSecurityContextFromAuth(tool2, ctx, options) {
287
288
  return context;
288
289
  }
289
290
  if (options.staticAuth) {
290
- return (0, import_mcp_from_openapi.createSecurityContext)(options.staticAuth);
291
+ return (0, import_mcp_from_openapi2.createSecurityContext)(options.staticAuth);
291
292
  }
292
- return (0, import_mcp_from_openapi.createSecurityContext)({
293
+ return (0, import_mcp_from_openapi2.createSecurityContext)({
293
294
  jwt: ctx.authInfo?.token
294
295
  });
295
296
  }
@@ -372,7 +373,7 @@ function validateSecurityConfiguration(tools, options) {
372
373
  return result;
373
374
  }
374
375
  async function resolveToolSecurity(tool2, ctx, options) {
375
- const securityResolver = new import_mcp_from_openapi.SecurityResolver();
376
+ const securityResolver = new import_mcp_from_openapi2.SecurityResolver();
376
377
  const securityContext = await createSecurityContextFromAuth(tool2, ctx, options);
377
378
  const hasAuth = securityContext.jwt || securityContext.apiKey || securityContext.basic || securityContext.oauth2Token || securityContext.apiKeys && Object.keys(securityContext.apiKeys).length > 0 || securityContext.customHeaders && Object.keys(securityContext.customHeaders).length > 0;
378
379
  const requiresSecurity = tool2.mapper.some((m) => m.security && m.required === true);
@@ -1230,7 +1231,7 @@ Add one of the following to your adapter configuration:
1230
1231
  async initializeGenerator() {
1231
1232
  const refResolution = this.resolveRefResolution();
1232
1233
  if ("url" in this.options) {
1233
- return await import_mcp_from_openapi2.OpenAPIToolGenerator.fromURL(this.options.url, {
1234
+ return await import_mcp_from_openapi3.OpenAPIToolGenerator.fromURL(this.options.url, {
1234
1235
  baseUrl: this.options.baseUrl,
1235
1236
  validate: this.options.loadOptions?.validate ?? true,
1236
1237
  dereference: this.options.loadOptions?.dereference ?? true,
@@ -1243,7 +1244,7 @@ Add one of the following to your adapter configuration:
1243
1244
  refResolution
1244
1245
  });
1245
1246
  } else if ("spec" in this.options) {
1246
- return await import_mcp_from_openapi2.OpenAPIToolGenerator.fromJSON(this.options.spec, {
1247
+ return await import_mcp_from_openapi3.OpenAPIToolGenerator.fromJSON(this.options.spec, {
1247
1248
  baseUrl: this.options.baseUrl,
1248
1249
  validate: this.options.loadOptions?.validate ?? true,
1249
1250
  dereference: this.options.loadOptions?.dereference ?? true,
@@ -1776,7 +1777,12 @@ ${this.formatSchemaAsSummary(schema)}`;
1776
1777
  if (this.poller) return;
1777
1778
  const polling = this.options.polling;
1778
1779
  if (!polling?.enabled || !("url" in this.options)) return;
1779
- this.poller = new OpenApiSpecPoller(this.options.url, polling, {
1780
+ const pollingOptions = {
1781
+ ...polling,
1782
+ ssrf: (0, import_mcp_from_openapi3.normalizeSsrfOptions)(this.resolveRefResolution()),
1783
+ followRedirects: this.options.loadOptions?.followRedirects ?? false
1784
+ };
1785
+ this.poller = new OpenApiSpecPoller(this.options.url, pollingOptions, {
1780
1786
  onChanged: (_spec, _hash) => {
1781
1787
  this.rebuildChain = this.rebuildChain.then(async () => {
1782
1788
  const previousGenerator = this.generator;
package/openapi/index.js CHANGED
@@ -45,10 +45,11 @@ __export(openapi_exports, {
45
45
  module.exports = __toCommonJS(openapi_exports);
46
46
 
47
47
  // libs/adapters/src/openapi/openapi.adapter.ts
48
- var import_mcp_from_openapi2 = require("mcp-from-openapi");
48
+ var import_mcp_from_openapi3 = require("mcp-from-openapi");
49
49
  var import_sdk4 = require("@frontmcp/sdk");
50
50
 
51
51
  // libs/adapters/src/openapi/openapi-spec-poller.ts
52
+ var import_mcp_from_openapi = require("mcp-from-openapi");
52
53
  var import_utils = require("@frontmcp/utils");
53
54
 
54
55
  // libs/adapters/src/openapi/openapi.errors.ts
@@ -74,6 +75,8 @@ var OpenApiSpecPoller = class {
74
75
  retry;
75
76
  unhealthyThreshold;
76
77
  headers;
78
+ ssrf;
79
+ followRedirects;
77
80
  callbacks;
78
81
  intervalTimer = null;
79
82
  lastHash = null;
@@ -91,6 +94,8 @@ var OpenApiSpecPoller = class {
91
94
  this.retry = { ...DEFAULT_RETRY, ...options.retry };
92
95
  this.unhealthyThreshold = options.unhealthyThreshold ?? 3;
93
96
  this.headers = options.headers ?? {};
97
+ this.ssrf = options.ssrf ?? (0, import_mcp_from_openapi.normalizeSsrfOptions)(void 0);
98
+ this.followRedirects = options.followRedirects ?? false;
94
99
  this.callbacks = callbacks;
95
100
  }
96
101
  /**
@@ -178,35 +183,31 @@ var OpenApiSpecPoller = class {
178
183
  headers["If-Modified-Since"] = this.lastModified;
179
184
  }
180
185
  }
181
- const controller = new AbortController();
182
- const timeout = setTimeout(() => controller.abort(), this.fetchTimeoutMs);
183
- try {
184
- const response = await fetch(this.url, {
185
- headers,
186
- signal: controller.signal
187
- });
188
- if (response.status === 304) {
189
- this.callbacks.onUnchanged?.();
190
- return;
191
- }
192
- if (!response.ok) {
193
- throw new OpenAPIFetchError(this.url, response.status, response.statusText);
194
- }
195
- const etag = response.headers.get("etag");
196
- const lastModified = response.headers.get("last-modified");
197
- if (etag) this.lastEtag = etag;
198
- if (lastModified) this.lastModified = lastModified;
199
- const body = await response.text();
200
- const hash = (0, import_utils.sha256Hex)(body);
201
- if (this.lastHash && this.lastHash === hash) {
202
- this.callbacks.onUnchanged?.();
203
- return;
204
- }
205
- this.lastHash = hash;
206
- this.callbacks.onChanged?.(body, hash);
207
- } finally {
208
- clearTimeout(timeout);
209
- }
186
+ const response = await (0, import_mcp_from_openapi.safeFetch)(this.url, {
187
+ headers,
188
+ timeoutMs: this.fetchTimeoutMs,
189
+ followRedirects: this.followRedirects,
190
+ ssrf: this.ssrf
191
+ });
192
+ if (response.status === 304) {
193
+ this.callbacks.onUnchanged?.();
194
+ return;
195
+ }
196
+ if (!response.ok) {
197
+ throw new OpenAPIFetchError(this.url, response.status, response.statusText);
198
+ }
199
+ const etag = response.headers.get("etag");
200
+ const lastModified = response.headers.get("last-modified");
201
+ if (etag) this.lastEtag = etag;
202
+ if (lastModified) this.lastModified = lastModified;
203
+ const body = await response.text();
204
+ const hash = (0, import_utils.sha256Hex)(body);
205
+ if (this.lastHash && this.lastHash === hash) {
206
+ this.callbacks.onUnchanged?.();
207
+ return;
208
+ }
209
+ this.lastHash = hash;
210
+ this.callbacks.onChanged?.(body, hash);
210
211
  }
211
212
  /**
212
213
  * Dispose the poller and release resources.
@@ -217,13 +218,13 @@ var OpenApiSpecPoller = class {
217
218
  };
218
219
 
219
220
  // libs/adapters/src/openapi/openapi.security.ts
220
- var import_mcp_from_openapi = require("mcp-from-openapi");
221
+ var import_mcp_from_openapi2 = require("mcp-from-openapi");
221
222
  async function createSecurityContextFromAuth(tool2, ctx, options) {
222
223
  if (options.securityResolver) {
223
224
  return await options.securityResolver(tool2, ctx);
224
225
  }
225
226
  if (options.authProviderMapper) {
226
- const context = (0, import_mcp_from_openapi.createSecurityContext)({});
227
+ const context = (0, import_mcp_from_openapi2.createSecurityContext)({});
227
228
  const securitySchemes = /* @__PURE__ */ new Set();
228
229
  for (const mapper of tool2.mapper) {
229
230
  if (mapper.security?.scheme) {
@@ -287,9 +288,9 @@ async function createSecurityContextFromAuth(tool2, ctx, options) {
287
288
  return context;
288
289
  }
289
290
  if (options.staticAuth) {
290
- return (0, import_mcp_from_openapi.createSecurityContext)(options.staticAuth);
291
+ return (0, import_mcp_from_openapi2.createSecurityContext)(options.staticAuth);
291
292
  }
292
- return (0, import_mcp_from_openapi.createSecurityContext)({
293
+ return (0, import_mcp_from_openapi2.createSecurityContext)({
293
294
  jwt: ctx.authInfo?.token
294
295
  });
295
296
  }
@@ -372,7 +373,7 @@ function validateSecurityConfiguration(tools, options) {
372
373
  return result;
373
374
  }
374
375
  async function resolveToolSecurity(tool2, ctx, options) {
375
- const securityResolver = new import_mcp_from_openapi.SecurityResolver();
376
+ const securityResolver = new import_mcp_from_openapi2.SecurityResolver();
376
377
  const securityContext = await createSecurityContextFromAuth(tool2, ctx, options);
377
378
  const hasAuth = securityContext.jwt || securityContext.apiKey || securityContext.basic || securityContext.oauth2Token || securityContext.apiKeys && Object.keys(securityContext.apiKeys).length > 0 || securityContext.customHeaders && Object.keys(securityContext.customHeaders).length > 0;
378
379
  const requiresSecurity = tool2.mapper.some((m) => m.security && m.required === true);
@@ -1230,7 +1231,7 @@ Add one of the following to your adapter configuration:
1230
1231
  async initializeGenerator() {
1231
1232
  const refResolution = this.resolveRefResolution();
1232
1233
  if ("url" in this.options) {
1233
- return await import_mcp_from_openapi2.OpenAPIToolGenerator.fromURL(this.options.url, {
1234
+ return await import_mcp_from_openapi3.OpenAPIToolGenerator.fromURL(this.options.url, {
1234
1235
  baseUrl: this.options.baseUrl,
1235
1236
  validate: this.options.loadOptions?.validate ?? true,
1236
1237
  dereference: this.options.loadOptions?.dereference ?? true,
@@ -1243,7 +1244,7 @@ Add one of the following to your adapter configuration:
1243
1244
  refResolution
1244
1245
  });
1245
1246
  } else if ("spec" in this.options) {
1246
- return await import_mcp_from_openapi2.OpenAPIToolGenerator.fromJSON(this.options.spec, {
1247
+ return await import_mcp_from_openapi3.OpenAPIToolGenerator.fromJSON(this.options.spec, {
1247
1248
  baseUrl: this.options.baseUrl,
1248
1249
  validate: this.options.loadOptions?.validate ?? true,
1249
1250
  dereference: this.options.loadOptions?.dereference ?? true,
@@ -1776,7 +1777,12 @@ ${this.formatSchemaAsSummary(schema)}`;
1776
1777
  if (this.poller) return;
1777
1778
  const polling = this.options.polling;
1778
1779
  if (!polling?.enabled || !("url" in this.options)) return;
1779
- this.poller = new OpenApiSpecPoller(this.options.url, polling, {
1780
+ const pollingOptions = {
1781
+ ...polling,
1782
+ ssrf: (0, import_mcp_from_openapi3.normalizeSsrfOptions)(this.resolveRefResolution()),
1783
+ followRedirects: this.options.loadOptions?.followRedirects ?? false
1784
+ };
1785
+ this.poller = new OpenApiSpecPoller(this.options.url, pollingOptions, {
1780
1786
  onChanged: (_spec, _hash) => {
1781
1787
  this.rebuildChain = this.rebuildChain.then(async () => {
1782
1788
  const previousGenerator = this.generator;
@@ -7,7 +7,7 @@
7
7
  *
8
8
  * @packageDocumentation
9
9
  */
10
- import type { SpecPollerOptions, SpecPollerCallbacks, SpecPollerStats } from './openapi-spec-poller.types';
10
+ import type { SpecPollerCallbacks, SpecPollerOptions, SpecPollerStats } from './openapi-spec-poller.types';
11
11
  /**
12
12
  * Polls an OpenAPI spec URL for changes using content-hash and ETag detection.
13
13
  * Follows the callback-based emitter pattern (like ToolEmitter).
@@ -20,6 +20,8 @@ export declare class OpenApiSpecPoller {
20
20
  private readonly retry;
21
21
  private readonly unhealthyThreshold;
22
22
  private readonly headers;
23
+ private readonly ssrf;
24
+ private readonly followRedirects;
23
25
  private readonly callbacks;
24
26
  private intervalTimer;
25
27
  private lastHash;
@@ -1 +1 @@
1
- {"version":3,"file":"openapi-spec-poller.d.ts","sourceRoot":"","sources":["../../src/openapi/openapi-spec-poller.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EACV,iBAAiB,EACjB,mBAAmB,EACnB,eAAe,EAGhB,MAAM,6BAA6B,CAAC;AAUrC;;;GAGG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAmC;IACnE,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAkC;IACxD,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAS;IAC5C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyB;IACjD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAsB;IAEhD,OAAO,CAAC,aAAa,CAA+C;IACpE,OAAO,CAAC,QAAQ,CAAuB;IACvC,OAAO,CAAC,QAAQ,CAAuB;IACvC,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,mBAAmB,CAAK;IAChC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,MAAM,CAAiC;gBAEnC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,iBAAsB,EAAE,SAAS,GAAE,mBAAwB;IAW7F;;OAEG;IACH,KAAK,IAAI,IAAI;IAWb;;OAEG;IACH,IAAI,IAAI,IAAI;IAOZ;;OAEG;IACH,QAAQ,IAAI,eAAe;IAS3B;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;YAWb,cAAc;YAoCd,OAAO;IAqDrB;;OAEG;IACH,OAAO,IAAI,IAAI;CAGhB"}
1
+ {"version":3,"file":"openapi-spec-poller.d.ts","sourceRoot":"","sources":["../../src/openapi/openapi-spec-poller.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,OAAO,KAAK,EAEV,mBAAmB,EACnB,iBAAiB,EAEjB,eAAe,EAChB,MAAM,6BAA6B,CAAC;AAUrC;;;GAGG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAmC;IACnE,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAkC;IACxD,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAS;IAC5C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyB;IACjD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAsB;IAC3C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAU;IAC1C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAsB;IAEhD,OAAO,CAAC,aAAa,CAA+C;IACpE,OAAO,CAAC,QAAQ,CAAuB;IACvC,OAAO,CAAC,QAAQ,CAAuB;IACvC,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,mBAAmB,CAAK;IAChC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,MAAM,CAAiC;gBAEnC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,iBAAsB,EAAE,SAAS,GAAE,mBAAwB;IAa7F;;OAEG;IACH,KAAK,IAAI,IAAI;IAWb;;OAEG;IACH,IAAI,IAAI,IAAI;IAOZ;;OAEG;IACH,QAAQ,IAAI,eAAe;IAS3B;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;YAWb,cAAc;YAoCd,OAAO;IAiDrB;;OAEG;IACH,OAAO,IAAI,IAAI;CAGhB"}
@@ -5,6 +5,7 @@
5
5
  *
6
6
  * @packageDocumentation
7
7
  */
8
+ import type { ResolvedSsrfOptions } from 'mcp-from-openapi';
8
9
  /**
9
10
  * Change detection strategy.
10
11
  */
@@ -42,6 +43,18 @@ export interface SpecPollerOptions {
42
43
  unhealthyThreshold?: number;
43
44
  /** Additional headers for fetch requests */
44
45
  headers?: Record<string, string>;
46
+ /**
47
+ * SSRF policy applied to the spec URL on every poll, matching the guard used
48
+ * for the initial `OPENAPIToolGenerator.fromURL()` load. The adapter injects
49
+ * this from `loadOptions.refResolution`; standalone callers may set it
50
+ * directly. Defaults to blocking internal/private addresses.
51
+ */
52
+ ssrf?: ResolvedSsrfOptions;
53
+ /**
54
+ * Follow (and re-validate) redirect hops when polling. Mirrors the adapter's
55
+ * spec-load redirect policy. @default false
56
+ */
57
+ followRedirects?: boolean;
45
58
  }
46
59
  /**
47
60
  * Callback types for spec poller events.
@@ -1 +1 @@
1
- {"version":3,"file":"openapi-spec-poller.types.d.ts","sourceRoot":"","sources":["../../src/openapi/openapi-spec-poller.types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG,cAAc,GAAG,MAAM,GAAG,MAAM,CAAC;AAEnE;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,0DAA0D;IAC1D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,2DAA2D;IAC3D,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,yDAAyD;IACzD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,oCAAoC;IACpC,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG,SAAS,GAAG,WAAW,GAAG,SAAS,CAAC;AAErE;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,mDAAmD;IACnD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mDAAmD;IACnD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gDAAgD;IAChD,eAAe,CAAC,EAAE,mBAAmB,CAAC;IACtC,0BAA0B;IAC1B,KAAK,CAAC,EAAE,qBAAqB,CAAC;IAC9B,yEAAyE;IACzE,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,4CAA4C;IAC5C,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,+CAA+C;IAC/C,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,0CAA0C;IAC1C,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB,2BAA2B;IAC3B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC,2CAA2C;IAC3C,WAAW,CAAC,EAAE,CAAC,mBAAmB,EAAE,MAAM,KAAK,IAAI,CAAC;IACpD,uDAAuD;IACvD,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,2BAA2B;IAC3B,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,qCAAqC;IACrC,mBAAmB,EAAE,MAAM,CAAC;IAC5B,oBAAoB;IACpB,MAAM,EAAE,kBAAkB,CAAC;IAC3B,8CAA8C;IAC9C,SAAS,EAAE,OAAO,CAAC;CACpB"}
1
+ {"version":3,"file":"openapi-spec-poller.types.d.ts","sourceRoot":"","sources":["../../src/openapi/openapi-spec-poller.types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAE5D;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG,cAAc,GAAG,MAAM,GAAG,MAAM,CAAC;AAEnE;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,0DAA0D;IAC1D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,2DAA2D;IAC3D,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,yDAAyD;IACzD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,oCAAoC;IACpC,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG,SAAS,GAAG,WAAW,GAAG,SAAS,CAAC;AAErE;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,mDAAmD;IACnD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mDAAmD;IACnD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gDAAgD;IAChD,eAAe,CAAC,EAAE,mBAAmB,CAAC;IACtC,0BAA0B;IAC1B,KAAK,CAAC,EAAE,qBAAqB,CAAC;IAC9B,yEAAyE;IACzE,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,4CAA4C;IAC5C,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC;;;;;OAKG;IACH,IAAI,CAAC,EAAE,mBAAmB,CAAC;IAC3B;;;OAGG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,+CAA+C;IAC/C,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,0CAA0C;IAC1C,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB,2BAA2B;IAC3B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC,2CAA2C;IAC3C,WAAW,CAAC,EAAE,CAAC,mBAAmB,EAAE,MAAM,KAAK,IAAI,CAAC;IACpD,uDAAuD;IACvD,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,2BAA2B;IAC3B,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,qCAAqC;IACrC,mBAAmB,EAAE,MAAM,CAAC;IAC5B,oBAAoB;IACpB,MAAM,EAAE,kBAAkB,CAAC;IAC3B,8CAA8C;IAC9C,SAAS,EAAE,OAAO,CAAC;CACpB"}
@@ -1 +1 @@
1
- {"version":3,"file":"openapi.adapter.d.ts","sourceRoot":"","sources":["../../src/openapi/openapi.adapter.ts"],"names":[],"mappings":"AAEA,OAAO,EAAW,cAAc,EAAE,KAAK,uBAAuB,EAAE,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;AAK3G,OAAO,EAIL,KAAK,qBAAqB,EAQ3B,MAAM,iBAAiB,CAAC;AAwBzB,MAAM,CAAC,OAAO,OAAO,cAAe,SAAQ,cAAc,CAAC,qBAAqB,CAAC;IAC/E,OAAO,CAAC,SAAS,CAAC,CAAuB;IACzC,OAAO,CAAC,MAAM,CAAiB;IACxB,OAAO,EAAE,qBAAqB,CAAC;IACtC,OAAO,CAAC,MAAM,CAAkC;IAChD,OAAO,CAAC,eAAe,CAA0D;IACjF,OAAO,CAAC,YAAY,CAAoC;gBAE5C,OAAO,EAAE,qBAAqB;IAc1C;;OAEG;IACH,SAAS,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI;IAIjC,KAAK,IAAI,OAAO,CAAC,uBAAuB,CAAC;IAuI/C;;;OAGG;IACH;;;;;;;;;;OAUG;IACH,OAAO,CAAC,oBAAoB;YAId,mBAAmB;IA4BjC;;;OAGG;IACH,OAAO,CAAC,oBAAoB;IA0C5B;;;OAGG;IACH,OAAO,CAAC,cAAc;IAMtB;;;OAGG;IACH,OAAO,CAAC,qBAAqB;IA6D7B;;;OAGG;IACH,OAAO,CAAC,mBAAmB;IAsC3B;;;OAGG;IACH,OAAO,CAAC,wBAAwB;IAwBhC;;;;;OAKG;IACH,OAAO,CAAC,oBAAoB;IAoD5B;;;;OAIG;IACH,OAAO,CAAC,qBAAqB;IA2D7B;;;;OAIG;IACH,OAAO,CAAC,qBAAqB;IA0C7B;;;OAGG;IACH,OAAO,CAAC,2BAA2B;IAkBnC;;;OAGG;IACH,OAAO,CAAC,4BAA4B;IAoBpC;;;;OAIG;YACW,wBAAwB;IAiFtC;;;OAGG;IACH,OAAO,CAAC,0BAA0B;IAgBlC;;;OAGG;IACH,OAAO,CAAC,0CAA0C;IA+BlD;;;OAGG;IACH,OAAO,CAAC,2CAA2C;IAyCnD;;;OAGG;IACH,OAAO,CAAC,qBAAqB;IAuB7B;;;OAGG;IACH,OAAO,CAAC,mBAAmB;IAiB3B;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,uBAAuB,KAAK,IAAI,GAAG,MAAM,IAAI;IAO3E;;;;OAIG;IACH,YAAY,IAAI,IAAI;IAsCpB;;OAEG;IACH,WAAW,IAAI,IAAI;CAOpB"}
1
+ {"version":3,"file":"openapi.adapter.d.ts","sourceRoot":"","sources":["../../src/openapi/openapi.adapter.ts"],"names":[],"mappings":"AAEA,OAAO,EAAW,cAAc,EAAE,KAAK,uBAAuB,EAAE,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;AAK3G,OAAO,EAIL,KAAK,qBAAqB,EAQ3B,MAAM,iBAAiB,CAAC;AAwBzB,MAAM,CAAC,OAAO,OAAO,cAAe,SAAQ,cAAc,CAAC,qBAAqB,CAAC;IAC/E,OAAO,CAAC,SAAS,CAAC,CAAuB;IACzC,OAAO,CAAC,MAAM,CAAiB;IACxB,OAAO,EAAE,qBAAqB,CAAC;IACtC,OAAO,CAAC,MAAM,CAAkC;IAChD,OAAO,CAAC,eAAe,CAA0D;IACjF,OAAO,CAAC,YAAY,CAAoC;gBAE5C,OAAO,EAAE,qBAAqB;IAc1C;;OAEG;IACH,SAAS,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI;IAIjC,KAAK,IAAI,OAAO,CAAC,uBAAuB,CAAC;IAuI/C;;;OAGG;IACH;;;;;;;;;;OAUG;IACH,OAAO,CAAC,oBAAoB;YAId,mBAAmB;IA4BjC;;;OAGG;IACH,OAAO,CAAC,oBAAoB;IA0C5B;;;OAGG;IACH,OAAO,CAAC,cAAc;IAMtB;;;OAGG;IACH,OAAO,CAAC,qBAAqB;IA6D7B;;;OAGG;IACH,OAAO,CAAC,mBAAmB;IAsC3B;;;OAGG;IACH,OAAO,CAAC,wBAAwB;IAwBhC;;;;;OAKG;IACH,OAAO,CAAC,oBAAoB;IAoD5B;;;;OAIG;IACH,OAAO,CAAC,qBAAqB;IA2D7B;;;;OAIG;IACH,OAAO,CAAC,qBAAqB;IA0C7B;;;OAGG;IACH,OAAO,CAAC,2BAA2B;IAkBnC;;;OAGG;IACH,OAAO,CAAC,4BAA4B;IAoBpC;;;;OAIG;YACW,wBAAwB;IAiFtC;;;OAGG;IACH,OAAO,CAAC,0BAA0B;IAgBlC;;;OAGG;IACH,OAAO,CAAC,0CAA0C;IA+BlD;;;OAGG;IACH,OAAO,CAAC,2CAA2C;IAyCnD;;;OAGG;IACH,OAAO,CAAC,qBAAqB;IAuB7B;;;OAGG;IACH,OAAO,CAAC,mBAAmB;IAiB3B;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,uBAAuB,KAAK,IAAI,GAAG,MAAM,IAAI;IAO3E;;;;OAIG;IACH,YAAY,IAAI,IAAI;IA6CpB;;OAEG;IACH,WAAW,IAAI,IAAI;CAOpB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@frontmcp/adapters",
3
- "version": "1.5.4",
3
+ "version": "1.5.6",
4
4
  "description": "Adapters for the FrontMCP framework",
5
5
  "author": "AgentFront <info@agentfront.dev>",
6
6
  "homepage": "https://docs.agentfront.dev",
@@ -64,15 +64,15 @@
64
64
  "node": ">=24.0.0"
65
65
  },
66
66
  "dependencies": {
67
- "@frontmcp/auth": "1.5.4",
68
- "@frontmcp/di": "1.5.4",
69
- "@frontmcp/sdk": "1.5.4",
70
- "@frontmcp/utils": "1.5.4",
67
+ "@frontmcp/auth": "1.5.6",
68
+ "@frontmcp/di": "1.5.6",
69
+ "@frontmcp/sdk": "1.5.6",
70
+ "@frontmcp/utils": "1.5.6",
71
71
  "js-yaml": "^4.1.0",
72
- "mcp-from-openapi": "2.5.0",
72
+ "mcp-from-openapi": "2.5.1",
73
73
  "openapi-types": "^12.1.3"
74
74
  },
75
75
  "peerDependencies": {
76
- "@frontmcp/lazy-zod": "1.5.4"
76
+ "@frontmcp/lazy-zod": "1.5.6"
77
77
  }
78
78
  }