fastmcp 4.21.2 → 4.22.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.
Files changed (36) hide show
  1. package/README.md +12 -2
  2. package/dist/FastMCP.cjs +3 -3
  3. package/dist/FastMCP.d.cts +2 -2
  4. package/dist/FastMCP.d.ts +2 -2
  5. package/dist/FastMCP.js +2 -2
  6. package/dist/{OAuthProvider-C4idKF29.d.cts → OAuthProvider-BcDb5bOz.d.cts} +8 -1
  7. package/dist/{OAuthProvider-C4idKF29.d.ts → OAuthProvider-BcDb5bOz.d.ts} +8 -1
  8. package/dist/auth/index.cjs +2 -2
  9. package/dist/auth/index.d.cts +2 -2
  10. package/dist/auth/index.d.ts +2 -2
  11. package/dist/auth/index.js +1 -1
  12. package/dist/{chunk-C5VOVQPC.cjs → chunk-RN2Z26T4.cjs} +118 -16
  13. package/dist/chunk-RN2Z26T4.cjs.map +1 -0
  14. package/dist/{chunk-QMRS4ZLD.js → chunk-XFUILY54.js} +115 -13
  15. package/dist/chunk-XFUILY54.js.map +1 -0
  16. package/dist/{chunk-AR3LVWUF.js → chunk-XPKMA7DH.js} +22 -1
  17. package/dist/chunk-XPKMA7DH.js.map +1 -0
  18. package/dist/{chunk-GTPK7A57.cjs → chunk-YOBCXNFP.cjs} +22 -1
  19. package/dist/chunk-YOBCXNFP.cjs.map +1 -0
  20. package/dist/edge/index.cjs +15 -12
  21. package/dist/edge/index.cjs.map +1 -1
  22. package/dist/edge/index.js +7 -4
  23. package/dist/edge/index.js.map +1 -1
  24. package/dist/examples/custom-routes.cjs +3 -3
  25. package/dist/examples/custom-routes.js +2 -2
  26. package/dist/openapi/index.cjs +165 -149
  27. package/dist/openapi/index.cjs.map +1 -1
  28. package/dist/openapi/index.d.cts +5 -3
  29. package/dist/openapi/index.d.ts +5 -3
  30. package/dist/openapi/index.js +155 -139
  31. package/dist/openapi/index.js.map +1 -1
  32. package/package.json +2 -2
  33. package/dist/chunk-AR3LVWUF.js.map +0 -1
  34. package/dist/chunk-C5VOVQPC.cjs.map +0 -1
  35. package/dist/chunk-GTPK7A57.cjs.map +0 -1
  36. package/dist/chunk-QMRS4ZLD.js.map +0 -1
@@ -2,8 +2,8 @@
2
2
 
3
3
 
4
4
 
5
- var _chunkC5VOVQPCcjs = require('../chunk-C5VOVQPC.cjs');
6
- require('../chunk-GTPK7A57.cjs');
5
+ var _chunkRN2Z26T4cjs = require('../chunk-RN2Z26T4.cjs');
6
+ require('../chunk-YOBCXNFP.cjs');
7
7
  require('../chunk-O22SYZMC.cjs');
8
8
 
9
9
  // src/openapi/loadSpec.ts
@@ -91,7 +91,13 @@ async function executeRequest(options) {
91
91
  pathParams[mapping.name] = String(value);
92
92
  break;
93
93
  case "query":
94
- appendQueryValue(query, mapping.name, mapping.style, value);
94
+ appendQueryValue(
95
+ query,
96
+ mapping.name,
97
+ mapping.style,
98
+ value,
99
+ mapping.explode
100
+ );
95
101
  break;
96
102
  }
97
103
  }
@@ -123,7 +129,7 @@ async function executeRequest(options) {
123
129
  });
124
130
  const text = await response.text();
125
131
  if (!response.ok) {
126
- throw new (0, _chunkC5VOVQPCcjs.UserError)(
132
+ throw new (0, _chunkRN2Z26T4cjs.UserError)(
127
133
  `${options.route.method.toUpperCase()} ${path} failed with ${response.status}: ${text.slice(0, 2e3)}`
128
134
  );
129
135
  }
@@ -185,7 +191,7 @@ function appendBracketPairs(params, key, value) {
185
191
  }
186
192
  params.append(key, String(value));
187
193
  }
