@frontmcp/adapters 0.5.0 → 0.6.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.
@@ -1,6 +1,330 @@
1
- import { AuthInfo } from '@modelcontextprotocol/sdk/server/auth/types.js';
2
- import { OpenAPIV3 } from 'openapi-types';
3
- import type { LoadOptions, GenerateOptions, McpOpenAPITool, SecurityContext } from 'mcp-from-openapi';
1
+ import { OpenAPIV3, OpenAPIV3_1 } from 'openapi-types';
2
+ import type { LoadOptions, GenerateOptions, McpOpenAPITool, SecurityContext, ToolMetadata } from 'mcp-from-openapi';
3
+ import type { FrontMcpLogger, ToolAnnotations, ToolExample, ToolUIConfig, FrontMcpContext } from '@frontmcp/sdk';
4
+ /**
5
+ * Context available when injecting values at request time
6
+ */
7
+ export interface InputTransformContext {
8
+ /** FrontMCP request context with authInfo, sessionId, traceId, etc. */
9
+ ctx: FrontMcpContext;
10
+ /** Environment variables */
11
+ env: NodeJS.ProcessEnv;
12
+ /** The OpenAPI tool being executed */
13
+ tool: McpOpenAPITool;
14
+ }
15
+ /**
16
+ * Single input transform configuration.
17
+ * Removes an input from the schema and injects its value at request time.
18
+ */
19
+ export interface InputTransform {
20
+ /**
21
+ * The input key (property name in inputSchema) to transform.
22
+ * This input will be removed from the schema visible to AI/users.
23
+ */
24
+ inputKey: string;
25
+ /**
26
+ * Value injector function called at request time.
27
+ * Returns the value to inject for this input.
28
+ */
29
+ inject: (ctx: InputTransformContext) => unknown | Promise<unknown>;
30
+ }
31
+ /**
32
+ * Input transform configuration options.
33
+ * Supports global, per-tool, and dynamic transforms.
34
+ */
35
+ export interface InputTransformOptions {
36
+ /**
37
+ * Global transforms applied to ALL tools.
38
+ * Use for common patterns like tenant headers.
39
+ */
40
+ global?: InputTransform[];
41
+ /**
42
+ * Per-tool transforms keyed by tool name.
43
+ * These are combined with global transforms.
44
+ */
45
+ perTool?: Record<string, InputTransform[]>;
46
+ /**
47
+ * Dynamic transform generator function.
48
+ * Called for each tool to generate transforms programmatically.
49
+ * Useful when transforms depend on tool metadata.
50
+ */
51
+ generator?: (tool: McpOpenAPITool) => InputTransform[];
52
+ }
53
+ /**
54
+ * The OpenAPI extension key for FrontMCP metadata.
55
+ * Add this to operations in your OpenAPI spec to configure tool behavior.
56
+ *
57
+ * @example OpenAPI YAML
58
+ * ```yaml
59
+ * paths:
60
+ * /users:
61
+ * get:
62
+ * operationId: listUsers
63
+ * summary: List all users
64
+ * x-frontmcp:
65
+ * annotations:
66
+ * readOnlyHint: true
67
+ * idempotentHint: true
68
+ * cache:
69
+ * ttl: 300
70
+ * tags:
71
+ * - users
72
+ * ```
73
+ */
74
+ export declare const FRONTMCP_EXTENSION_KEY = "x-frontmcp";
75
+ /**
76
+ * Cache configuration for tools.
77
+ */
78
+ export interface FrontMcpCacheConfig {
79
+ /**
80
+ * Time-to-live in seconds for cached responses.
81
+ */
82
+ ttl?: number;
83
+ /**
84
+ * If true, cache window slides on each access.
85
+ * If false, cache expires at fixed time from first access.
86
+ */
87
+ slideWindow?: boolean;
88
+ }
89
+ /**
90
+ * CodeCall configuration for tools.
91
+ */
92
+ export interface FrontMcpCodeCallConfig {
93
+ /**
94
+ * Whether this tool can be used via CodeCall.
95
+ * @default true
96
+ */
97
+ enabledInCodeCall?: boolean;
98
+ /**
99
+ * If true, this tool stays visible in `list_tools`
100
+ * even when CodeCall is hiding most tools.
101
+ * @default false
102
+ */
103
+ visibleInListTools?: boolean;
104
+ }
105
+ /**
106
+ * Tool annotations that hint at tool behavior.
107
+ * These map directly to MCP ToolAnnotations.
108
+ */
109
+ export interface FrontMcpAnnotations {
110
+ /**
111
+ * A human-readable title for the tool.
112
+ */
113
+ title?: string;
114
+ /**
115
+ * If true, the tool does not modify its environment.
116
+ * @default false
117
+ */
118
+ readOnlyHint?: boolean;
119
+ /**
120
+ * If true, the tool may perform destructive updates.
121
+ * If false, the tool performs only additive updates.
122
+ * (Meaningful only when readOnlyHint == false)
123
+ * @default true
124
+ */
125
+ destructiveHint?: boolean;
126
+ /**
127
+ * If true, calling repeatedly with same args has no additional effect.
128
+ * (Meaningful only when readOnlyHint == false)
129
+ * @default false
130
+ */
131
+ idempotentHint?: boolean;
132
+ /**
133
+ * If true, tool may interact with external entities (open world).
134
+ * If false, tool's domain is closed (e.g., memory tool).
135
+ * @default true
136
+ */
137
+ openWorldHint?: boolean;
138
+ }
139
+ /**
140
+ * FrontMCP extension schema for OpenAPI operations.
141
+ * Add `x-frontmcp` to any operation to configure tool behavior.
142
+ *
143
+ * @example
144
+ * ```yaml
145
+ * x-frontmcp:
146
+ * annotations:
147
+ * readOnlyHint: true
148
+ * idempotentHint: true
149
+ * cache:
150
+ * ttl: 300
151
+ * codecall:
152
+ * enabledInCodeCall: true
153
+ * visibleInListTools: true
154
+ * tags:
155
+ * - users
156
+ * - public-api
157
+ * hideFromDiscovery: false
158
+ * ```
159
+ */
160
+ export interface FrontMcpExtension {
161
+ /**
162
+ * Tool annotations for AI behavior hints.
163
+ */
164
+ annotations?: FrontMcpAnnotations;
165
+ /**
166
+ * Cache configuration for response caching.
167
+ */
168
+ cache?: FrontMcpCacheConfig;
169
+ /**
170
+ * CodeCall-specific configuration.
171
+ */
172
+ codecall?: FrontMcpCodeCallConfig;
173
+ /**
174
+ * Tags/labels for categorization and filtering.
175
+ */
176
+ tags?: string[];
177
+ /**
178
+ * If true, hide tool from discovery/listing.
179
+ * @default false
180
+ */
181
+ hideFromDiscovery?: boolean;
182
+ /**
183
+ * Usage examples for the tool.
184
+ */
185
+ examples?: Array<{
186
+ description: string;
187
+ input: Record<string, unknown>;
188
+ output?: unknown;
189
+ }>;
190
+ }
191
+ /**
192
+ * How to generate tool descriptions from OpenAPI operations.
193
+ * - 'summaryOnly': Use only the operation summary (default, current behavior)
194
+ * - 'descriptionOnly': Use only the operation description
195
+ * - 'combined': Combine summary and description (summary first, then description)
196
+ * - 'full': Include summary, description, and operation ID
197
+ */
198
+ export type DescriptionMode = 'summaryOnly' | 'descriptionOnly' | 'combined' | 'full';
199
+ /**
200
+ * Transform configuration for modifying generated tools.
201
+ * Can override or augment any tool property.
202
+ */
203
+ export interface ToolTransform {
204
+ /**
205
+ * Override or transform the tool name.
206
+ * - string: Replace the name entirely
207
+ * - function: Transform the existing name
208
+ */
209
+ name?: string | ((originalName: string, tool: McpOpenAPITool) => string);
210
+ /**
211
+ * Override or transform the tool description.
212
+ * - string: Replace the description entirely
213
+ * - function: Transform with access to original description and tool metadata
214
+ *
215
+ * @example
216
+ * ```typescript
217
+ * // Combine summary and description
218
+ * description: (original, tool) => {
219
+ * const summary = tool.metadata.operationSummary || '';
220
+ * const desc = tool.metadata.operationDescription || '';
221
+ * return summary && desc ? `${summary}\n\n${desc}` : original;
222
+ * }
223
+ * ```
224
+ */
225
+ description?: string | ((originalDescription: string, tool: McpOpenAPITool) => string);
226
+ /**
227
+ * Annotations to add or merge with existing tool annotations.
228
+ * These hint at tool behavior for AI clients.
229
+ *
230
+ * @example
231
+ * ```typescript
232
+ * annotations: {
233
+ * readOnlyHint: true, // Tool doesn't modify state
234
+ * openWorldHint: true, // Tool interacts with external systems
235
+ * destructiveHint: false, // Tool doesn't delete data
236
+ * idempotentHint: true, // Repeated calls have same effect
237
+ * }
238
+ * ```
239
+ */
240
+ annotations?: ToolAnnotations;
241
+ /**
242
+ * UI configuration for the tool (forms, rendering hints).
243
+ */
244
+ ui?: ToolUIConfig;
245
+ /**
246
+ * If true, hide the tool from tool discovery/listing.
247
+ * The tool can still be called directly.
248
+ */
249
+ hideFromDiscovery?: boolean;
250
+ /**
251
+ * Tags to add to the tool for categorization.
252
+ */
253
+ tags?: string[];
254
+ /**
255
+ * Usage examples to add to the tool.
256
+ */
257
+ examples?: ToolExample[];
258
+ }
259
+ /**
260
+ * Tool transform configuration options.
261
+ * Supports global, per-tool, and dynamic transforms.
262
+ */
263
+ export interface ToolTransformOptions {
264
+ /**
265
+ * Global transforms applied to ALL tools.
266
+ * Use for common patterns like adding readOnlyHint to all GET operations.
267
+ */
268
+ global?: ToolTransform;
269
+ /**
270
+ * Per-tool transforms keyed by tool name.
271
+ * Takes precedence over global transforms for overlapping properties.
272
+ */
273
+ perTool?: Record<string, ToolTransform>;
274
+ /**
275
+ * Dynamic transform generator function.
276
+ * Called for each tool to generate transforms programmatically.
277
+ * Useful when transforms depend on tool metadata (e.g., HTTP method).
278
+ *
279
+ * @example
280
+ * ```typescript
281
+ * generator: (tool) => {
282
+ * // Mark all GET operations as read-only
283
+ * if (tool.metadata.method === 'get') {
284
+ * return {
285
+ * annotations: { readOnlyHint: true, destructiveHint: false },
286
+ * };
287
+ * }
288
+ * // Mark DELETE operations as destructive
289
+ * if (tool.metadata.method === 'delete') {
290
+ * return {
291
+ * annotations: { destructiveHint: true },
292
+ * };
293
+ * }
294
+ * return undefined;
295
+ * }
296
+ * ```
297
+ */
298
+ generator?: (tool: McpOpenAPITool) => ToolTransform | undefined;
299
+ }
300
+ /**
301
+ * Extended tool metadata that includes adapter-specific fields.
302
+ * This extends the base ToolMetadata from mcp-from-openapi with
303
+ * fields used for transforms and extensions.
304
+ */
305
+ export interface ExtendedToolMetadata extends ToolMetadata {
306
+ /**
307
+ * Adapter-specific runtime configuration.
308
+ * Contains transforms and other metadata added during tool processing.
309
+ */
310
+ adapter?: {
311
+ /** Input transforms to apply at request time */
312
+ inputTransforms?: InputTransform[];
313
+ /** Tool transform configuration */
314
+ toolTransform?: ToolTransform;
315
+ /** Security schemes that are included in tool input (user provides) */
316
+ securitySchemesInInput?: string[];
317
+ /** Security schemes resolved from context (authProviderMapper, etc.) */
318
+ securitySchemesFromContext?: string[];
319
+ };
320
+ }
321
+ /**
322
+ * McpOpenAPITool with extended metadata type.
323
+ * Use this type when accessing adapter-extended metadata.
324
+ */
325
+ export interface ExtendedMcpOpenAPITool extends Omit<McpOpenAPITool, 'metadata'> {
326
+ metadata: ExtendedToolMetadata;
327
+ }
4
328
  interface BaseOptions {
5
329
  /**
6
330
  * The name of the adapter.
@@ -28,10 +352,10 @@ interface BaseOptions {
28
352
  * For example, mapping tenantId from authenticated session payload to
29
353
  * a specific header, this key will be hidden to mcp clients
30
354
  * and filled by the adapter before sending the request to the API.
31
- * @param authInfo
355
+ * @param ctx - FrontMCP request context with authInfo, sessionId, traceId, etc.
32
356
  * @param headers
33
357
  */
34
- headersMapper?: (authInfo: AuthInfo, headers: Headers) => Headers;
358
+ headersMapper?: (ctx: FrontMcpContext, headers: Headers) => Headers;
35
359
  /**
36
360
  * This can be used to map request information to specific
37
361
  * body values as required by the API.
@@ -39,10 +363,10 @@ interface BaseOptions {
39
363
  * a specific property in the body, this key will be hidden to mcp clients
40
364
  * and filled by the adapter before sending the request to the API.
41
365
  *
42
- * @param authInfo
366
+ * @param ctx - FrontMCP request context with authInfo, sessionId, traceId, etc.
43
367
  * @param body
44
368
  */
45
- bodyMapper?: (authInfo: AuthInfo, body: Record<string, unknown>) => Record<string, unknown>;
369
+ bodyMapper?: (ctx: FrontMcpContext, body: Record<string, unknown>) => Record<string, unknown>;
46
370
  /**
47
371
  * Custom security resolver for resolving authentication from context.
48
372
  * This allows you to map different auth providers to different tools/security schemes.
@@ -54,7 +378,8 @@ interface BaseOptions {
54
378
  *
55
379
  * @example
56
380
  * ```typescript
57
- * securityResolver: (tool, authInfo) => {
381
+ * securityResolver: (tool, ctx) => {
382
+ * const authInfo = ctx.authInfo;
58
383
  * // Use GitHub token for GitHub API tools
59
384
  * if (tool.name.startsWith('github_')) {
60
385
  * return { jwt: authInfo.user?.githubToken };
@@ -68,7 +393,7 @@ interface BaseOptions {
68
393
  * }
69
394
  * ```
70
395
  */
71
- securityResolver?: (tool: McpOpenAPITool, authInfo: AuthInfo) => SecurityContext | Promise<SecurityContext>;
396
+ securityResolver?: (tool: McpOpenAPITool, ctx: FrontMcpContext) => SecurityContext | Promise<SecurityContext>;
72
397
  /**
73
398
  * Map security scheme names to auth provider extractors.
74
399
  * This allows different security schemes to use different auth providers.
@@ -80,15 +405,15 @@ interface BaseOptions {
80
405
  * ```typescript
81
406
  * authProviderMapper: {
82
407
  * // GitHub OAuth security scheme
83
- * 'GitHubAuth': (authInfo) => authInfo.user?.githubToken,
408
+ * 'GitHubAuth': (ctx) => ctx.authInfo.user?.githubToken,
84
409
  * // Google OAuth security scheme
85
- * 'GoogleAuth': (authInfo) => authInfo.user?.googleToken,
410
+ * 'GoogleAuth': (ctx) => ctx.authInfo.user?.googleToken,
86
411
  * // API Key security scheme
87
- * 'ApiKeyAuth': (authInfo) => authInfo.user?.apiKey,
412
+ * 'ApiKeyAuth': (ctx) => ctx.authInfo.user?.apiKey,
88
413
  * }
89
414
  * ```
90
415
  */
91
- authProviderMapper?: Record<string, (authInfo: AuthInfo) => string | undefined>;
416
+ authProviderMapper?: Record<string, (ctx: FrontMcpContext) => string | undefined>;
92
417
  /**
93
418
  * Static authentication configuration when not using dynamic auth from context.
94
419
  * Useful for server-to-server APIs with static credentials.
@@ -112,12 +437,158 @@ interface BaseOptions {
112
437
  * @see GenerateOptions from mcp-from-openapi
113
438
  */
114
439
  generateOptions?: GenerateOptions;
440
+ /**
441
+ * Specify which security schemes should be included in the tool's input schema.
442
+ * Use this for per-scheme control over authentication handling.
443
+ *
444
+ * - Schemes in this list → included in input (user/AI provides the value)
445
+ * - Schemes NOT in this list → resolved from context (authProviderMapper, staticAuth, etc.)
446
+ *
447
+ * This allows hybrid authentication where some schemes come from user input
448
+ * and others come from the session/context.
449
+ *
450
+ * @example
451
+ * ```typescript
452
+ * // OpenAPI spec has: GitHubAuth (Bearer), ApiKeyAuth (API key)
453
+ * // You want: GitHubAuth from session, ApiKeyAuth from user input
454
+ *
455
+ * const adapter = new OpenapiAdapter({
456
+ * name: 'my-api',
457
+ * baseUrl: 'https://api.example.com',
458
+ * spec: mySpec,
459
+ *
460
+ * // ApiKeyAuth will be in tool input schema
461
+ * securitySchemesInInput: ['ApiKeyAuth'],
462
+ *
463
+ * // GitHubAuth will be resolved from context
464
+ * authProviderMapper: {
465
+ * 'GitHubAuth': (ctx) => ctx.authInfo?.user?.githubToken,
466
+ * },
467
+ * });
468
+ * ```
469
+ */
470
+ securitySchemesInInput?: string[];
471
+ /**
472
+ * Input schema transforms for hiding inputs and injecting values at request time.
473
+ *
474
+ * Use cases:
475
+ * - Hide tenant headers from AI/users and inject from session
476
+ * - Hide internal correlation IDs and inject from environment
477
+ * - Remove API-internal fields that should be computed server-side
478
+ *
479
+ * @example
480
+ * ```typescript
481
+ * inputTransforms: {
482
+ * global: [
483
+ * { inputKey: 'X-Tenant-Id', inject: (ctx) => ctx.authInfo.user?.tenantId },
484
+ * ],
485
+ * perTool: {
486
+ * 'createUser': [
487
+ * { inputKey: 'createdBy', inject: (ctx) => ctx.authInfo.user?.email },
488
+ * ],
489
+ * },
490
+ * generator: (tool) => {
491
+ * if (['post', 'put', 'patch'].includes(tool.metadata.method)) {
492
+ * return [{ inputKey: 'X-Correlation-Id', inject: () => crypto.randomUUID() }];
493
+ * }
494
+ * return [];
495
+ * },
496
+ * }
497
+ * ```
498
+ */
499
+ inputTransforms?: InputTransformOptions;
500
+ /**
501
+ * Tool transforms for modifying generated tools (description, annotations, UI, etc.).
502
+ *
503
+ * Use cases:
504
+ * - Add annotations (readOnlyHint, openWorldHint) based on HTTP method
505
+ * - Override tool descriptions with combined summary + description
506
+ * - Add UI configuration for tool forms
507
+ * - Hide internal tools from discovery
508
+ *
509
+ * @example
510
+ * ```typescript
511
+ * toolTransforms: {
512
+ * global: {
513
+ * annotations: { openWorldHint: true },
514
+ * },
515
+ * perTool: {
516
+ * 'createUser': {
517
+ * annotations: { destructiveHint: false },
518
+ * tags: ['user-management'],
519
+ * },
520
+ * },
521
+ * generator: (tool) => {
522
+ * if (tool.metadata.method === 'get') {
523
+ * return { annotations: { readOnlyHint: true } };
524
+ * }
525
+ * if (tool.metadata.method === 'delete') {
526
+ * return { annotations: { destructiveHint: true } };
527
+ * }
528
+ * return undefined;
529
+ * },
530
+ * }
531
+ * ```
532
+ */
533
+ toolTransforms?: ToolTransformOptions;
534
+ /**
535
+ * How to generate tool descriptions from OpenAPI operations.
536
+ * - 'summaryOnly': Use only summary (default)
537
+ * - 'descriptionOnly': Use only description
538
+ * - 'combined': Summary followed by description
539
+ * - 'full': Summary, description, and operation details
540
+ *
541
+ * @default 'summaryOnly'
542
+ */
543
+ descriptionMode?: DescriptionMode;
544
+ /**
545
+ * Logger instance for adapter diagnostics.
546
+ * Optional - if not provided, the SDK will inject it automatically via setLogger().
547
+ */
548
+ logger?: FrontMcpLogger;
549
+ /**
550
+ * Timeout for HTTP requests in milliseconds.
551
+ * If a request takes longer than this, it will be aborted.
552
+ * @default 30000 (30 seconds)
553
+ */
554
+ requestTimeoutMs?: number;
555
+ /**
556
+ * Maximum request body size in bytes.
557
+ * Requests with bodies larger than this will be rejected before sending.
558
+ * @default 10485760 (10MB)
559
+ */
560
+ maxRequestSize?: number;
561
+ /**
562
+ * Maximum response size in bytes.
563
+ * Responses larger than this will be rejected.
564
+ * The check is performed first on Content-Length header (if present),
565
+ * then on actual response size.
566
+ * @default 10485760 (10MB)
567
+ */
568
+ maxResponseSize?: number;
115
569
  }
