fastmcp 4.17.1 → 4.19.0

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.
@@ -0,0 +1,662 @@
1
+ import {
2
+ FastMCP,
3
+ UserError,
4
+ jsonSchemaAdapter
5
+ } from "../chunk-UODI5E6U.js";
6
+ import "../chunk-KWRV7CHJ.js";
7
+
8
+ // src/openapi/loadSpec.ts
9
+ import SwaggerParser from "@apidevtools/swagger-parser";
10
+ async function loadSpec(spec) {
11
+ const document = await SwaggerParser.bundle(
12
+ spec
13
+ );
14
+ if (!document.openapi?.startsWith("3.")) {
15
+ throw new Error(
16
+ `fromOpenAPI only supports OpenAPI 3.x documents (found ${document.openapi ?? document.swagger ?? "an unrecognized version"}). Swagger 2.0 is not supported.`
17
+ );
18
+ }
19
+ return {
20
+ document,
21
+ origin: typeof spec === "string" && isHttpUrl(spec) ? spec : void 0
22
+ };
23
+ }
24
+ function isHttpUrl(value) {
25
+ return value.startsWith("http://") || value.startsWith("https://");
26
+ }
27
+
28
+ // src/openapi/naming.ts
29
+ var MAX_NAME_LENGTH = 56;
30
+ var MAX_BASE_LENGTH = MAX_NAME_LENGTH - 5;
31
+ function generateNames(routes, mcpNames) {
32
+ const names = /* @__PURE__ */ new Map();
33
+ const used = /* @__PURE__ */ new Set();
34
+ for (const route of routes) {
35
+ const base = slugify(baseNameFor(route, mcpNames));
36
+ let candidate = base;
37
+ let suffix = 1;
38
+ while (used.has(candidate)) {
39
+ suffix += 1;
40
+ candidate = `${base}_${suffix}`;
41
+ }
42
+ used.add(candidate);
43
+ names.set(route, candidate);
44
+ }
45
+ return names;
46
+ }
47
+ function baseNameFor(route, mcpNames) {
48
+ if (route.operationId) {
49
+ return mcpNames?.[route.operationId] ?? route.operationId.split("__")[0];
50
+ }
51
+ return route.summary || `${route.method}_${route.path}`;
52
+ }
53
+ function slugify(value) {
54
+ const slug = value.replace(/[^a-zA-Z0-9_]+/g, "_").replace(/_+/g, "_").replace(/^_|_$/g, "").slice(0, MAX_BASE_LENGTH);
55
+ return slug || "operation";
56
+ }
57
+
58
+ // src/openapi/requestBuilder.ts
59
+ async function executeRequest(options) {
60
+ const baseUrl = resolveBaseUrl(
61
+ options.servers,
62
+ options.origin,
63
+ options.baseUrlOverride
64
+ );
65
+ const pathParams = {};
66
+ const query = new URLSearchParams();
67
+ const headers = new Headers(await resolveHeaders(options.headers));
68
+ const bodyProps = {};
69
+ for (const [key, value] of Object.entries(options.args)) {
70
+ const mapping = options.parameterMap[key];
71
+ if (!mapping || value === void 0) {
72
+ continue;
73
+ }
74
+ switch (mapping.in) {
75
+ case "body":
76
+ bodyProps[mapping.name] = value;
77
+ break;
78
+ case "cookie": {
79
+ const existing = headers.get("cookie");
80
+ headers.set(
81
+ "cookie",
82
+ existing ? `${existing}; ${mapping.name}=${String(value)}` : `${mapping.name}=${String(value)}`
83
+ );
84
+ break;
85
+ }
86
+ case "header":
87
+ headers.set(mapping.name, String(value));
88
+ break;
89
+ case "path":
90
+ pathParams[mapping.name] = String(value);
91
+ break;
92
+ case "query":
93
+ for (const item of Array.isArray(value) ? value : [value]) {
94
+ query.append(mapping.name, String(item));
95
+ }
96
+ break;
97
+ }
98
+ }
99
+ let path = options.route.path;
100
+ for (const [name, value] of Object.entries(pathParams)) {
101
+ path = path.replace(`{${name}}`, encodeURIComponent(value));
102
+ }
103
+ const url = new URL(baseUrl.replace(/\/$/, "") + path);
104
+ url.search = query.toString();
105
+ let body;
106
+ if (Object.keys(bodyProps).length > 0) {
107
+ const payload = options.wholeBodyKey ? bodyProps[options.wholeBodyKey] : bodyProps;
108
+ if (options.bodyEncoding === "form") {
109
+ if (!headers.has("content-type")) {
110
+ headers.set("content-type", "application/x-www-form-urlencoded");
111
+ }
112
+ body = encodeFormBody(payload);
113
+ } else {
114
+ if (!headers.has("content-type")) {
115
+ headers.set("content-type", "application/json");
116
+ }
117
+ body = JSON.stringify(payload);
118
+ }
119
+ }
120
+ const response = await options.fetchImpl(url.toString(), {
121
+ body,
122
+ headers,
123
+ method: options.route.method.toUpperCase()
124
+ });
125
+ const text = await response.text();
126
+ if (!response.ok) {
127
+ throw new UserError(
128
+ `${options.route.method.toUpperCase()} ${path} failed with ${response.status}: ${text.slice(0, 2e3)}`
129
+ );
130
+ }
131
+ if (response.headers.get("content-type")?.includes("json")) {
132
+ try {
133
+ return JSON.stringify(JSON.parse(text), null, 2);
134
+ } catch {
135
+ return text;
136
+ }
137
+ }
138
+ return text;
139
+ }
140
+ function resolveBaseUrl(servers, origin, overrideUrl) {
141
+ if (overrideUrl) {
142
+ return overrideUrl.replace(/\/$/, "");
143
+ }
144
+ const server = servers?.[0];
145
+ if (!server) {
146
+ throw new Error(
147
+ "The OpenAPI document has no `servers` entry. Pass `baseUrl` to fromOpenAPI() explicitly."
148
+ );
149
+ }
150
+ let url = server.url;
151
+ for (const [name, variable] of Object.entries(server.variables ?? {})) {
152
+ url = url.replaceAll(`{${name}}`, variable.default);
153
+ }
154
+ try {
155
+ return new URL(url).toString().replace(/\/$/, "");
156
+ } catch {
157
+ if (!origin) {
158
+ throw new Error(
159
+ `The OpenAPI document's servers[0].url ("${url}") is relative, and the spec was not loaded from an http(s) URL, so it cannot be resolved to an absolute address. Pass \`baseUrl\` to fromOpenAPI() explicitly.`
160
+ );
161
+ }
162
+ return new URL(url, origin).toString().replace(/\/$/, "");
163
+ }
164
+ }
165
+ function encodeFormBody(payload) {
166
+ const params = new URLSearchParams();
167
+ if (payload && typeof payload === "object" && !Array.isArray(payload)) {
168
+ for (const [key, value] of Object.entries(
169
+ payload
170
+ )) {
171
+ if (value === void 0) {
172
+ continue;
173
+ }
174
+ for (const item of Array.isArray(value) ? value : [value]) {
175
+ params.append(
176
+ key,
177
+ item !== null && typeof item === "object" ? JSON.stringify(item) : String(item)
178
+ );
179
+ }
180
+ }
181
+ }
182
+ return params.toString();
183
+ }
184
+ async function resolveHeaders(headers) {
185
+ if (!headers) {
186
+ return {};
187
+ }
188
+ return typeof headers === "function" ? await headers() : { ...headers };
189
+ }
190
+
191
+ // src/openapi/resourceMapping.ts
192
+ function buildResourceMapping(route, name, parameterMap, requiredKeys) {
193
+ const entries = Object.entries(parameterMap);
194
+ if (entries.length === 0) {
195
+ return { kind: "resource", uri: `openapi://${name}${route.path}` };
196
+ }
197
+ const required = new Set(requiredKeys ?? []);
198
+ const args = [];
199
+ const queryKeys = [];
200
+ let path = route.path;
201
+ for (const [flatKey, mapping] of entries) {
202
+ if (mapping.in === "path") {
203
+ if (flatKey !== mapping.name) {
204
+ path = path.replace(`{${mapping.name}}`, `{${flatKey}}`);
205
+ }
206
+ } else {
207
+ queryKeys.push(flatKey);
208
+ }
209
+ args.push({ name: flatKey, required: required.has(flatKey) });
210
+ }
211
+ const uriTemplate = `openapi://${name}${path}` + (queryKeys.length > 0 ? `{?${queryKeys.join(",")}}` : "");
212
+ return { args, kind: "template", uriTemplate };
213
+ }
214
+ function isEligibleForResource(route) {
215
+ return route.parameters.every((param) => {
216
+ if (param.in === "header" || param.in === "cookie") {
217
+ return false;
218
+ }
219
+ return param.schema?.type !== "array";
220
+ });
221
+ }
222
+
223
+ // src/openapi/routes.ts
224
+ var HTTP_METHODS = ["get", "put", "post", "delete", "patch"];
225
+ function extractRoutes(document) {
226
+ const routes = [];
227
+ for (const [path, pathItem] of Object.entries(document.paths ?? {})) {
228
+ const pathLevelParams = (pathItem.parameters ?? []).map(
229
+ (param) => resolveRef(document, param)
230
+ );
231
+ for (const method of HTTP_METHODS) {
232
+ const operation = pathItem[method];
233
+ if (!operation) {
234
+ continue;
235
+ }
236
+ const operationParams = (operation.parameters ?? []).map(
237
+ (param) => resolveRef(document, param)
238
+ );
239
+ routes.push({
240
+ deprecated: operation.deprecated ?? false,
241
+ method,
242
+ operationId: operation.operationId,
243
+ parameters: mergeParameters(pathLevelParams, operationParams),
244
+ path,
245
+ requestBody: operation.requestBody ? resolveRef(document, operation.requestBody) : void 0,
246
+ summary: operation.summary,
247
+ tags: operation.tags ?? []
248
+ });
249
+ }
250
+ }
251
+ return routes;
252
+ }
253
+ function mergeParameters(pathLevel, operationLevel) {
254
+ const overridden = new Set(
255
+ operationLevel.map((param) => `${param.in}:${param.name}`)
256
+ );
257
+ return [
258
+ ...pathLevel.filter(
259
+ (param) => !overridden.has(`${param.in}:${param.name}`)
260
+ ),
261
+ ...operationLevel
262
+ ];
263
+ }
264
+ function resolveRef(document, value) {
265
+ if (!value || typeof value !== "object" || !("$ref" in value)) {
266
+ return value;
267
+ }
268
+ const pointer = value.$ref;
269
+ if (!pointer.startsWith("#/")) {
270
+ throw new Error(`Unexpected external $ref after bundling: ${pointer}`);
271
+ }
272
+ const segments = pointer.slice(2).split("/").map(
273
+ (segment) => decodeURIComponent(segment.replaceAll("~1", "/").replaceAll("~0", "~"))
274
+ );
275
+ let node = document;
276
+ for (const segment of segments) {
277
+ node = node?.[segment];
278
+ }
279
+ return node;
280
+ }
281
+
282
+ // src/openapi/schemas.ts
283
+ var SCHEMA_MAP_KEYS = /* @__PURE__ */ new Set([
284
+ "$defs",
285
+ "definitions",
286
+ "dependentSchemas",
287
+ "patternProperties",
288
+ "properties"
289
+ ]);
290
+ var DATA_KEYS = /* @__PURE__ */ new Set(["const", "default", "enum", "example", "examples"]);
291
+ function buildFlatSchema(route, sharedDefs) {
292
+ const byName = /* @__PURE__ */ new Map();
293
+ for (const param of route.parameters) {
294
+ const list = byName.get(param.name) ?? [];
295
+ list.push(param);
296
+ byName.set(param.name, list);
297
+ }
298
+ const {
299
+ bodyEncoding,
300
+ properties: bodyProperties,
301
+ unsupportedBodyContentType,
302
+ wholeBodyKey
303
+ } = extractBodyProperties(
304
+ route.method === "get" ? void 0 : route.requestBody,
305
+ sharedDefs
306
+ );
307
+ const properties = {};
308
+ const required = [];
309
+ const parameterMap = {};
310
+ for (const [name, occurrences] of byName) {
311
+ const collides = occurrences.length > 1 || bodyProperties.has(name);
312
+ for (const param of occurrences) {
313
+ const key = collides ? `${name}__${param.in}` : name;
314
+ properties[key] = rewriteComponentRefs(
315
+ param.schema ?? { type: "string" }
316
+ );
317
+ parameterMap[key] = { in: param.in, name };
318
+ if (param.in === "path" || param.required) {
319
+ required.push(key);
320
+ }
321
+ }
322
+ }
323
+ for (const [name, { required: isRequired, schema }] of bodyProperties) {
324
+ properties[name] = rewriteComponentRefs(schema);
325
+ parameterMap[name] = { in: "body", name };
326
+ if (isRequired) {
327
+ required.push(name);
328
+ }
329
+ }
330
+ const flatSchema = {
331
+ additionalProperties: false,
332
+ properties,
333
+ type: "object",
334
+ ...required.length > 0 ? { required } : {}
335
+ };
336
+ const usedDefs = sharedDefs && filterReferencedDefs(properties, sharedDefs);
337
+ if (usedDefs) {
338
+ flatSchema.$defs = usedDefs;
339
+ }
340
+ return {
341
+ bodyEncoding,
342
+ flatSchema,
343
+ parameterMap,
344
+ unsupportedBodyContentType,
345
+ wholeBodyKey
346
+ };
347
+ }
348
+ function buildSharedDefs(document) {
349
+ const schemas = document.components?.schemas;
350
+ if (!schemas || Object.keys(schemas).length === 0) {
351
+ return void 0;
352
+ }
353
+ return rewriteNode(schemas, "schemaMap");
354
+ }
355
+ function rewriteComponentRefs(value) {
356
+ return rewriteNode(value, "schema");
357
+ }
358
+ function childMode(key) {
359
+ if (DATA_KEYS.has(key)) {
360
+ return "data";
361
+ }
362
+ return SCHEMA_MAP_KEYS.has(key) ? "schemaMap" : "schema";
363
+ }
364
+ function componentSchemaName(ref) {
365
+ for (const prefix of ["#/components/schemas/", "#/$defs/"]) {
366
+ if (ref.startsWith(prefix)) {
367
+ return ref.slice(prefix.length);
368
+ }
369
+ }
370
+ return void 0;
371
+ }
372
+ function extractBodyProperties(requestBody, sharedDefs) {
373
+ const properties = /* @__PURE__ */ new Map();
374
+ const content = requestBody?.content;
375
+ if (!content) {
376
+ return { properties };
377
+ }
378
+ const hasJson = "application/json" in content;
379
+ const hasForm = "application/x-www-form-urlencoded" in content;
380
+ if (!hasJson && !hasForm) {
381
+ const contentTypes = Object.keys(content);
382
+ return contentTypes.length > 0 ? { properties, unsupportedBodyContentType: contentTypes[0] } : { properties };
383
+ }
384
+ const bodyEncoding = hasJson ? "json" : "form";
385
+ const declaredSchema = hasJson ? content["application/json"]?.schema : content["application/x-www-form-urlencoded"]?.schema;
386
+ if (!declaredSchema) {
387
+ return { bodyEncoding, properties };
388
+ }
389
+ const schema = bodyEncoding === "form" ? resolveComponentRef(declaredSchema, sharedDefs) : declaredSchema;
390
+ const schemaProperties = schema.properties;
391
+ if (schema.type === "object" && schemaProperties) {
392
+ const requiredNames = new Set(
393
+ schema.required ?? []
394
+ );
395
+ for (const [name, propertySchema] of Object.entries(schemaProperties)) {
396
+ properties.set(name, {
397
+ required: requiredNames.has(name),
398
+ schema: propertySchema
399
+ });
400
+ }
401
+ return { bodyEncoding, properties };
402
+ }
403
+ if (bodyEncoding === "form") {
404
+ return {
405
+ properties,
406
+ unsupportedBodyContentType: "application/x-www-form-urlencoded"
407
+ };
408
+ }
409
+ properties.set("body", {
410
+ required: requestBody?.required ?? false,
411
+ schema
412
+ });
413
+ return { bodyEncoding, properties, wholeBodyKey: "body" };
414
+ }
415
+ function filterReferencedDefs(node, allDefs) {
416
+ const referenced = /* @__PURE__ */ new Set();
417
+ const stack = [node];
418
+ while (stack.length > 0) {
419
+ const current = stack.pop();
420
+ if (Array.isArray(current)) {
421
+ stack.push(...current);
422
+ continue;
423
+ }
424
+ if (!current || typeof current !== "object") {
425
+ continue;
426
+ }
427
+ for (const [key, value] of Object.entries(
428
+ current
429
+ )) {
430
+ if (key === "$ref" && typeof value === "string" && value.startsWith("#/$defs/")) {
431
+ const name = value.slice("#/$defs/".length);
432
+ if (allDefs[name] && !referenced.has(name)) {
433
+ referenced.add(name);
434
+ stack.push(allDefs[name]);
435
+ }
436
+ continue;
437
+ }
438
+ stack.push(value);
439
+ }
440
+ }
441
+ if (referenced.size === 0) {
442
+ return void 0;
443
+ }
444
+ return Object.fromEntries(
445
+ [...referenced].map((name) => [name, allDefs[name]])
446
+ );
447
+ }
448
+ function normalizeNullable(schema) {
449
+ if (!("nullable" in schema)) {
450
+ return schema;
451
+ }
452
+ const { nullable, type, ...rest } = schema;
453
+ if (nullable !== true) {
454
+ return rest;
455
+ }
456
+ if (typeof type === "string") {
457
+ return { ...rest, type: [type, "null"] };
458
+ }
459
+ if (Array.isArray(type)) {
460
+ return { ...rest, type: [.../* @__PURE__ */ new Set(["null", ...type])] };
461
+ }
462
+ return rest;
463
+ }
464
+ function resolveComponentRef(schema, sharedDefs) {
465
+ const seen = /* @__PURE__ */ new Set();
466
+ let current = schema;
467
+ let ref = current.$ref;
468
+ while (typeof ref === "string") {
469
+ const name = componentSchemaName(ref);
470
+ const target = name === void 0 ? void 0 : sharedDefs?.[name];
471
+ if (name === void 0 || target === void 0 || seen.has(name)) {
472
+ break;
473
+ }
474
+ seen.add(name);
475
+ current = target;
476
+ ref = current.$ref;
477
+ }
478
+ return current;
479
+ }
480
+ function rewriteNode(value, mode) {
481
+ if (mode === "data") {
482
+ return value;
483
+ }
484
+ if (Array.isArray(value)) {
485
+ return value.map((item) => rewriteNode(item, "schema"));
486
+ }
487
+ if (!value || typeof value !== "object") {
488
+ return value;
489
+ }
490
+ const entries = Object.entries(value).map(
491
+ ([key, entryValue]) => {
492
+ if (mode === "schemaMap") {
493
+ return [key, rewriteNode(entryValue, "schema")];
494
+ }
495
+ if (key === "$ref" && typeof entryValue === "string" && entryValue.startsWith("#/components/schemas/")) {
496
+ return [key, entryValue.replace("#/components/schemas/", "#/$defs/")];
497
+ }
498
+ return [key, rewriteNode(entryValue, childMode(key))];
499
+ }
500
+ );
501
+ const rewritten = Object.fromEntries(entries);
502
+ return mode === "schemaMap" ? rewritten : normalizeNullable(rewritten);
503
+ }
504
+
505
+ // src/openapi/selection.ts
506
+ var DEFAULT_MAX_OPERATIONS = 40;
507
+ var METHOD_PRIORITY = {
508
+ delete: 4,
509
+ get: 0,
510
+ patch: 3,
511
+ post: 1,
512
+ put: 2
513
+ };
514
+ function selectRoutes(routes, options) {
515
+ let selected = routes.filter((route) => !route.deprecated);
516
+ if (options.include) {
517
+ const include = options.include;
518
+ selected = selected.filter((route) => include(toSummary(route)));
519
+ }
520
+ if (options.exclude) {
521
+ const exclude = options.exclude;
522
+ selected = selected.filter((route) => !exclude(toSummary(route)));
523
+ }
524
+ selected = [...selected].sort((a, b) => {
525
+ const byMethod = METHOD_PRIORITY[a.method] - METHOD_PRIORITY[b.method];
526
+ return byMethod !== 0 ? byMethod : a.path.localeCompare(b.path);
527
+ });
528
+ const noSelectionGiven = !options.include && !options.exclude;
529
+ if (noSelectionGiven && options.maxTools === void 0 && selected.length > DEFAULT_MAX_OPERATIONS) {
530
+ throw new Error(
531
+ `fromOpenAPI found ${selected.length} operations, which exceeds the default limit of ${DEFAULT_MAX_OPERATIONS}. This is a deliberate stop, not a bug: turning every operation in a large spec into a tool produces a tool list most MCP clients can't use well. Pass \`include\`/\`exclude\` to choose the operations you actually want, or \`maxTools\` to raise this limit explicitly.`
532
+ );
533
+ }
534
+ if (options.maxTools !== void 0 && selected.length > options.maxTools) {
535
+ throw new Error(
536
+ `fromOpenAPI found ${selected.length} operations, which exceeds maxTools (${options.maxTools}). Narrow the spec with \`include\`/\`exclude\`, or raise \`maxTools\`.`
537
+ );
538
+ }
539
+ return selected;
540
+ }
541
+ function toSummary(route) {
542
+ return {
543
+ deprecated: route.deprecated,
544
+ method: route.method,
545
+ operationId: route.operationId,
546
+ path: route.path,
547
+ tags: route.tags
548
+ };
549
+ }
550
+
551
+ // src/openapi/fromOpenAPI.ts
552
+ async function fromOpenAPI(options) {
553
+ const { document, origin } = await loadSpec(options.spec);
554
+ const routes = extractRoutes(document);
555
+ const selected = selectRoutes(routes, options);
556
+ const names = generateNames(selected, options.mcpNames);
557
+ const sharedDefs = buildSharedDefs(document);
558
+ const server = options.server ?? new FastMCP({
559
+ name: options.name ?? document.info?.title ?? "OpenAPI Server",
560
+ version: options.version ?? "1.0.0"
561
+ });
562
+ const skippedOperations = [];
563
+ for (const route of selected) {
564
+ const name = names.get(route);
565
+ if (!name) {
566
+ continue;
567
+ }
568
+ const {
569
+ bodyEncoding,
570
+ flatSchema,
571
+ parameterMap,
572
+ unsupportedBodyContentType,
573
+ wholeBodyKey
574
+ } = buildFlatSchema(route, sharedDefs);
575
+ const execOptions = {
576
+ baseUrlOverride: options.baseUrl,
577
+ fetchImpl: options.fetch ?? fetch,
578
+ headers: options.headers,
579
+ origin,
580
+ parameterMap,
581
+ route,
582
+ servers: document.servers
583
+ };
584
+ if (options.resources && route.method === "get" && isEligibleForResource(route)) {
585
+ registerResource(
586
+ server,
587
+ route,
588
+ name,
589
+ parameterMap,
590
+ flatSchema.required,
591
+ execOptions
592
+ );
593
+ continue;
594
+ }
595
+ if (unsupportedBodyContentType) {
596
+ skippedOperations.push({
597
+ contentType: unsupportedBodyContentType,
598
+ method: route.method,
599
+ path: route.path
600
+ });
601
+ continue;
602
+ }
603
+ server.addTool({
604
+ description: route.summary ?? `${route.method.toUpperCase()} ${route.path}`,
605
+ execute: async (args) => executeRequest({
606
+ ...execOptions,
607
+ args,
608
+ bodyEncoding,
609
+ wholeBodyKey
610
+ }),
611
+ name,
612
+ parameters: jsonSchemaAdapter(flatSchema)
613
+ });
614
+ }
615
+ if (skippedOperations.length > 0) {
616
+ console.warn(
617
+ `fromOpenAPI: skipped ${skippedOperations.length} operation(s) whose request body can't be turned into tool parameters (supported: application/json, or application/x-www-form-urlencoded with a flat object schema): ` + skippedOperations.map(
618
+ (op) => `${op.method.toUpperCase()} ${op.path} (${op.contentType})`
619
+ ).join(", ")
620
+ );
621
+ }
622
+ return server;
623
+ }
624
+ function registerResource(server, route, name, parameterMap, requiredKeys, execOptions) {
625
+ const mapping = buildResourceMapping(route, name, parameterMap, requiredKeys);
626
+ const description = route.summary ?? `GET ${route.path}`;
627
+ if (mapping.kind === "resource") {
628
+ server.addResource({
629
+ description,
630
+ load: async () => wrapAsResourceResult(
631
+ await executeRequest({ ...execOptions, args: {} })
632
+ ),
633
+ name,
634
+ uri: mapping.uri
635
+ });
636
+ return;
637
+ }
638
+ server.addResourceTemplate({
639
+ arguments: mapping.args,
640
+ description,
641
+ load: async (args) => wrapAsResourceResult(
642
+ await executeRequest({
643
+ ...execOptions,
644
+ args
645
+ })
646
+ ),
647
+ name,
648
+ uriTemplate: mapping.uriTemplate
649
+ });
650
+ }
651
+ function wrapAsResourceResult(text) {
652
+ try {
653
+ JSON.parse(text);
654
+ return { mimeType: "application/json", text };
655
+ } catch {
656
+ return { mimeType: "text/plain", text };
657
+ }
658
+ }
659
+ export {
660
+ fromOpenAPI
661
+ };
662
+ //# sourceMappingURL=index.js.map