188
- function appendQueryValue(query, name, style, value) {
194
+ function appendQueryValue(query, name, style, value, explode) {
189
195
  if (style === "deepObject") {
190
196
  appendBracketPairs(query, name, value);
191
197
  return;
@@ -196,6 +202,10 @@ function appendQueryValue(query, name, style, value) {
196
202
  query.append(name, items.map(String).join(separator));
197
203
  return;
198
204
  }
205
+ if ((style === void 0 || style === "form") && explode === false && Array.isArray(value) && value.length > 0) {
206
+ query.append(name, value.map(String).join(","));
207
+ return;
208
+ }
199
209
  for (const item of Array.isArray(value) ? value : [value]) {
200
210
  query.append(name, String(item));
201
211
  }
@@ -221,123 +231,6 @@ async function resolveHeaders(headers) {
221
231
  return typeof headers === "function" ? await headers() : { ...headers };
222
232
  }
223
233
 
224
- // src/openapi/resourceMapping.ts
225
- function buildResourceMapping(route, name, parameterMap, requiredKeys) {
226
- const entries = Object.entries(parameterMap);
227
- if (entries.length === 0) {
228
- return { kind: "resource", uri: `openapi://${name}${route.path}` };
229
- }
230
- const required = new Set(_nullishCoalesce(requiredKeys, () => ( [])));
231
- const args = [];
232
- const queryKeys = [];
233
- let path = route.path;
234
- for (const [flatKey, mapping] of entries) {
235
- if (mapping.in === "path") {
236
- if (flatKey !== mapping.name) {
237
- path = path.replaceAll(`{${mapping.name}}`, `{${flatKey}}`);
238
- }
239
- } else {
240
- queryKeys.push(flatKey);
241
- }
242
- args.push({ name: flatKey, required: required.has(flatKey) });
243
- }
244
- const uriTemplate = `openapi://${name}${path}` + (queryKeys.length > 0 ? `{?${queryKeys.join(",")}}` : "");
245
- return { args, kind: "template", uriTemplate };
246
- }
247
- function isEligibleForResource(route) {
248
- return route.parameters.every((param) => {
249
- if (param.in === "header" || param.in === "cookie") {
250
- return false;
251
- }
252
- return _optionalChain([param, 'access', _11 => _11.schema, 'optionalAccess', _12 => _12.type]) !== "array";
253
- });
254
- }
255
-
256
- // src/openapi/routes.ts
257
- var HTTP_METHODS = ["get", "put", "post", "delete", "patch"];
258
- function extractRoutes(document) {
259
- const routes = [];
260
- for (const [path, rawPathItem] of Object.entries(_nullishCoalesce(document.paths, () => ( {})))) {
261
- const pathItem = resolvePathItem(document, rawPathItem);
262
- const pathLevelParams = (_nullishCoalesce(pathItem.parameters, () => ( []))).map(
263
- (param) => resolveRef(document, param)
264
- );
265
- for (const method of HTTP_METHODS) {
266
- const operation = pathItem[method];
267
- if (!operation) {
268
- continue;
269
- }
270
- const operationParams = (_nullishCoalesce(operation.parameters, () => ( []))).map(
271
- (param) => resolveRef(document, param)
272
- );
273
- routes.push({
274
- deprecated: _nullishCoalesce(operation.deprecated, () => ( false)),
275
- method,
276
- operationId: operation.operationId,
277
- parameters: mergeParameters(pathLevelParams, operationParams),
278
- path,
279
- requestBody: operation.requestBody ? resolveRef(document, operation.requestBody) : void 0,
280
- responses: resolveResponses(document, operation.responses),
281
- servers: [operation.servers, pathItem.servers, document.servers].find(
282
- (servers) => _optionalChain([servers, 'optionalAccess', _13 => _13.length])
283
- ),
284
- summary: operation.summary,
285
- tags: _nullishCoalesce(operation.tags, () => ( []))
286
- });
287
- }
288
- }
289
- return routes;
290
- }
291
- function mergeParameters(pathLevel, operationLevel) {
292
- const overridden = new Set(
293
- operationLevel.map((param) => `${param.in}:${param.name}`)
294
- );
295
- return [
296
- ...pathLevel.filter(
297
- (param) => !overridden.has(`${param.in}:${param.name}`)
298
- ),
299
- ...operationLevel
300
- ];
301
- }
302
- function resolvePathItem(document, pathItem) {
303
- const visited = /* @__PURE__ */ new Set();
304
- let resolved = pathItem;
305
- while (resolved.$ref && !visited.has(resolved.$ref)) {
306
- visited.add(resolved.$ref);
307
- const { $ref, ...siblings } = resolved;
308
- resolved = { ...resolveRef(document, { $ref }), ...siblings };
309
- }
310
- return resolved;
311
- }
312
- function resolveRef(document, value) {
313
- if (!value || typeof value !== "object" || !("$ref" in value)) {
314
- return value;
315
- }
316
- const pointer = value.$ref;
317
- if (!pointer.startsWith("#/")) {
318
- throw new Error(`Unexpected external $ref after bundling: ${pointer}`);
319
- }
320
- const segments = pointer.slice(2).split("/").map(
321
- (segment) => decodeURIComponent(segment.replaceAll("~1", "/").replaceAll("~0", "~"))
322
- );
323
- let node = document;
324
- for (const segment of segments) {
325
- node = _optionalChain([node, 'optionalAccess', _14 => _14[segment]]);
326
- }
327
- return node;
328
- }
329
- function resolveResponses(document, rawResponses) {
330
- if (!rawResponses) {
331
- return void 0;
332
- }
333
- return Object.fromEntries(
334
- Object.entries(rawResponses).map(([code, response]) => [
335
- code,
336
- resolveRef(document, response)
337
- ])
338
- );
339
- }
340
-
341
234
  // src/openapi/schemas.ts
342
235
  var SCHEMA_MAP_KEYS = /* @__PURE__ */ new Set([
343
236
  "$defs",
@@ -374,7 +267,12 @@ function buildFlatSchema(route, sharedDefs) {
374
267
  properties[key] = rewriteComponentRefs(
375
268
  _nullishCoalesce(param.schema, () => ( { type: "string" }))
376
269
  );
377
- parameterMap[key] = { in: param.in, name, style: param.style };
270
+ parameterMap[key] = {
271
+ explode: param.explode,
272
+ in: param.in,
273
+ name,
274
+ style: param.style
275
+ };
378
276
  if (param.in === "path" || param.required) {
379
277
  required.push(key);
380
278
  }
@@ -406,7 +304,7 @@ function buildFlatSchema(route, sharedDefs) {
406
304
  };
407
305
  }
408
306
  function buildSharedDefs(document) {
409
- const schemas = _optionalChain([document, 'access', _15 => _15.components, 'optionalAccess', _16 => _16.schemas]);
307
+ const schemas = _optionalChain([document, 'access', _11 => _11.components, 'optionalAccess', _12 => _12.schemas]);
410
308
  if (!schemas || Object.keys(schemas).length === 0) {
411
309
  return void 0;
412
310
  }
@@ -418,7 +316,7 @@ function buildOutputSchema(route, sharedDefs) {
418
316
  const successEntry = Object.entries(_nullishCoalesce(route.responses, () => ( {}))).find(
419
317
  ([code]) => SUCCESS_STATUS_PATTERN.test(code)
420
318
  );
421
- const declaredSchema = _optionalChain([successEntry, 'optionalAccess', _17 => _17[1], 'access', _18 => _18.content, 'optionalAccess', _19 => _19["application/json"], 'optionalAccess', _20 => _20.schema]);
319
+ const declaredSchema = _optionalChain([successEntry, 'optionalAccess', _13 => _13[1], 'access', _14 => _14.content, 'optionalAccess', _15 => _15["application/json"], 'optionalAccess', _16 => _16.schema]);
422
320
  if (!declaredSchema) {
423
321
  return void 0;
424
322
  }
@@ -441,6 +339,22 @@ function buildOutputSchema(route, sharedDefs) {
441
339
  } : {}
442
340
  };
443
341
  }
342
+ function resolveComponentRef(schema, sharedDefs) {
343
+ const seen = /* @__PURE__ */ new Set();
344
+ let current = schema;
345
+ let ref = current.$ref;
346
+ while (typeof ref === "string") {
347
+ const name = componentSchemaName(ref);
348
+ const target = name === void 0 ? void 0 : _optionalChain([sharedDefs, 'optionalAccess', _17 => _17[name]]);
349
+ if (name === void 0 || target === void 0 || seen.has(name)) {
350
+ break;
351
+ }
352
+ seen.add(name);
353
+ current = target;
354
+ ref = current.$ref;
355
+ }
356
+ return current;
357
+ }
444
358
  function rewriteComponentRefs(value, stripExamples = false) {
445
359
  return rewriteNode(value, "schema", stripExamples);
446
360
  }
@@ -460,7 +374,7 @@ function componentSchemaName(ref) {
460
374
  }
461
375
  function extractBodyProperties(requestBody, sharedDefs) {
462
376
  const properties = /* @__PURE__ */ new Map();
463
- const content = _optionalChain([requestBody, 'optionalAccess', _21 => _21.content]);
377
+ const content = _optionalChain([requestBody, 'optionalAccess', _18 => _18.content]);
464
378
  if (!content) {
465
379
  return { properties };
466
380
  }
@@ -471,7 +385,7 @@ function extractBodyProperties(requestBody, sharedDefs) {
471
385
  return contentTypes.length > 0 ? { properties, unsupportedBodyContentType: contentTypes[0] } : { properties };
472
386
  }
473
387
  const bodyEncoding = hasJson ? "json" : "form";
474
- const declaredSchema = hasJson ? _optionalChain([content, 'access', _22 => _22["application/json"], 'optionalAccess', _23 => _23.schema]) : _optionalChain([content, 'access', _24 => _24["application/x-www-form-urlencoded"], 'optionalAccess', _25 => _25.schema]);
388
+ const declaredSchema = hasJson ? _optionalChain([content, 'access', _19 => _19["application/json"], 'optionalAccess', _20 => _20.schema]) : _optionalChain([content, 'access', _21 => _21["application/x-www-form-urlencoded"], 'optionalAccess', _22 => _22.schema]);
475
389
  if (!declaredSchema) {
476
390
  return { bodyEncoding, properties };
477
391
  }
@@ -496,7 +410,7 @@ function extractBodyProperties(requestBody, sharedDefs) {
496
410
  };
497
411
  }
498
412
  properties.set("body", {
499
- required: _nullishCoalesce(_optionalChain([requestBody, 'optionalAccess', _26 => _26.required]), () => ( false)),
413
+ required: _nullishCoalesce(_optionalChain([requestBody, 'optionalAccess', _23 => _23.required]), () => ( false)),
500
414
  schema
501
415
  });
502
416
  return { bodyEncoding, properties, wholeBodyKey: "body" };
@@ -569,22 +483,6 @@ function normalizeNullable(schema) {
569
483
  }
570
484
  return rest;
571
485
  }
572
- function resolveComponentRef(schema, sharedDefs) {
573
- const seen = /* @__PURE__ */ new Set();
574
- let current = schema;
575
- let ref = current.$ref;
576
- while (typeof ref === "string") {
577
- const name = componentSchemaName(ref);
578
- const target = name === void 0 ? void 0 : _optionalChain([sharedDefs, 'optionalAccess', _27 => _27[name]]);
579
- if (name === void 0 || target === void 0 || seen.has(name)) {
580
- break;
581
- }
582
- seen.add(name);
583
- current = target;
584
- ref = current.$ref;
585
- }
586
- return current;
587
- }
588
486
  function rewriteNode(value, mode, stripExamples = false) {
589
487
  if (mode === "data") {
590
488
  return value;
@@ -610,6 +508,124 @@ function rewriteNode(value, mode, stripExamples = false) {
610
508
  return mode === "schemaMap" ? rewritten : normalizeExclusiveBounds(normalizeNullable(rewritten));
611
509
  }
612
510
 
511
+ // src/openapi/resourceMapping.ts
512
+ function buildResourceMapping(route, name, parameterMap, requiredKeys) {
513
+ const entries = Object.entries(parameterMap);
514
+ if (entries.length === 0) {
515
+ return { kind: "resource", uri: `openapi://${name}${route.path}` };
516
+ }
517
+ const required = new Set(_nullishCoalesce(requiredKeys, () => ( [])));
518
+ const args = [];
519
+ const queryKeys = [];
520
+ let path = route.path;
521
+ for (const [flatKey, mapping] of entries) {
522
+ if (mapping.in === "path") {
523
+ if (flatKey !== mapping.name) {
524
+ path = path.replaceAll(`{${mapping.name}}`, `{${flatKey}}`);
525
+ }
526
+ } else {
527
+ queryKeys.push(flatKey);
528
+ }
529
+ args.push({ name: flatKey, required: required.has(flatKey) });
530
+ }
531
+ const uriTemplate = `openapi://${name}${path}` + (queryKeys.length > 0 ? `{?${queryKeys.join(",")}}` : "");
532
+ return { args, kind: "template", uriTemplate };
533
+ }
534
+ function isEligibleForResource(route, sharedDefs) {
535
+ return route.parameters.every((param) => {
536
+ if (param.in === "header" || param.in === "cookie") {
537
+ return false;
538
+ }
539
+ const type = resolveComponentRef(_nullishCoalesce(param.schema, () => ( {})), sharedDefs).type;
540
+ return type !== "array" && (!Array.isArray(type) || !type.includes("array"));
541
+ });
542
+ }
543
+
544
+ // src/openapi/routes.ts
545
+ var HTTP_METHODS = ["get", "put", "post", "delete", "patch"];
546
+ function extractRoutes(document) {
547
+ const routes = [];
548
+ for (const [path, rawPathItem] of Object.entries(_nullishCoalesce(document.paths, () => ( {})))) {
549
+ const pathItem = resolvePathItem(document, rawPathItem);
550
+ const pathLevelParams = (_nullishCoalesce(pathItem.parameters, () => ( []))).map(
551
+ (param) => resolveRef(document, param)
552
+ );
553
+ for (const method of HTTP_METHODS) {
554
+ const operation = pathItem[method];
555
+ if (!operation) {
556
+ continue;
557
+ }
558
+ const operationParams = (_nullishCoalesce(operation.parameters, () => ( []))).map(
559
+ (param) => resolveRef(document, param)
560
+ );
561
+ routes.push({
562
+ deprecated: _nullishCoalesce(operation.deprecated, () => ( false)),
563
+ method,
564
+ operationId: operation.operationId,
565
+ parameters: mergeParameters(pathLevelParams, operationParams),
566
+ path,
567
+ requestBody: operation.requestBody ? resolveRef(document, operation.requestBody) : void 0,
568
+ responses: resolveResponses(document, operation.responses),
569
+ servers: [operation.servers, pathItem.servers, document.servers].find(
570
+ (servers) => _optionalChain([servers, 'optionalAccess', _24 => _24.length])
571
+ ),
572
+ summary: operation.summary,
573
+ tags: _nullishCoalesce(operation.tags, () => ( []))
574
+ });
575
+ }
576
+ }
577
+ return routes;
578
+ }
579
+ function mergeParameters(pathLevel, operationLevel) {
580
+ const overridden = new Set(
581
+ operationLevel.map((param) => `${param.in}:${param.name}`)
582
+ );
583
+ return [
584
+ ...pathLevel.filter(
585
+ (param) => !overridden.has(`${param.in}:${param.name}`)
586
+ ),
587
+ ...operationLevel
588
+ ];
589
+ }
590
+ function resolvePathItem(document, pathItem) {
591
+ const visited = /* @__PURE__ */ new Set();
592
+ let resolved = pathItem;
593
+ while (resolved.$ref && !visited.has(resolved.$ref)) {
594
+ visited.add(resolved.$ref);
595
+ const { $ref, ...siblings } = resolved;
596
+ resolved = { ...resolveRef(document, { $ref }), ...siblings };
597
+ }
598
+ return resolved;
599
+ }
600
+ function resolveRef(document, value) {
601
+ if (!value || typeof value !== "object" || !("$ref" in value)) {
602
+ return value;
603
+ }
604
+ const pointer = value.$ref;
605
+ if (!pointer.startsWith("#/")) {
606
+ throw new Error(`Unexpected external $ref after bundling: ${pointer}`);
607
+ }
608
+ const segments = pointer.slice(2).split("/").map(
609
+ (segment) => decodeURIComponent(segment.replaceAll("~1", "/").replaceAll("~0", "~"))
610
+ );
611
+ let node = document;
612
+ for (const segment of segments) {
613
+ node = _optionalChain([node, 'optionalAccess', _25 => _25[segment]]);
614
+ }
615
+ return node;
616
+ }
617
+ function resolveResponses(document, rawResponses) {
618
+ if (!rawResponses) {
619
+ return void 0;
620
+ }
621
+ return Object.fromEntries(
622
+ Object.entries(rawResponses).map(([code, response]) => [
623
+ code,
624
+ resolveRef(document, response)
625
+ ])
626
+ );
627
+ }
628
+
613
629
  // src/openapi/selection.ts
614
630
  var DEFAULT_MAX_OPERATIONS = 40;
615
631
  var METHOD_PRIORITY = {
@@ -663,8 +679,8 @@ async function fromOpenAPI(options) {
663
679
  const selected = selectRoutes(routes, options);
664
680
  const names = generateNames(selected, options.mcpNames);
665
681
  const sharedDefs = buildSharedDefs(document);
666
- const server = _nullishCoalesce(options.server, () => ( new (0, _chunkC5VOVQPCcjs.FastMCP)({
667
- name: _nullishCoalesce(_nullishCoalesce(options.name, () => ( _optionalChain([document, 'access', _28 => _28.info, 'optionalAccess', _29 => _29.title]))), () => ( "OpenAPI Server")),
682
+ const server = _nullishCoalesce(options.server, () => ( new (0, _chunkRN2Z26T4cjs.FastMCP)({
683
+ name: _nullishCoalesce(_nullishCoalesce(options.name, () => ( _optionalChain([document, 'access', _26 => _26.info, 'optionalAccess', _27 => _27.title]))), () => ( "OpenAPI Server")),
668
684
  version: _nullishCoalesce(options.version, () => ( "1.0.0"))
669
685
  })));
670
686
  const skippedOperations = [];
@@ -689,7 +705,7 @@ async function fromOpenAPI(options) {
689
705
  route,
690
706
  servers: route.servers
691
707
  };
692
- if (options.resources && route.method === "get" && isEligibleForResource(route)) {
708
+ if (options.resources && route.method === "get" && isEligibleForResource(route, sharedDefs)) {
693
709
  registerResource(
694
710
  server,
695
711
  route,
@@ -709,7 +725,7 @@ async function fromOpenAPI(options) {
709
725
  continue;
710
726
  }
711
727
  const outputSchemaJson = buildOutputSchema(route, sharedDefs);
712
- const outputSchema = outputSchemaJson ? _chunkC5VOVQPCcjs.jsonSchemaAdapter.call(void 0, outputSchemaJson) : void 0;
728
+ const outputSchema = outputSchemaJson ? _chunkRN2Z26T4cjs.jsonSchemaAdapter.call(void 0, outputSchemaJson) : void 0;
713
729
  server.addTool({
714
730
  description: _nullishCoalesce(route.summary, () => ( `${route.method.toUpperCase()} ${route.path}`)),
715
731
  execute: async (args) => {
@@ -722,7 +738,7 @@ async function fromOpenAPI(options) {
722
738
  return resolveToolResult(result, outputSchema);
723
739
  },
724
740
  name,
725
- parameters: _chunkC5VOVQPCcjs.jsonSchemaAdapter.call(void 0, flatSchema),
741
+ parameters: _chunkRN2Z26T4cjs.jsonSchemaAdapter.call(void 0, flatSchema),
726
742
  ...outputSchema ? { outputSchema } : {}
727
743
  });
728
744
  }