116
570
  interface SpecOptions extends BaseOptions {
117
571
  /**
118
- * The OpenAPI specification the OpenAPI specification.
572
+ * The OpenAPI specification as a JSON object.
573
+ *
574
+ * Accepts:
575
+ * - `OpenAPIV3.Document` (typed)
576
+ * - `OpenAPIV3_1.Document` (typed)
577
+ * - Plain object from `import spec from './openapi.json'`
578
+ *
579
+ * @example
580
+ * ```typescript
581
+ * // From typed constant
582
+ * import { OpenAPIV3 } from 'openapi-types';
583
+ * const spec: OpenAPIV3.Document = { ... };
584
+ * new OpenapiAdapter({ spec, ... })
585
+ *
586
+ * // From JSON import
587
+ * import openapiJson from './my-openapi.json';
588
+ * new OpenapiAdapter({ spec: openapiJson, ... })
589
+ * ```
119
590
  */
120
- spec: OpenAPIV3.Document;
591
+ spec: OpenAPIV3.Document | OpenAPIV3_1.Document | object;
121
592
  }
122
593
  interface UrlOptions extends BaseOptions {
123
594
  /**
@@ -1,3 +1,29 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FRONTMCP_EXTENSION_KEY = void 0;
4
+ // ============================================================================
5
+ // OpenAPI Extension Types (x-frontmcp)
6
+ // ============================================================================
7
+ /**
8
+ * The OpenAPI extension key for FrontMCP metadata.
9
+ * Add this to operations in your OpenAPI spec to configure tool behavior.
10
+ *
11
+ * @example OpenAPI YAML
12
+ * ```yaml
13
+ * paths:
14
+ * /users:
15
+ * get:
16
+ * operationId: listUsers
17
+ * summary: List all users
18
+ * x-frontmcp:
19
+ * annotations:
20
+ * readOnlyHint: true
21
+ * idempotentHint: true
22
+ * cache:
23
+ * ttl: 300
24
+ * tags:
25
+ * - users
26
+ * ```
27
+ */
28
+ exports.FRONTMCP_EXTENSION_KEY = 'x-frontmcp';
3
29
  //# sourceMappingURL=openapi.types.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"openapi.types.js","sourceRoot":"","sources":["../../../src/openapi/openapi.types.ts"],"names":[],"mappings":"","sourcesContent":["import { AuthInfo } from '@modelcontextprotocol/sdk/server/auth/types.js';\nimport { OpenAPIV3 } from 'openapi-types';\nimport type { LoadOptions, GenerateOptions, McpOpenAPITool, SecurityContext } from 'mcp-from-openapi';\n\ninterface BaseOptions {\n /**\n * The name of the adapter.\n * This is used to identify the adapter in the MCP configuration.\n * Also used to prefix tools if conflicted with other adapters in the same app.\n */\n name: string;\n\n /**\n * The base URL of the API.\n * This is used to construct the full URL for each request.\n * For example, if the API is hosted at https://api.example.com/v1,\n * the baseUrl should be set to https://api.example.com/v1.\n * This overrides the baseUrl in LoadOptions.\n */\n baseUrl: string;\n\n /**\n * Additional headers to be sent with each request.\n * This can be used to set authentication headers,\n * such as Authorization or API Key.\n */\n additionalHeaders?: Record<string, string>;\n\n /**\n * This can be used to map request information to specific\n * headers as required by the API.\n * For example, mapping tenantId from authenticated session payload to\n * a specific header, this key will be hidden to mcp clients\n * and filled by the adapter before sending the request to the API.\n * @param authInfo\n * @param headers\n */\n headersMapper?: (authInfo: AuthInfo, headers: Headers) => Headers;\n\n /**\n * This can be used to map request information to specific\n * body values as required by the API.\n * For example, mapping tenantId from authenticated session payload to\n * a specific property in the body, this key will be hidden to mcp clients\n * and filled by the adapter before sending the request to the API.\n *\n * @param authInfo\n * @param body\n */\n bodyMapper?: (authInfo: AuthInfo, body: Record<string, unknown>) => Record<string, unknown>;\n\n /**\n * Custom security resolver for resolving authentication from context.\n * This allows you to map different auth providers to different tools/security schemes.\n *\n * Use this when:\n * - You have multiple auth providers (e.g., GitHub OAuth, Google OAuth, API keys)\n * - Different tools need different authentication\n * - You need custom logic to select the right auth provider\n *\n * @example\n * ```typescript\n * securityResolver: (tool, authInfo) => {\n * // Use GitHub token for GitHub API tools\n * if (tool.name.startsWith('github_')) {\n * return { jwt: authInfo.user?.githubToken };\n * }\n * // Use Google token for Google API tools\n * if (tool.name.startsWith('google_')) {\n * return { jwt: authInfo.user?.googleToken };\n * }\n * // Default to main JWT token\n * return { jwt: authInfo.token };\n * }\n * ```\n */\n securityResolver?: (\n tool: McpOpenAPITool,\n authInfo: AuthInfo\n ) => SecurityContext | Promise<SecurityContext>;\n\n /**\n * Map security scheme names to auth provider extractors.\n * This allows different security schemes to use different auth providers.\n *\n * Use this when your OpenAPI spec has multiple security schemes\n * and each should use a different auth provider from the context.\n *\n * @example\n * ```typescript\n * authProviderMapper: {\n * // GitHub OAuth security scheme\n * 'GitHubAuth': (authInfo) => authInfo.user?.githubToken,\n * // Google OAuth security scheme\n * 'GoogleAuth': (authInfo) => authInfo.user?.googleToken,\n * // API Key security scheme\n * 'ApiKeyAuth': (authInfo) => authInfo.user?.apiKey,\n * }\n * ```\n */\n authProviderMapper?: Record<string, (authInfo: AuthInfo) => string | undefined>;\n\n /**\n * Static authentication configuration when not using dynamic auth from context.\n * Useful for server-to-server APIs with static credentials.\n *\n * @example\n * ```typescript\n * staticAuth: {\n * jwt: process.env.API_JWT_TOKEN,\n * apiKey: process.env.API_KEY,\n * }\n * ```\n */\n staticAuth?: Partial<SecurityContext>;\n\n /**\n * Options for loading the OpenAPI specification\n * @see LoadOptions from mcp-from-openapi\n */\n loadOptions?: Omit<LoadOptions, 'baseUrl'>; // baseUrl is in BaseOptions\n\n /**\n * Options for generating tools from the OpenAPI specification\n * @see GenerateOptions from mcp-from-openapi\n */\n generateOptions?: GenerateOptions;\n}\n\ninterface SpecOptions extends BaseOptions {\n /**\n * The OpenAPI specification the OpenAPI specification.\n */\n spec: OpenAPIV3.Document;\n}\n\ninterface UrlOptions extends BaseOptions {\n /**\n * The URL of the OpenAPI specification.\n * Can be a local file path or a remote URL.\n */\n url: string;\n}\n\nexport type OpenApiAdapterOptions = SpecOptions | UrlOptions;\n"]}
1
+ {"version":3,"file":"openapi.types.js","sourceRoot":"","sources":["../../../src/openapi/openapi.types.ts"],"names":[],"mappings":";;;AA+DA,+EAA+E;AAC/E,uCAAuC;AACvC,+EAA+E;AAE/E;;;;;;;;;;;;;;;;;;;;GAoBG;AACU,QAAA,sBAAsB,GAAG,YAAY,CAAC","sourcesContent":["import { OpenAPIV3, OpenAPIV3_1 } from 'openapi-types';\nimport type { LoadOptions, GenerateOptions, McpOpenAPITool, SecurityContext, ToolMetadata } from 'mcp-from-openapi';\nimport type { FrontMcpLogger, ToolAnnotations, ToolExample, ToolUIConfig, FrontMcpContext } from '@frontmcp/sdk';\n\n// ============================================================================\n// Input Transform Types\n// ============================================================================\n\n/**\n * Context available when injecting values at request time\n */\nexport interface InputTransformContext {\n /** FrontMCP request context with authInfo, sessionId, traceId, etc. */\n ctx: FrontMcpContext;\n /** Environment variables */\n env: NodeJS.ProcessEnv;\n /** The OpenAPI tool being executed */\n tool: McpOpenAPITool;\n}\n\n/**\n * Single input transform configuration.\n * Removes an input from the schema and injects its value at request time.\n */\nexport interface InputTransform {\n /**\n * The input key (property name in inputSchema) to transform.\n * This input will be removed from the schema visible to AI/users.\n */\n inputKey: string;\n\n /**\n * Value injector function called at request time.\n * Returns the value to inject for this input.\n */\n inject: (ctx: InputTransformContext) => unknown | Promise<unknown>;\n}\n\n/**\n * Input transform configuration options.\n * Supports global, per-tool, and dynamic transforms.\n */\nexport interface InputTransformOptions {\n /**\n * Global transforms applied to ALL tools.\n * Use for common patterns like tenant headers.\n */\n global?: InputTransform[];\n\n /**\n * Per-tool transforms keyed by tool name.\n * These are combined with global transforms.\n */\n perTool?: Record<string, InputTransform[]>;\n\n /**\n * Dynamic transform generator function.\n * Called for each tool to generate transforms programmatically.\n * Useful when transforms depend on tool metadata.\n */\n generator?: (tool: McpOpenAPITool) => InputTransform[];\n}\n\n// ============================================================================\n// OpenAPI Extension Types (x-frontmcp)\n// ============================================================================\n\n/**\n * The OpenAPI extension key for FrontMCP metadata.\n * Add this to operations in your OpenAPI spec to configure tool behavior.\n *\n * @example OpenAPI YAML\n * ```yaml\n * paths:\n * /users:\n * get:\n * operationId: listUsers\n * summary: List all users\n * x-frontmcp:\n * annotations:\n * readOnlyHint: true\n * idempotentHint: true\n * cache:\n * ttl: 300\n * tags:\n * - users\n * ```\n */\nexport const FRONTMCP_EXTENSION_KEY = 'x-frontmcp';\n\n/**\n * Cache configuration for tools.\n */\nexport interface FrontMcpCacheConfig {\n /**\n * Time-to-live in seconds for cached responses.\n */\n ttl?: number;\n\n /**\n * If true, cache window slides on each access.\n * If false, cache expires at fixed time from first access.\n */\n slideWindow?: boolean;\n}\n\n/**\n * CodeCall configuration for tools.\n */\nexport interface FrontMcpCodeCallConfig {\n /**\n * Whether this tool can be used via CodeCall.\n * @default true\n */\n enabledInCodeCall?: boolean;\n\n /**\n * If true, this tool stays visible in `list_tools`\n * even when CodeCall is hiding most tools.\n * @default false\n */\n visibleInListTools?: boolean;\n}\n\n/**\n * Tool annotations that hint at tool behavior.\n * These map directly to MCP ToolAnnotations.\n */\nexport interface FrontMcpAnnotations {\n /**\n * A human-readable title for the tool.\n */\n title?: string;\n\n /**\n * If true, the tool does not modify its environment.\n * @default false\n */\n readOnlyHint?: boolean;\n\n /**\n * If true, the tool may perform destructive updates.\n * If false, the tool performs only additive updates.\n * (Meaningful only when readOnlyHint == false)\n * @default true\n */\n destructiveHint?: boolean;\n\n /**\n * If true, calling repeatedly with same args has no additional effect.\n * (Meaningful only when readOnlyHint == false)\n * @default false\n */\n idempotentHint?: boolean;\n\n /**\n * If true, tool may interact with external entities (open world).\n * If false, tool's domain is closed (e.g., memory tool).\n * @default true\n */\n openWorldHint?: boolean;\n}\n\n/**\n * FrontMCP extension schema for OpenAPI operations.\n * Add `x-frontmcp` to any operation to configure tool behavior.\n *\n * @example\n * ```yaml\n * x-frontmcp:\n * annotations:\n * readOnlyHint: true\n * idempotentHint: true\n * cache:\n * ttl: 300\n * codecall:\n * enabledInCodeCall: true\n * visibleInListTools: true\n * tags:\n * - users\n * - public-api\n * hideFromDiscovery: false\n * ```\n */\nexport interface FrontMcpExtension {\n /**\n * Tool annotations for AI behavior hints.\n */\n annotations?: FrontMcpAnnotations;\n\n /**\n * Cache configuration for response caching.\n */\n cache?: FrontMcpCacheConfig;\n\n /**\n * CodeCall-specific configuration.\n */\n codecall?: FrontMcpCodeCallConfig;\n\n /**\n * Tags/labels for categorization and filtering.\n */\n tags?: string[];\n\n /**\n * If true, hide tool from discovery/listing.\n * @default false\n */\n hideFromDiscovery?: boolean;\n\n /**\n * Usage examples for the tool.\n */\n examples?: Array<{\n description: string;\n input: Record<string, unknown>;\n output?: unknown;\n }>;\n}\n\n// ============================================================================\n// Tool Transform Types\n// ============================================================================\n\n/**\n * How to generate tool descriptions from OpenAPI operations.\n * - 'summaryOnly': Use only the operation summary (default, current behavior)\n * - 'descriptionOnly': Use only the operation description\n * - 'combined': Combine summary and description (summary first, then description)\n * - 'full': Include summary, description, and operation ID\n */\nexport type DescriptionMode = 'summaryOnly' | 'descriptionOnly' | 'combined' | 'full';\n\n/**\n * Transform configuration for modifying generated tools.\n * Can override or augment any tool property.\n */\nexport interface ToolTransform {\n /**\n * Override or transform the tool name.\n * - string: Replace the name entirely\n * - function: Transform the existing name\n */\n name?: string | ((originalName: string, tool: McpOpenAPITool) => string);\n\n /**\n * Override or transform the tool description.\n * - string: Replace the description entirely\n * - function: Transform with access to original description and tool metadata\n *\n * @example\n * ```typescript\n * // Combine summary and description\n * description: (original, tool) => {\n * const summary = tool.metadata.operationSummary || '';\n * const desc = tool.metadata.operationDescription || '';\n * return summary && desc ? `${summary}\\n\\n${desc}` : original;\n * }\n * ```\n */\n description?: string | ((originalDescription: string, tool: McpOpenAPITool) => string);\n\n /**\n * Annotations to add or merge with existing tool annotations.\n * These hint at tool behavior for AI clients.\n *\n * @example\n * ```typescript\n * annotations: {\n * readOnlyHint: true, // Tool doesn't modify state\n * openWorldHint: true, // Tool interacts with external systems\n * destructiveHint: false, // Tool doesn't delete data\n * idempotentHint: true, // Repeated calls have same effect\n * }\n * ```\n */\n annotations?: ToolAnnotations;\n\n /**\n * UI configuration for the tool (forms, rendering hints).\n */\n ui?: ToolUIConfig;\n\n /**\n * If true, hide the tool from tool discovery/listing.\n * The tool can still be called directly.\n */\n hideFromDiscovery?: boolean;\n\n /**\n * Tags to add to the tool for categorization.\n */\n tags?: string[];\n\n /**\n * Usage examples to add to the tool.\n */\n examples?: ToolExample[];\n}\n\n/**\n * Tool transform configuration options.\n * Supports global, per-tool, and dynamic transforms.\n */\nexport interface ToolTransformOptions {\n /**\n * Global transforms applied to ALL tools.\n * Use for common patterns like adding readOnlyHint to all GET operations.\n */\n global?: ToolTransform;\n\n /**\n * Per-tool transforms keyed by tool name.\n * Takes precedence over global transforms for overlapping properties.\n */\n perTool?: Record<string, ToolTransform>;\n\n /**\n * Dynamic transform generator function.\n * Called for each tool to generate transforms programmatically.\n * Useful when transforms depend on tool metadata (e.g., HTTP method).\n *\n * @example\n * ```typescript\n * generator: (tool) => {\n * // Mark all GET operations as read-only\n * if (tool.metadata.method === 'get') {\n * return {\n * annotations: { readOnlyHint: true, destructiveHint: false },\n * };\n * }\n * // Mark DELETE operations as destructive\n * if (tool.metadata.method === 'delete') {\n * return {\n * annotations: { destructiveHint: true },\n * };\n * }\n * return undefined;\n * }\n * ```\n */\n generator?: (tool: McpOpenAPITool) => ToolTransform | undefined;\n}\n\n// ============================================================================\n// Extended Metadata Types (internal)\n// ============================================================================\n\n/**\n * Extended tool metadata that includes adapter-specific fields.\n * This extends the base ToolMetadata from mcp-from-openapi with\n * fields used for transforms and extensions.\n */\nexport interface ExtendedToolMetadata extends ToolMetadata {\n /**\n * Adapter-specific runtime configuration.\n * Contains transforms and other metadata added during tool processing.\n */\n adapter?: {\n /** Input transforms to apply at request time */\n inputTransforms?: InputTransform[];\n /** Tool transform configuration */\n toolTransform?: ToolTransform;\n /** Security schemes that are included in tool input (user provides) */\n securitySchemesInInput?: string[];\n /** Security schemes resolved from context (authProviderMapper, etc.) */\n securitySchemesFromContext?: string[];\n };\n}\n\n/**\n * McpOpenAPITool with extended metadata type.\n * Use this type when accessing adapter-extended metadata.\n */\nexport interface ExtendedMcpOpenAPITool extends Omit<McpOpenAPITool, 'metadata'> {\n metadata: ExtendedToolMetadata;\n}\n\ninterface BaseOptions {\n /**\n * The name of the adapter.\n * This is used to identify the adapter in the MCP configuration.\n * Also used to prefix tools if conflicted with other adapters in the same app.\n */\n name: string;\n\n /**\n * The base URL of the API.\n * This is used to construct the full URL for each request.\n * For example, if the API is hosted at https://api.example.com/v1,\n * the baseUrl should be set to https://api.example.com/v1.\n * This overrides the baseUrl in LoadOptions.\n */\n baseUrl: string;\n\n /**\n * Additional headers to be sent with each request.\n * This can be used to set authentication headers,\n * such as Authorization or API Key.\n */\n additionalHeaders?: Record<string, string>;\n\n /**\n * This can be used to map request information to specific\n * headers as required by the API.\n * For example, mapping tenantId from authenticated session payload to\n * a specific header, this key will be hidden to mcp clients\n * and filled by the adapter before sending the request to the API.\n * @param ctx - FrontMCP request context with authInfo, sessionId, traceId, etc.\n * @param headers\n */\n headersMapper?: (ctx: FrontMcpContext, headers: Headers) => Headers;\n\n /**\n * This can be used to map request information to specific\n * body values as required by the API.\n * For example, mapping tenantId from authenticated session payload to\n * a specific property in the body, this key will be hidden to mcp clients\n * and filled by the adapter before sending the request to the API.\n *\n * @param ctx - FrontMCP request context with authInfo, sessionId, traceId, etc.\n * @param body\n */\n bodyMapper?: (ctx: FrontMcpContext, body: Record<string, unknown>) => Record<string, unknown>;\n\n /**\n * Custom security resolver for resolving authentication from context.\n * This allows you to map different auth providers to different tools/security schemes.\n *\n * Use this when:\n * - You have multiple auth providers (e.g., GitHub OAuth, Google OAuth, API keys)\n * - Different tools need different authentication\n * - You need custom logic to select the right auth provider\n *\n * @example\n * ```typescript\n * securityResolver: (tool, ctx) => {\n * const authInfo = ctx.authInfo;\n * // Use GitHub token for GitHub API tools\n * if (tool.name.startsWith('github_')) {\n * return { jwt: authInfo.user?.githubToken };\n * }\n * // Use Google token for Google API tools\n * if (tool.name.startsWith('google_')) {\n * return { jwt: authInfo.user?.googleToken };\n * }\n * // Default to main JWT token\n * return { jwt: authInfo.token };\n * }\n * ```\n */\n securityResolver?: (tool: McpOpenAPITool, ctx: FrontMcpContext) => SecurityContext | Promise<SecurityContext>;\n\n /**\n * Map security scheme names to auth provider extractors.\n * This allows different security schemes to use different auth providers.\n *\n * Use this when your OpenAPI spec has multiple security schemes\n * and each should use a different auth provider from the context.\n *\n * @example\n * ```typescript\n * authProviderMapper: {\n * // GitHub OAuth security scheme\n * 'GitHubAuth': (ctx) => ctx.authInfo.user?.githubToken,\n * // Google OAuth security scheme\n * 'GoogleAuth': (ctx) => ctx.authInfo.user?.googleToken,\n * // API Key security scheme\n * 'ApiKeyAuth': (ctx) => ctx.authInfo.user?.apiKey,\n * }\n * ```\n */\n authProviderMapper?: Record<string, (ctx: FrontMcpContext) => string | undefined>;\n\n /**\n * Static authentication configuration when not using dynamic auth from context.\n * Useful for server-to-server APIs with static credentials.\n *\n * @example\n * ```typescript\n * staticAuth: {\n * jwt: process.env.API_JWT_TOKEN,\n * apiKey: process.env.API_KEY,\n * }\n * ```\n */\n staticAuth?: Partial<SecurityContext>;\n\n /**\n * Options for loading the OpenAPI specification\n * @see LoadOptions from mcp-from-openapi\n */\n loadOptions?: Omit<LoadOptions, 'baseUrl'>; // baseUrl is in BaseOptions\n\n /**\n * Options for generating tools from the OpenAPI specification\n * @see GenerateOptions from mcp-from-openapi\n */\n generateOptions?: GenerateOptions;\n\n /**\n * Specify which security schemes should be included in the tool's input schema.\n * Use this for per-scheme control over authentication handling.\n *\n * - Schemes in this list → included in input (user/AI provides the value)\n * - Schemes NOT in this list → resolved from context (authProviderMapper, staticAuth, etc.)\n *\n * This allows hybrid authentication where some schemes come from user input\n * and others come from the session/context.\n *\n * @example\n * ```typescript\n * // OpenAPI spec has: GitHubAuth (Bearer), ApiKeyAuth (API key)\n * // You want: GitHubAuth from session, ApiKeyAuth from user input\n *\n * const adapter = new OpenapiAdapter({\n * name: 'my-api',\n * baseUrl: 'https://api.example.com',\n * spec: mySpec,\n *\n * // ApiKeyAuth will be in tool input schema\n * securitySchemesInInput: ['ApiKeyAuth'],\n *\n * // GitHubAuth will be resolved from context\n * authProviderMapper: {\n * 'GitHubAuth': (ctx) => ctx.authInfo?.user?.githubToken,\n * },\n * });\n * ```\n */\n securitySchemesInInput?: string[];\n\n /**\n * Input schema transforms for hiding inputs and injecting values at request time.\n *\n * Use cases:\n * - Hide tenant headers from AI/users and inject from session\n * - Hide internal correlation IDs and inject from environment\n * - Remove API-internal fields that should be computed server-side\n *\n * @example\n * ```typescript\n * inputTransforms: {\n * global: [\n * { inputKey: 'X-Tenant-Id', inject: (ctx) => ctx.authInfo.user?.tenantId },\n * ],\n * perTool: {\n * 'createUser': [\n * { inputKey: 'createdBy', inject: (ctx) => ctx.authInfo.user?.email },\n * ],\n * },\n * generator: (tool) => {\n * if (['post', 'put', 'patch'].includes(tool.metadata.method)) {\n * return [{ inputKey: 'X-Correlation-Id', inject: () => crypto.randomUUID() }];\n * }\n * return [];\n * },\n * }\n * ```\n */\n inputTransforms?: InputTransformOptions;\n\n /**\n * Tool transforms for modifying generated tools (description, annotations, UI, etc.).\n *\n * Use cases:\n * - Add annotations (readOnlyHint, openWorldHint) based on HTTP method\n * - Override tool descriptions with combined summary + description\n * - Add UI configuration for tool forms\n * - Hide internal tools from discovery\n *\n * @example\n * ```typescript\n * toolTransforms: {\n * global: {\n * annotations: { openWorldHint: true },\n * },\n * perTool: {\n * 'createUser': {\n * annotations: { destructiveHint: false },\n * tags: ['user-management'],\n * },\n * },\n * generator: (tool) => {\n * if (tool.metadata.method === 'get') {\n * return { annotations: { readOnlyHint: true } };\n * }\n * if (tool.metadata.method === 'delete') {\n * return { annotations: { destructiveHint: true } };\n * }\n * return undefined;\n * },\n * }\n * ```\n */\n toolTransforms?: ToolTransformOptions;\n\n /**\n * How to generate tool descriptions from OpenAPI operations.\n * - 'summaryOnly': Use only summary (default)\n * - 'descriptionOnly': Use only description\n * - 'combined': Summary followed by description\n * - 'full': Summary, description, and operation details\n *\n * @default 'summaryOnly'\n */\n descriptionMode?: DescriptionMode;\n\n /**\n * Logger instance for adapter diagnostics.\n * Optional - if not provided, the SDK will inject it automatically via setLogger().\n */\n logger?: FrontMcpLogger;\n\n /**\n * Timeout for HTTP requests in milliseconds.\n * If a request takes longer than this, it will be aborted.\n * @default 30000 (30 seconds)\n */\n requestTimeoutMs?: number;\n\n /**\n * Maximum request body size in bytes.\n * Requests with bodies larger than this will be rejected before sending.\n * @default 10485760 (10MB)\n */\n maxRequestSize?: number;\n\n /**\n * Maximum response size in bytes.\n * Responses larger than this will be rejected.\n * The check is performed first on Content-Length header (if present),\n * then on actual response size.\n * @default 10485760 (10MB)\n */\n maxResponseSize?: number;\n}\n\ninterface SpecOptions extends BaseOptions {\n /**\n * The OpenAPI specification as a JSON object.\n *\n * Accepts:\n * - `OpenAPIV3.Document` (typed)\n * - `OpenAPIV3_1.Document` (typed)\n * - Plain object from `import spec from './openapi.json'`\n *\n * @example\n * ```typescript\n * // From typed constant\n * import { OpenAPIV3 } from 'openapi-types';\n * const spec: OpenAPIV3.Document = { ... };\n * new OpenapiAdapter({ spec, ... })\n *\n * // From JSON import\n * import openapiJson from './my-openapi.json';\n * new OpenapiAdapter({ spec: openapiJson, ... })\n * ```\n */\n spec: OpenAPIV3.Document | OpenAPIV3_1.Document | object;\n}\n\ninterface UrlOptions extends BaseOptions {\n /**\n * The URL of the OpenAPI specification.\n * Can be a local file path or a remote URL.\n */\n url: string;\n}\n\nexport type OpenApiAdapterOptions = SpecOptions | UrlOptions;\n"]}
@@ -7,6 +7,14 @@ export interface RequestConfig {
7
7
  headers: Headers;
8
8
  body?: Record<string, unknown>;
9
9
  }
10
+ /**
11
+ * Validate and normalize a base URL.
12
+ *
13
+ * @param url - URL to validate
14
+ * @returns Validated URL object
15
+ * @throws Error if URL is invalid or uses unsupported protocol
16
+ */
17
+ export declare function validateBaseUrl(url: string): URL;
10
18
  /**
11
19
  * Build HTTP request from OpenAPI tool and input parameters
12
20
  *
@@ -24,12 +32,20 @@ export declare function buildRequest(tool: McpOpenAPITool, input: Record<string,
24
32
  * @param additionalHeaders - Additional static headers to add
25
33
  */
26
34
  export declare function applyAdditionalHeaders(headers: Headers, additionalHeaders?: Record<string, string>): void;
35
+ /**
36
+ * Options for response parsing
37
+ */
38
+ export interface ParseResponseOptions {
39
+ /** Maximum response size in bytes (default: 10MB) */
40
+ maxResponseSize?: number;
41
+ }
27
42
  /**
28
43
  * Parse API response based on content type
29
44
  *
30
45
  * @param response - Fetch response
46
+ * @param options - Optional parsing options
31
47
  * @returns Parsed response data
32
48
  */
33
- export declare function parseResponse(response: Response): Promise<{
49
+ export declare function parseResponse(response: Response, options?: ParseResponseOptions): Promise<{
34
50
  data: unknown;
35
51
  }>;