@frontmcp/adapters 0.6.0 → 0.6.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.
@@ -1,8 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.default = void 0;
4
- const tslib_1 = require("tslib");
5
- var openapi_adapter_1 = require("./openapi.adapter");
6
- Object.defineProperty(exports, "default", { enumerable: true, get: function () { return tslib_1.__importDefault(openapi_adapter_1).default; } });
7
- tslib_1.__exportStar(require("./openapi.types"), exports);
8
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/openapi/index.ts"],"names":[],"mappings":";;;;AAAA,qDAA4C;AAAnC,mIAAA,OAAO,OAAA;AAChB,0DAAgC","sourcesContent":["export { default } from './openapi.adapter';\nexport * from './openapi.types';\n"]}
@@ -1,434 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const tslib_1 = require("tslib");
4
- const sdk_1 = require("@frontmcp/sdk");
5
- const mcp_from_openapi_1 = require("mcp-from-openapi");
6
- const openapi_tool_1 = require("./openapi.tool");
7
- const openapi_security_1 = require("./openapi.security");
8
- /** Reserved keys that cannot be used as inputKey (prototype pollution protection) */
9
- const RESERVED_KEYS = ['__proto__', 'constructor', 'prototype'];
10
- /**
11
- * Creates a simple console-based logger for use outside the SDK context.
12
- */
13
- function createConsoleLogger(prefix) {
14
- const formatMessage = (level, msg) => `[${prefix}] ${level}: ${msg}`;
15
- return {
16
- verbose: (msg, ...args) => console.debug(formatMessage('VERBOSE', msg), ...args),
17
- debug: (msg, ...args) => console.debug(formatMessage('DEBUG', msg), ...args),
18
- info: (msg, ...args) => console.info(formatMessage('INFO', msg), ...args),
19
- warn: (msg, ...args) => console.warn(formatMessage('WARN', msg), ...args),
20
- error: (msg, ...args) => console.error(formatMessage('ERROR', msg), ...args),
21
- child: (childPrefix) => createConsoleLogger(`${prefix}:${childPrefix}`),
22
- };
23
- }
24
- let OpenapiAdapter = class OpenapiAdapter extends sdk_1.DynamicAdapter {
25
- generator;
26
- logger;
27
- options;
28
- constructor(options) {
29
- super();
30
- this.options = options;
31
- // Use provided logger or create console fallback
32
- this.logger = options.logger ?? createConsoleLogger(`openapi:${options.name}`);
33
- }
34
- /**
35
- * Receive the SDK logger. Called by the SDK before fetch().
36
- */
37
- setLogger(logger) {
38
- this.logger = logger;
39
- }
40
- async fetch() {
41
- // Lazy load: Initialize generator on first fetch if not already initialized
42
- if (!this.generator) {
43
- this.generator = await this.initializeGenerator();
44
- }
45
- // Determine if we need security in input
46
- // If securitySchemesInInput is set, we need all security in input first, then filter
47
- const hasPerSchemeControl = this.options.securitySchemesInInput && this.options.securitySchemesInInput.length > 0;
48
- const includeSecurityInInput = hasPerSchemeControl || (this.options.generateOptions?.includeSecurityInInput ?? false);
49
- // Generate tools from OpenAPI spec
50
- let openapiTools = await this.generator.generateTools({
51
- includeOperations: this.options.generateOptions?.includeOperations,
52
- excludeOperations: this.options.generateOptions?.excludeOperations,
53
- filterFn: this.options.generateOptions?.filterFn,
54
- namingStrategy: this.options.generateOptions?.namingStrategy,
55
- preferredStatusCodes: this.options.generateOptions?.preferredStatusCodes ?? [200, 201, 202, 204],
56
- includeDeprecated: this.options.generateOptions?.includeDeprecated ?? false,
57
- includeAllResponses: this.options.generateOptions?.includeAllResponses ?? true,
58
- includeSecurityInInput: includeSecurityInInput,
59
- maxSchemaDepth: this.options.generateOptions?.maxSchemaDepth,
60
- includeExamples: this.options.generateOptions?.includeExamples,
61
- });
62
- // If per-scheme control is enabled, filter security inputs
63
- if (hasPerSchemeControl) {
64
- openapiTools = openapiTools.map((tool) => this.filterSecuritySchemes(tool));
65
- }
66
- // Validate security configuration
67
- const validation = (0, openapi_security_1.validateSecurityConfiguration)(openapiTools, this.options);
68
- // Log security information
69
- this.logger.info('Security Analysis:');
70
- this.logger.info(` Security Risk Score: ${validation.securityRiskScore.toUpperCase()}`);
71
- this.logger.info(` Valid Configuration: ${validation.valid ? 'YES' : 'NO'}`);
72
- if (validation.warnings.length > 0) {
73
- this.logger.info('Messages:');
74
- validation.warnings.forEach((warning) => {
75
- if (warning.startsWith('ERROR:')) {
76
- this.logger.error(` - ${warning}`);
77
- }
78
- else if (warning.startsWith('SECURITY WARNING:')) {
79
- this.logger.warn(` - ${warning}`);
80
- }
81
- else {
82
- this.logger.info(` - ${warning}`);
83
- }
84
- });
85
- }
86
- // Fail if configuration is invalid and security is required
87
- if (!validation.valid) {
88
- throw new Error(`[OpenAPI Adapter: ${this.options.name}] Invalid security configuration.\n` +
89
- `Missing auth provider mappings for security schemes: ${validation.missingMappings.join(', ')}\n\n` +
90
- `Your OpenAPI spec requires these security schemes, but no auth configuration was provided.\n\n` +
91
- `Add one of the following to your adapter configuration:\n\n` +
92
- `1. authProviderMapper (recommended):\n` +
93
- ` authProviderMapper: {\n` +
94
- validation.missingMappings
95
- .map((s) => ` '${s}': (authInfo) => authInfo.user?.${s.toLowerCase()}Token,`)
96
- .join('\n') +
97
- `\n }\n\n` +
98
- `2. securityResolver:\n` +
99
- ` securityResolver: (tool, authInfo) => ({ jwt: authInfo.token })\n\n` +
100
- `3. staticAuth:\n` +
101
- ` staticAuth: { jwt: process.env.API_TOKEN }\n\n` +
102
- `4. Include security in input (NOT recommended for production):\n` +
103
- ` generateOptions: { includeSecurityInInput: true }`);
104
- }
105
- // Apply all transforms to tools
106
- let transformedTools = openapiTools;
107
- // 1. Apply description mode (generates description from summary/description)
108
- if (this.options.descriptionMode && this.options.descriptionMode !== 'summaryOnly') {
109
- transformedTools = transformedTools.map((tool) => this.applyDescriptionMode(tool));
110
- }
111
- // 2. Apply tool transforms (annotations, name, description overrides, etc.)
112
- if (this.options.toolTransforms) {
113
- transformedTools = transformedTools.map((tool) => this.applyToolTransforms(tool));
114
- }
115
- // 3. Apply input transforms (hide inputs, inject values at runtime)
116
- if (this.options.inputTransforms) {
117
- transformedTools = transformedTools.map((tool) => this.applyInputTransforms(tool));
118
- }
119
- // Convert OpenAPI tools to FrontMCP tools
120
- const tools = transformedTools.map((openapiTool) => (0, openapi_tool_1.createOpenApiTool)(openapiTool, this.options, this.logger));
121
- return { tools };
122
- }
123
- /**
124
- * Initialize the OpenAPI tool generator from URL or spec
125
- * @private
126
- */
127
- async initializeGenerator() {
128
- if ('url' in this.options) {
129
- return await mcp_from_openapi_1.OpenAPIToolGenerator.fromURL(this.options.url, {
130
- baseUrl: this.options.baseUrl,
131
- validate: this.options.loadOptions?.validate ?? true,
132
- dereference: this.options.loadOptions?.dereference ?? true,
133
- headers: this.options.loadOptions?.headers,
134
- timeout: this.options.loadOptions?.timeout,
135
- followRedirects: this.options.loadOptions?.followRedirects,
136
- });
137
- }
138
- else if ('spec' in this.options) {
139
- return await mcp_from_openapi_1.OpenAPIToolGenerator.fromJSON(this.options.spec, {
140
- baseUrl: this.options.baseUrl,
141
- validate: this.options.loadOptions?.validate ?? true,
142
- dereference: this.options.loadOptions?.dereference ?? true,
143
- });
144
- }
145
- else {
146
- throw new Error('Either url or spec must be provided in OpenApiAdapterOptions');
147
- }
148
- }
149
- /**
150
- * Apply description mode to generate description from summary/description
151
- * @private
152
- */
153
- applyDescriptionMode(tool) {
154
- const mode = this.options.descriptionMode || 'summaryOnly';
155
- const metadata = tool.metadata;
156
- const summary = metadata['operationSummary'];
157
- const opDescription = metadata['operationDescription'];
158
- const operationId = metadata['operationId'];
159
- const method = metadata['method'];
160
- const path = metadata['path'];
161
- let description;
162
- switch (mode) {
163
- case 'descriptionOnly':
164
- description = opDescription || summary || `${method.toUpperCase()} ${path}`;
165
- break;
166
- case 'combined':
167
- if (summary && opDescription) {
168
- description = `${summary}\n\n${opDescription}`;
169
- }
170
- else {
171
- description = summary || opDescription || `${method.toUpperCase()} ${path}`;
172
- }
173
- break;
174
- case 'full': {
175
- const parts = [];
176
- if (summary)
177
- parts.push(summary);
178
- if (opDescription && opDescription !== summary)
179
- parts.push(opDescription);
180
- if (operationId)
181
- parts.push(`Operation: ${operationId}`);
182
- parts.push(`${method.toUpperCase()} ${path}`);
183
- description = parts.join('\n\n');
184
- break;
185
- }
186
- default:
187
- // 'summaryOnly' - use existing description
188
- return tool;
189
- }
190
- return {
191
- ...tool,
192
- description,
193
- };
194
- }
195
- /**
196
- * Collect tool transforms for a specific tool
197
- * @private
198
- */
199
- collectToolTransforms(tool) {
200
- const result = {};
201
- const opts = this.options.toolTransforms;
202
- if (!opts)
203
- return result;
204
- // 1. Apply global transforms
205
- if (opts.global) {
206
- Object.assign(result, opts.global);
207
- if (opts.global.annotations) {
208
- result.annotations = { ...opts.global.annotations };
209
- }
210
- if (opts.global.tags) {
211
- result.tags = [...opts.global.tags];
212
- }
213
- if (opts.global.examples) {
214
- result.examples = [...opts.global.examples];
215
- }
216
- }
217
- // 2. Apply per-tool transforms (override global)
218
- if (opts.perTool?.[tool.name]) {
219
- const perTool = opts.perTool[tool.name];
220
- if (perTool.name)
221
- result.name = perTool.name;
222
- if (perTool.description)
223
- result.description = perTool.description;
224
- if (perTool.hideFromDiscovery !== undefined)
225
- result.hideFromDiscovery = perTool.hideFromDiscovery;
226
- if (perTool.ui)
227
- result.ui = perTool.ui;
228
- if (perTool.annotations) {
229
- result.annotations = { ...result.annotations, ...perTool.annotations };
230
- }
231
- if (perTool.tags) {
232
- result.tags = [...(result.tags || []), ...perTool.tags];
233
- }
234
- if (perTool.examples) {
235
- result.examples = [...(result.examples || []), ...perTool.examples];
236
- }
237
- }
238
- // 3. Apply generator-produced transforms (override per-tool)
239
- if (opts.generator) {
240
- const generated = opts.generator(tool);
241
- if (generated) {
242
- if (generated.name)
243
- result.name = generated.name;
244
- if (generated.description)
245
- result.description = generated.description;
246
- if (generated.hideFromDiscovery !== undefined)
247
- result.hideFromDiscovery = generated.hideFromDiscovery;
248
- if (generated.ui)
249
- result.ui = generated.ui;
250
- if (generated.annotations) {
251
- result.annotations = { ...result.annotations, ...generated.annotations };
252
- }
253
- if (generated.tags) {
254
- result.tags = [...(result.tags || []), ...generated.tags];
255
- }
256
- if (generated.examples) {
257
- result.examples = [...(result.examples || []), ...generated.examples];
258
- }
259
- }
260
- }
261
- return result;
262
- }
263
- /**
264
- * Apply tool transforms to an OpenAPI tool
265
- * @private
266
- */
267
- applyToolTransforms(tool) {
268
- const transforms = this.collectToolTransforms(tool);
269
- if (Object.keys(transforms).length === 0)
270
- return tool;
271
- let newName = tool.name;
272
- let newDescription = tool.description;
273
- // Apply name transform
274
- if (transforms.name) {
275
- newName = typeof transforms.name === 'function' ? transforms.name(tool.name, tool) : transforms.name;
276
- }
277
- // Apply description transform
278
- if (transforms.description) {
279
- newDescription =
280
- typeof transforms.description === 'function'
281
- ? transforms.description(tool.description, tool)
282
- : transforms.description;
283
- }
284
- this.logger.debug(`Applied tool transforms to '${tool.name}'`);
285
- const metadataRecord = tool.metadata;
286
- const existingAdapter = metadataRecord['adapter'];
287
- return {
288
- ...tool,
289
- name: newName,
290
- description: newDescription,
291
- metadata: {
292
- ...tool.metadata,
293
- adapter: {
294
- ...(existingAdapter || {}),
295
- toolTransform: transforms,
296
- },
297
- },
298
- };
299
- }
300
- /**
301
- * Collect all input transforms for a specific tool
302
- * @private
303
- */
304
- collectTransformsForTool(tool) {
305
- const transforms = [];
306
- const opts = this.options.inputTransforms;
307
- if (!opts)
308
- return transforms;
309
- // 1. Add global transforms
310
- if (opts.global) {
311
- transforms.push(...opts.global);
312
- }
313
- // 2. Add per-tool transforms
314
- if (opts.perTool?.[tool.name]) {
315
- transforms.push(...opts.perTool[tool.name]);
316
- }
317
- // 3. Add generator-produced transforms
318
- if (opts.generator) {
319
- transforms.push(...opts.generator(tool));
320
- }
321
- return transforms;
322
- }
323
- /**
324
- * Apply input transforms to an OpenAPI tool
325
- * - Removes transformed inputKeys from the inputSchema
326
- * - Stores transform metadata for runtime injection
327
- * @private
328
- */
329
- applyInputTransforms(tool) {
330
- const transforms = this.collectTransformsForTool(tool);
331
- if (transforms.length === 0)
332
- return tool;
333
- // Validate input keys against reserved keys (prototype pollution protection)
334
- for (const transform of transforms) {
335
- if (RESERVED_KEYS.includes(transform.inputKey)) {
336
- throw new Error(`Invalid inputKey '${transform.inputKey}' in tool '${tool.name}': ` +
337
- `reserved keys (${RESERVED_KEYS.join(', ')}) cannot be used`);
338
- }
339
- }
340
- const transformedInputKeys = new Set(transforms.map((t) => t.inputKey));
341
- // Clone and modify inputSchema to remove transformed keys
342
- const inputSchema = tool.inputSchema;
343
- const properties = inputSchema?.['properties'] || {};
344
- const required = inputSchema?.['required'] || [];
345
- // Remove transformed keys from properties
346
- const newProperties = { ...properties };
347
- for (const key of transformedInputKeys) {
348
- delete newProperties[key];
349
- }
350
- // Update required array to exclude transformed keys
351
- const newRequired = required.filter((key) => !transformedInputKeys.has(key));
352
- this.logger.debug(`Applied ${transforms.length} input transforms to tool '${tool.name}'`);
353
- const metadataRecord = tool.metadata;
354
- const existingAdapter = metadataRecord['adapter'];
355
- return {
356
- ...tool,
357
- inputSchema: {
358
- ...inputSchema,
359
- properties: newProperties,
360
- ...(newRequired.length > 0 ? { required: newRequired } : {}),
361
- },
362
- // Store transforms in metadata for runtime use
363
- metadata: {
364
- ...tool.metadata,
365
- adapter: {
366
- ...(existingAdapter || {}),
367
- inputTransforms: transforms,
368
- },
369
- },
370
- };
371
- }
372
- /**
373
- * Filter security schemes in tool input based on securitySchemesInInput option.
374
- * Removes security inputs that should be resolved from context instead of user input.
375
- * @private
376
- */
377
- filterSecuritySchemes(tool) {
378
- const allowedSchemes = new Set(this.options.securitySchemesInInput || []);
379
- if (allowedSchemes.size === 0)
380
- return tool;
381
- // Find security mappers that should NOT be in input (resolved from context)
382
- const schemesToRemove = new Set();
383
- const inputKeysToRemove = new Set();
384
- for (const mapper of tool.mapper) {
385
- if (mapper.security?.scheme && !allowedSchemes.has(mapper.security.scheme)) {
386
- schemesToRemove.add(mapper.security.scheme);
387
- inputKeysToRemove.add(mapper.inputKey);
388
- }
389
- }
390
- if (inputKeysToRemove.size === 0)
391
- return tool;
392
- // Remove security inputs from inputSchema
393
- const inputSchema = tool.inputSchema;
394
- const properties = inputSchema?.['properties'] || {};
395
- const required = inputSchema?.['required'] || [];
396
- const newProperties = { ...properties };
397
- for (const key of inputKeysToRemove) {
398
- delete newProperties[key];
399
- }
400
- const newRequired = required.filter((key) => !inputKeysToRemove.has(key));
401
- this.logger.debug(`[${tool.name}] Filtered security schemes from input: ${Array.from(schemesToRemove).join(', ')}. ` +
402
- `Kept in input: ${Array.from(allowedSchemes)
403
- .filter((s) => !schemesToRemove.has(s))
404
- .join(', ') || 'none'}`);
405
- const metadataRecord = tool.metadata;
406
- const existingAdapter = metadataRecord['adapter'];
407
- return {
408
- ...tool,
409
- inputSchema: {
410
- ...inputSchema,
411
- properties: newProperties,
412
- ...(newRequired.length > 0 ? { required: newRequired } : {}),
413
- },
414
- // Store which security schemes are in input vs context for later resolution
415
- metadata: {
416
- ...tool.metadata,
417
- adapter: {
418
- ...(existingAdapter || {}),
419
- securitySchemesInInput: Array.from(allowedSchemes),
420
- securitySchemesFromContext: Array.from(schemesToRemove),
421
- },
422
- },
423
- };
424
- }
425
- };
426
- OpenapiAdapter = tslib_1.__decorate([
427
- (0, sdk_1.Adapter)({
428
- name: 'openapi',
429
- description: 'OpenAPI adapter for FrontMCP - Automatically generates MCP tools from OpenAPI specifications',
430
- }),
431
- tslib_1.__metadata("design:paramtypes", [Object])
432
- ], OpenapiAdapter);
433
- exports.default = OpenapiAdapter;
434
- //# sourceMappingURL=openapi.adapter.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"openapi.adapter.js","sourceRoot":"","sources":["../../../src/openapi/openapi.adapter.ts"],"names":[],"mappings":"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","sourcesContent":["import { Adapter, DynamicAdapter, FrontMcpAdapterResponse, FrontMcpLogger } from '@frontmcp/sdk';\nimport { OpenApiAdapterOptions, InputTransform, ToolTransform, ExtendedMcpOpenAPITool } from './openapi.types';\nimport { OpenAPIToolGenerator, McpOpenAPITool } from 'mcp-from-openapi';\nimport { createOpenApiTool } from './openapi.tool';\nimport { validateSecurityConfiguration } from './openapi.security';\n\n/** Reserved keys that cannot be used as inputKey (prototype pollution protection) */\nconst RESERVED_KEYS = ['__proto__', 'constructor', 'prototype'];\n\n/**\n * Creates a simple console-based logger for use outside the SDK context.\n */\nfunction createConsoleLogger(prefix: string): FrontMcpLogger {\n const formatMessage = (level: string, msg: string) => `[${prefix}] ${level}: ${msg}`;\n return {\n verbose: (msg: string, ...args: unknown[]) => console.debug(formatMessage('VERBOSE', msg), ...args),\n debug: (msg: string, ...args: unknown[]) => console.debug(formatMessage('DEBUG', msg), ...args),\n info: (msg: string, ...args: unknown[]) => console.info(formatMessage('INFO', msg), ...args),\n warn: (msg: string, ...args: unknown[]) => console.warn(formatMessage('WARN', msg), ...args),\n error: (msg: string, ...args: unknown[]) => console.error(formatMessage('ERROR', msg), ...args),\n child: (childPrefix: string) => createConsoleLogger(`${prefix}:${childPrefix}`),\n };\n}\n\n@Adapter({\n name: 'openapi',\n description: 'OpenAPI adapter for FrontMCP - Automatically generates MCP tools from OpenAPI specifications',\n})\nexport default class OpenapiAdapter extends DynamicAdapter<OpenApiAdapterOptions> {\n private generator?: OpenAPIToolGenerator;\n private logger: FrontMcpLogger;\n public options: OpenApiAdapterOptions;\n\n constructor(options: OpenApiAdapterOptions) {\n super();\n this.options = options;\n // Use provided logger or create console fallback\n this.logger = options.logger ?? createConsoleLogger(`openapi:${options.name}`);\n }\n\n /**\n * Receive the SDK logger. Called by the SDK before fetch().\n */\n setLogger(logger: FrontMcpLogger): void {\n this.logger = logger;\n }\n\n async fetch(): Promise<FrontMcpAdapterResponse> {\n // Lazy load: Initialize generator on first fetch if not already initialized\n if (!this.generator) {\n this.generator = await this.initializeGenerator();\n }\n\n // Determine if we need security in input\n // If securitySchemesInInput is set, we need all security in input first, then filter\n const hasPerSchemeControl = this.options.securitySchemesInInput && this.options.securitySchemesInInput.length > 0;\n const includeSecurityInInput =\n hasPerSchemeControl || (this.options.generateOptions?.includeSecurityInInput ?? false);\n\n // Generate tools from OpenAPI spec\n let openapiTools = await this.generator.generateTools({\n includeOperations: this.options.generateOptions?.includeOperations,\n excludeOperations: this.options.generateOptions?.excludeOperations,\n filterFn: this.options.generateOptions?.filterFn,\n namingStrategy: this.options.generateOptions?.namingStrategy,\n preferredStatusCodes: this.options.generateOptions?.preferredStatusCodes ?? [200, 201, 202, 204],\n includeDeprecated: this.options.generateOptions?.includeDeprecated ?? false,\n includeAllResponses: this.options.generateOptions?.includeAllResponses ?? true,\n includeSecurityInInput: includeSecurityInInput,\n maxSchemaDepth: this.options.generateOptions?.maxSchemaDepth,\n includeExamples: this.options.generateOptions?.includeExamples,\n });\n\n // If per-scheme control is enabled, filter security inputs\n if (hasPerSchemeControl) {\n openapiTools = openapiTools.map((tool) => this.filterSecuritySchemes(tool));\n }\n\n // Validate security configuration\n const validation = validateSecurityConfiguration(openapiTools, this.options);\n\n // Log security information\n this.logger.info('Security Analysis:');\n this.logger.info(` Security Risk Score: ${validation.securityRiskScore.toUpperCase()}`);\n this.logger.info(` Valid Configuration: ${validation.valid ? 'YES' : 'NO'}`);\n\n if (validation.warnings.length > 0) {\n this.logger.info('Messages:');\n validation.warnings.forEach((warning) => {\n if (warning.startsWith('ERROR:')) {\n this.logger.error(` - ${warning}`);\n } else if (warning.startsWith('SECURITY WARNING:')) {\n this.logger.warn(` - ${warning}`);\n } else {\n this.logger.info(` - ${warning}`);\n }\n });\n }\n\n // Fail if configuration is invalid and security is required\n if (!validation.valid) {\n throw new Error(\n `[OpenAPI Adapter: ${this.options.name}] Invalid security configuration.\\n` +\n `Missing auth provider mappings for security schemes: ${validation.missingMappings.join(', ')}\\n\\n` +\n `Your OpenAPI spec requires these security schemes, but no auth configuration was provided.\\n\\n` +\n `Add one of the following to your adapter configuration:\\n\\n` +\n `1. authProviderMapper (recommended):\\n` +\n ` authProviderMapper: {\\n` +\n validation.missingMappings\n .map((s) => ` '${s}': (authInfo) => authInfo.user?.${s.toLowerCase()}Token,`)\n .join('\\n') +\n `\\n }\\n\\n` +\n `2. securityResolver:\\n` +\n ` securityResolver: (tool, authInfo) => ({ jwt: authInfo.token })\\n\\n` +\n `3. staticAuth:\\n` +\n ` staticAuth: { jwt: process.env.API_TOKEN }\\n\\n` +\n `4. Include security in input (NOT recommended for production):\\n` +\n ` generateOptions: { includeSecurityInInput: true }`,\n );\n }\n\n // Apply all transforms to tools\n let transformedTools = openapiTools;\n\n // 1. Apply description mode (generates description from summary/description)\n if (this.options.descriptionMode && this.options.descriptionMode !== 'summaryOnly') {\n transformedTools = transformedTools.map((tool) => this.applyDescriptionMode(tool));\n }\n\n // 2. Apply tool transforms (annotations, name, description overrides, etc.)\n if (this.options.toolTransforms) {\n transformedTools = transformedTools.map((tool) => this.applyToolTransforms(tool));\n }\n\n // 3. Apply input transforms (hide inputs, inject values at runtime)\n if (this.options.inputTransforms) {\n transformedTools = transformedTools.map((tool) => this.applyInputTransforms(tool));\n }\n\n // Convert OpenAPI tools to FrontMCP tools\n const tools = transformedTools.map((openapiTool) => createOpenApiTool(openapiTool, this.options, this.logger));\n\n return { tools };\n }\n\n /**\n * Initialize the OpenAPI tool generator from URL or spec\n * @private\n */\n private async initializeGenerator(): Promise<OpenAPIToolGenerator> {\n if ('url' in this.options) {\n return await OpenAPIToolGenerator.fromURL(this.options.url, {\n baseUrl: this.options.baseUrl,\n validate: this.options.loadOptions?.validate ?? true,\n dereference: this.options.loadOptions?.dereference ?? true,\n headers: this.options.loadOptions?.headers,\n timeout: this.options.loadOptions?.timeout,\n followRedirects: this.options.loadOptions?.followRedirects,\n });\n } else if ('spec' in this.options) {\n return await OpenAPIToolGenerator.fromJSON(this.options.spec, {\n baseUrl: this.options.baseUrl,\n validate: this.options.loadOptions?.validate ?? true,\n dereference: this.options.loadOptions?.dereference ?? true,\n });\n } else {\n throw new Error('Either url or spec must be provided in OpenApiAdapterOptions');\n }\n }\n\n /**\n * Apply description mode to generate description from summary/description\n * @private\n */\n private applyDescriptionMode(tool: McpOpenAPITool): McpOpenAPITool {\n const mode = this.options.descriptionMode || 'summaryOnly';\n const metadata = tool.metadata as unknown as Record<string, unknown>;\n const summary = metadata['operationSummary'] as string | undefined;\n const opDescription = metadata['operationDescription'] as string | undefined;\n const operationId = metadata['operationId'] as string | undefined;\n const method = metadata['method'] as string;\n const path = metadata['path'] as string;\n\n let description: string;\n\n switch (mode) {\n case 'descriptionOnly':\n description = opDescription || summary || `${method.toUpperCase()} ${path}`;\n break;\n case 'combined':\n if (summary && opDescription) {\n description = `${summary}\\n\\n${opDescription}`;\n } else {\n description = summary || opDescription || `${method.toUpperCase()} ${path}`;\n }\n break;\n case 'full': {\n const parts: string[] = [];\n if (summary) parts.push(summary);\n if (opDescription && opDescription !== summary) parts.push(opDescription);\n if (operationId) parts.push(`Operation: ${operationId}`);\n parts.push(`${method.toUpperCase()} ${path}`);\n description = parts.join('\\n\\n');\n break;\n }\n default:\n // 'summaryOnly' - use existing description\n return tool;\n }\n\n return {\n ...tool,\n description,\n };\n }\n\n /**\n * Collect tool transforms for a specific tool\n * @private\n */\n private collectToolTransforms(tool: McpOpenAPITool): ToolTransform {\n const result: ToolTransform = {};\n const opts = this.options.toolTransforms;\n if (!opts) return result;\n\n // 1. Apply global transforms\n if (opts.global) {\n Object.assign(result, opts.global);\n if (opts.global.annotations) {\n result.annotations = { ...opts.global.annotations };\n }\n if (opts.global.tags) {\n result.tags = [...opts.global.tags];\n }\n if (opts.global.examples) {\n result.examples = [...opts.global.examples];\n }\n }\n\n // 2. Apply per-tool transforms (override global)\n if (opts.perTool?.[tool.name]) {\n const perTool = opts.perTool[tool.name];\n if (perTool.name) result.name = perTool.name;\n if (perTool.description) result.description = perTool.description;\n if (perTool.hideFromDiscovery !== undefined) result.hideFromDiscovery = perTool.hideFromDiscovery;\n if (perTool.ui) result.ui = perTool.ui;\n if (perTool.annotations) {\n result.annotations = { ...result.annotations, ...perTool.annotations };\n }\n if (perTool.tags) {\n result.tags = [...(result.tags || []), ...perTool.tags];\n }\n if (perTool.examples) {\n result.examples = [...(result.examples || []), ...perTool.examples];\n }\n }\n\n // 3. Apply generator-produced transforms (override per-tool)\n if (opts.generator) {\n const generated = opts.generator(tool);\n if (generated) {\n if (generated.name) result.name = generated.name;\n if (generated.description) result.description = generated.description;\n if (generated.hideFromDiscovery !== undefined) result.hideFromDiscovery = generated.hideFromDiscovery;\n if (generated.ui) result.ui = generated.ui;\n if (generated.annotations) {\n result.annotations = { ...result.annotations, ...generated.annotations };\n }\n if (generated.tags) {\n result.tags = [...(result.tags || []), ...generated.tags];\n }\n if (generated.examples) {\n result.examples = [...(result.examples || []), ...generated.examples];\n }\n }\n }\n\n return result;\n }\n\n /**\n * Apply tool transforms to an OpenAPI tool\n * @private\n */\n private applyToolTransforms(tool: McpOpenAPITool): McpOpenAPITool {\n const transforms = this.collectToolTransforms(tool);\n if (Object.keys(transforms).length === 0) return tool;\n\n let newName = tool.name;\n let newDescription = tool.description;\n\n // Apply name transform\n if (transforms.name) {\n newName = typeof transforms.name === 'function' ? transforms.name(tool.name, tool) : transforms.name;\n }\n\n // Apply description transform\n if (transforms.description) {\n newDescription =\n typeof transforms.description === 'function'\n ? transforms.description(tool.description, tool)\n : transforms.description;\n }\n\n this.logger.debug(`Applied tool transforms to '${tool.name}'`);\n\n const metadataRecord = tool.metadata as unknown as Record<string, unknown>;\n const existingAdapter = metadataRecord['adapter'] as Record<string, unknown> | undefined;\n return {\n ...tool,\n name: newName,\n description: newDescription,\n metadata: {\n ...tool.metadata,\n adapter: {\n ...(existingAdapter || {}),\n toolTransform: transforms,\n },\n },\n } as ExtendedMcpOpenAPITool;\n }\n\n /**\n * Collect all input transforms for a specific tool\n * @private\n */\n private collectTransformsForTool(tool: McpOpenAPITool): InputTransform[] {\n const transforms: InputTransform[] = [];\n const opts = this.options.inputTransforms;\n if (!opts) return transforms;\n\n // 1. Add global transforms\n if (opts.global) {\n transforms.push(...opts.global);\n }\n\n // 2. Add per-tool transforms\n if (opts.perTool?.[tool.name]) {\n transforms.push(...opts.perTool[tool.name]);\n }\n\n // 3. Add generator-produced transforms\n if (opts.generator) {\n transforms.push(...opts.generator(tool));\n }\n\n return transforms;\n }\n\n /**\n * Apply input transforms to an OpenAPI tool\n * - Removes transformed inputKeys from the inputSchema\n * - Stores transform metadata for runtime injection\n * @private\n */\n private applyInputTransforms(tool: McpOpenAPITool): McpOpenAPITool {\n const transforms = this.collectTransformsForTool(tool);\n if (transforms.length === 0) return tool;\n\n // Validate input keys against reserved keys (prototype pollution protection)\n for (const transform of transforms) {\n if (RESERVED_KEYS.includes(transform.inputKey)) {\n throw new Error(\n `Invalid inputKey '${transform.inputKey}' in tool '${tool.name}': ` +\n `reserved keys (${RESERVED_KEYS.join(', ')}) cannot be used`,\n );\n }\n }\n\n const transformedInputKeys = new Set(transforms.map((t) => t.inputKey));\n\n // Clone and modify inputSchema to remove transformed keys\n const inputSchema = tool.inputSchema as Record<string, unknown>;\n const properties = (inputSchema?.['properties'] as Record<string, unknown>) || {};\n const required = (inputSchema?.['required'] as string[]) || [];\n\n // Remove transformed keys from properties\n const newProperties = { ...properties };\n for (const key of transformedInputKeys) {\n delete newProperties[key];\n }\n\n // Update required array to exclude transformed keys\n const newRequired = required.filter((key) => !transformedInputKeys.has(key));\n\n this.logger.debug(`Applied ${transforms.length} input transforms to tool '${tool.name}'`);\n\n const metadataRecord = tool.metadata as unknown as Record<string, unknown>;\n const existingAdapter = metadataRecord['adapter'] as Record<string, unknown> | undefined;\n return {\n ...tool,\n inputSchema: {\n ...inputSchema,\n properties: newProperties,\n ...(newRequired.length > 0 ? { required: newRequired } : {}),\n },\n // Store transforms in metadata for runtime use\n metadata: {\n ...tool.metadata,\n adapter: {\n ...(existingAdapter || {}),\n inputTransforms: transforms,\n },\n },\n } as ExtendedMcpOpenAPITool;\n }\n\n /**\n * Filter security schemes in tool input based on securitySchemesInInput option.\n * Removes security inputs that should be resolved from context instead of user input.\n * @private\n */\n private filterSecuritySchemes(tool: McpOpenAPITool): McpOpenAPITool {\n const allowedSchemes = new Set(this.options.securitySchemesInInput || []);\n if (allowedSchemes.size === 0) return tool;\n\n // Find security mappers that should NOT be in input (resolved from context)\n const schemesToRemove = new Set<string>();\n const inputKeysToRemove = new Set<string>();\n\n for (const mapper of tool.mapper) {\n if (mapper.security?.scheme && !allowedSchemes.has(mapper.security.scheme)) {\n schemesToRemove.add(mapper.security.scheme);\n inputKeysToRemove.add(mapper.inputKey);\n }\n }\n\n if (inputKeysToRemove.size === 0) return tool;\n\n // Remove security inputs from inputSchema\n const inputSchema = tool.inputSchema as Record<string, unknown>;\n const properties = (inputSchema?.['properties'] as Record<string, unknown>) || {};\n const required = (inputSchema?.['required'] as string[]) || [];\n\n const newProperties = { ...properties };\n for (const key of inputKeysToRemove) {\n delete newProperties[key];\n }\n\n const newRequired = required.filter((key) => !inputKeysToRemove.has(key));\n\n this.logger.debug(\n `[${tool.name}] Filtered security schemes from input: ${Array.from(schemesToRemove).join(', ')}. ` +\n `Kept in input: ${\n Array.from(allowedSchemes)\n .filter((s) => !schemesToRemove.has(s))\n .join(', ') || 'none'\n }`,\n );\n\n const metadataRecord = tool.metadata as unknown as Record<string, unknown>;\n const existingAdapter = metadataRecord['adapter'] as Record<string, unknown> | undefined;\n return {\n ...tool,\n inputSchema: {\n ...inputSchema,\n properties: newProperties,\n ...(newRequired.length > 0 ? { required: newRequired } : {}),\n },\n // Store which security schemes are in input vs context for later resolution\n metadata: {\n ...tool.metadata,\n adapter: {\n ...(existingAdapter || {}),\n securitySchemesInInput: Array.from(allowedSchemes),\n securitySchemesFromContext: Array.from(schemesToRemove),\n },\n },\n } as ExtendedMcpOpenAPITool;\n }\n}\n"]}