mcp-from-openapi 0.0.1 → 2.0.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.
- package/CHANGELOG.md +57 -0
- package/package.json +11 -5
- package/src/errors.js +6 -1
- package/src/errors.js.map +1 -1
- package/src/generator.js +37 -13
- package/src/generator.js.map +1 -1
- package/src/index.d.ts +5 -3
- package/src/index.js +5 -2
- package/src/index.js.map +1 -1
- package/src/parameter-resolver.d.ts +11 -4
- package/src/parameter-resolver.js +93 -10
- package/src/parameter-resolver.js.map +1 -1
- package/src/response-builder.d.ts +5 -2
- package/src/response-builder.js +3 -1
- package/src/response-builder.js.map +1 -1
- package/src/schema-builder.d.ts +27 -32
- package/src/schema-builder.js +8 -13
- package/src/schema-builder.js.map +1 -1
- package/src/security-resolver.d.ts +289 -0
- package/src/security-resolver.js +324 -0
- package/src/security-resolver.js.map +1 -0
- package/src/types.d.ts +72 -6
- package/src/types.js +75 -14
- package/src/types.js.map +1 -1
- package/src/validator.js +3 -1
- package/src/validator.js.map +1 -1
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
## [2.0.0] - 2025-12-11
|
|
2
|
+
|
|
3
|
+
### Breaking
|
|
4
|
+
|
|
5
|
+
- Migrated to Zod v4 (now a peer dependency) and aligned JSON schema types with Zod’s v4 JSONSchema
|
|
6
|
+
- Renamed utility export `toJSONSchema7` to `toJsonSchema`, affecting consumers of the types/helpers
|
|
7
|
+
|
|
8
|
+
### Changed
|
|
9
|
+
|
|
10
|
+
- Updated SWC/Jest config to inline ES2022 settings and modernized tooling versions
|
|
11
|
+
- Adjusted exports formatting and minor parameter resolver refactors for consistency
|
|
12
|
+
|
|
13
|
+
# Changelog
|
|
14
|
+
|
|
15
|
+
## [1.0.0] - 2025-11-21
|
|
16
|
+
|
|
17
|
+
### Features
|
|
18
|
+
|
|
19
|
+
- Production-ready library for converting OpenAPI specifications into MCP tool definitions
|
|
20
|
+
- OpenAPI 3.0+ and Swagger 2.0 support
|
|
21
|
+
- Comprehensive operation parsing:
|
|
22
|
+
- RESTful endpoint detection (GET, POST, PUT, PATCH, DELETE, etc.)
|
|
23
|
+
- Path parameter extraction and validation
|
|
24
|
+
- Query parameter handling
|
|
25
|
+
- Request body schema conversion
|
|
26
|
+
- Response schema parsing
|
|
27
|
+
- Advanced OpenAPI features:
|
|
28
|
+
- Reference resolution ($ref) across the entire specification
|
|
29
|
+
- Security scheme detection and configuration
|
|
30
|
+
- Parameter conflict resolution
|
|
31
|
+
- Operation naming controls and customization
|
|
32
|
+
- Request mapper generation:
|
|
33
|
+
- Automatic parameter mapping from MCP tool inputs to HTTP requests
|
|
34
|
+
- Type-safe parameter handling
|
|
35
|
+
- Support for different parameter locations (path, query, header, cookie)
|
|
36
|
+
- Request body transformation
|
|
37
|
+
- Tool metadata generation:
|
|
38
|
+
- Descriptive tool names from operation IDs
|
|
39
|
+
- Documentation from OpenAPI descriptions
|
|
40
|
+
- Schema validation rules
|
|
41
|
+
- Multiple input formats:
|
|
42
|
+
- JSON OpenAPI specifications
|
|
43
|
+
- YAML OpenAPI specifications
|
|
44
|
+
- Inline specification objects
|
|
45
|
+
- URL references to remote specifications
|
|
46
|
+
- Type-safe TypeScript implementation
|
|
47
|
+
- Node.js 18+ compatibility
|
|
48
|
+
|
|
49
|
+
### Documentation
|
|
50
|
+
|
|
51
|
+
- Complete API reference
|
|
52
|
+
- OpenAPI conversion examples
|
|
53
|
+
- Integration guides for MCP servers
|
|
54
|
+
- Best practices for tool generation
|
|
55
|
+
|
|
56
|
+
This is the first official release of `mcp-from-openapi`, extracted from the FrontMCP framework to be published as a
|
|
57
|
+
standalone, reusable library for the community.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mcp-from-openapi",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Production-ready library for converting OpenAPI specifications into MCP tool definitions",
|
|
5
5
|
"author": "AgentFront <info@agentfront.dev>",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -20,12 +20,16 @@
|
|
|
20
20
|
],
|
|
21
21
|
"repository": {
|
|
22
22
|
"type": "git",
|
|
23
|
-
"url": "git+https://github.com/agentfront/frontmcp.git"
|
|
23
|
+
"url": "git+https://github.com/agentfront/frontmcp.git",
|
|
24
|
+
"directory": "libs/mcp-from-openapi"
|
|
24
25
|
},
|
|
25
26
|
"bugs": {
|
|
26
27
|
"url": "https://github.com/agentfront/frontmcp/issues"
|
|
27
28
|
},
|
|
28
29
|
"homepage": "https://github.com/agentfront/frontmcp/blob/main/libs/mcp-from-openapi/README.md",
|
|
30
|
+
"engines": {
|
|
31
|
+
"node": ">=18.0.0"
|
|
32
|
+
},
|
|
29
33
|
"main": "./src/index.js",
|
|
30
34
|
"types": "./src/index.d.ts",
|
|
31
35
|
"exports": {
|
|
@@ -38,14 +42,16 @@
|
|
|
38
42
|
},
|
|
39
43
|
"dependencies": {
|
|
40
44
|
"@apidevtools/json-schema-ref-parser": "^11.5.4",
|
|
41
|
-
"json-schema": "^0.4.0",
|
|
42
45
|
"openapi-types": "^12.1.3",
|
|
43
46
|
"yaml": "^2.8.1"
|
|
44
47
|
},
|
|
48
|
+
"peerDependencies": {
|
|
49
|
+
"zod": "^4.0.0"
|
|
50
|
+
},
|
|
45
51
|
"devDependencies": {
|
|
46
|
-
"@types/node": "^
|
|
52
|
+
"@types/node": "^24.0.0",
|
|
47
53
|
"typescript": "^5.0.0",
|
|
48
|
-
"zod": "^
|
|
54
|
+
"zod": "^4.0.0"
|
|
49
55
|
},
|
|
50
56
|
"type": "commonjs"
|
|
51
57
|
}
|
package/src/errors.js
CHANGED
|
@@ -5,11 +5,15 @@ exports.SchemaError = exports.GenerationError = exports.ValidationError = export
|
|
|
5
5
|
* Base error class for all library errors
|
|
6
6
|
*/
|
|
7
7
|
class OpenAPIToolError extends Error {
|
|
8
|
+
context;
|
|
8
9
|
constructor(message, context) {
|
|
9
10
|
super(message);
|
|
10
11
|
this.name = this.constructor.name;
|
|
11
12
|
this.context = context;
|
|
12
|
-
|
|
13
|
+
// captureStackTrace is Node.js-specific, guard against non-Node environments
|
|
14
|
+
if (Error.captureStackTrace) {
|
|
15
|
+
Error.captureStackTrace(this, this.constructor);
|
|
16
|
+
}
|
|
13
17
|
}
|
|
14
18
|
}
|
|
15
19
|
exports.OpenAPIToolError = OpenAPIToolError;
|
|
@@ -35,6 +39,7 @@ exports.ParseError = ParseError;
|
|
|
35
39
|
* Error thrown when validating an OpenAPI specification fails
|
|
36
40
|
*/
|
|
37
41
|
class ValidationError extends OpenAPIToolError {
|
|
42
|
+
errors;
|
|
38
43
|
constructor(message, context) {
|
|
39
44
|
super(message, context);
|
|
40
45
|
this.errors = context?.['errors'];
|
package/src/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":";;;AAAA;;GAEG;AACH,MAAa,gBAAiB,SAAQ,KAAK;
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":";;;AAAA;;GAEG;AACH,MAAa,gBAAiB,SAAQ,KAAK;IACzB,OAAO,CAAuB;IAE9C,YAAY,OAAe,EAAE,OAA6B;QACxD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;QAClC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QAEvB,6EAA6E;QAC7E,IAAI,KAAK,CAAC,iBAAiB,EAAE,CAAC;YAC5B,KAAK,CAAC,iBAAiB,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;QAClD,CAAC;IACH,CAAC;CACF;AAbD,4CAaC;AAED;;GAEG;AACH,MAAa,SAAU,SAAQ,gBAAgB;IAC7C,YAAY,OAAe,EAAE,OAA6B;QACxD,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC1B,CAAC;CACF;AAJD,8BAIC;AAED;;GAEG;AACH,MAAa,UAAW,SAAQ,gBAAgB;IAC9C,YAAY,OAAe,EAAE,OAA6B;QACxD,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC1B,CAAC;CACF;AAJD,gCAIC;AAED;;GAEG;AACH,MAAa,eAAgB,SAAQ,gBAAgB;IACnC,MAAM,CAAS;IAE/B,YAAY,OAAe,EAAE,OAA6B;QACxD,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,IAAI,CAAC,MAAM,GAAG,OAAO,EAAE,CAAC,QAAQ,CAAC,CAAC;IACpC,CAAC;CACF;AAPD,0CAOC;AAED;;GAEG;AACH,MAAa,eAAgB,SAAQ,gBAAgB;IACnD,YAAY,OAAe,EAAE,OAA6B;QACxD,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC1B,CAAC;CACF;AAJD,0CAIC;AAED;;GAEG;AACH,MAAa,WAAY,SAAQ,gBAAgB;IAC/C,YAAY,OAAe,EAAE,OAA6B;QACxD,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC1B,CAAC;CACF;AAJD,kCAIC","sourcesContent":["/**\n * Base error class for all library errors\n */\nexport class OpenAPIToolError extends Error {\n public readonly context?: Record<string, any>;\n\n constructor(message: string, context?: Record<string, any>) {\n super(message);\n this.name = this.constructor.name;\n this.context = context;\n\n // captureStackTrace is Node.js-specific, guard against non-Node environments\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor);\n }\n }\n}\n\n/**\n * Error thrown when loading an OpenAPI specification fails\n */\nexport class LoadError extends OpenAPIToolError {\n constructor(message: string, context?: Record<string, any>) {\n super(message, context);\n }\n}\n\n/**\n * Error thrown when parsing an OpenAPI specification fails\n */\nexport class ParseError extends OpenAPIToolError {\n constructor(message: string, context?: Record<string, any>) {\n super(message, context);\n }\n}\n\n/**\n * Error thrown when validating an OpenAPI specification fails\n */\nexport class ValidationError extends OpenAPIToolError {\n public readonly errors?: any[];\n\n constructor(message: string, context?: Record<string, any>) {\n super(message, context);\n this.errors = context?.['errors'];\n }\n}\n\n/**\n * Error thrown when generating a tool fails\n */\nexport class GenerationError extends OpenAPIToolError {\n constructor(message: string, context?: Record<string, any>) {\n super(message, context);\n }\n}\n\n/**\n * Error thrown when a schema is invalid\n */\nexport class SchemaError extends OpenAPIToolError {\n constructor(message: string, context?: Record<string, any>) {\n super(message, context);\n }\n}\n"]}
|
package/src/generator.js
CHANGED
|
@@ -15,6 +15,9 @@ const errors_1 = require("./errors");
|
|
|
15
15
|
* Main class for generating MCP tools from OpenAPI specifications
|
|
16
16
|
*/
|
|
17
17
|
class OpenAPIToolGenerator {
|
|
18
|
+
document;
|
|
19
|
+
dereferencedDocument;
|
|
20
|
+
options;
|
|
18
21
|
/**
|
|
19
22
|
* Private constructor - use static factory methods to create instances
|
|
20
23
|
*/
|
|
@@ -43,10 +46,7 @@ class OpenAPIToolGenerator {
|
|
|
43
46
|
});
|
|
44
47
|
clearTimeout(timeout);
|
|
45
48
|
if (!response.ok) {
|
|
46
|
-
throw new errors_1.LoadError(`Failed to fetch OpenAPI spec from URL: ${response.status} ${response.statusText}`, {
|
|
47
|
-
url,
|
|
48
|
-
status: response.status,
|
|
49
|
-
});
|
|
49
|
+
throw new errors_1.LoadError(`Failed to fetch OpenAPI spec from URL: ${response.status} ${response.statusText}`, { url, status: response.status });
|
|
50
50
|
}
|
|
51
51
|
const contentType = response.headers.get('content-type') || '';
|
|
52
52
|
const text = await response.text();
|
|
@@ -216,7 +216,13 @@ class OpenAPIToolGenerator {
|
|
|
216
216
|
if (pathItem.parameters) {
|
|
217
217
|
pathParameters = pathItem.parameters.filter((p) => !(0, types_1.isReferenceObject)(p));
|
|
218
218
|
}
|
|
219
|
-
|
|
219
|
+
// Extract security requirements
|
|
220
|
+
let securityRequirements = undefined;
|
|
221
|
+
const securitySpec = operation.security ?? document.security;
|
|
222
|
+
if (securitySpec) {
|
|
223
|
+
securityRequirements = this.extractSecurityRequirements(securitySpec, document);
|
|
224
|
+
}
|
|
225
|
+
const { inputSchema, mapper } = parameterResolver.resolve(operation, pathParameters, securityRequirements, options.includeSecurityInInput);
|
|
220
226
|
// Build response schema
|
|
221
227
|
const responseBuilder = new response_builder_1.ResponseBuilder(options);
|
|
222
228
|
const outputSchema = responseBuilder.build(operation.responses);
|
|
@@ -259,7 +265,7 @@ class OpenAPIToolGenerator {
|
|
|
259
265
|
return options.filterFn({
|
|
260
266
|
...operation,
|
|
261
267
|
path,
|
|
262
|
-
method
|
|
268
|
+
method
|
|
263
269
|
});
|
|
264
270
|
}
|
|
265
271
|
return true;
|
|
@@ -308,11 +314,18 @@ class OpenAPIToolGenerator {
|
|
|
308
314
|
else if (this.options.baseUrl) {
|
|
309
315
|
metadata.servers = [{ url: this.options.baseUrl }];
|
|
310
316
|
}
|
|
311
|
-
// Extract response status codes
|
|
312
|
-
if (outputSchema && outputSchema.oneOf) {
|
|
313
|
-
|
|
317
|
+
// Extract response status codes (preserve 0 for default responses)
|
|
318
|
+
if (outputSchema && Array.isArray(outputSchema.oneOf)) {
|
|
319
|
+
const codes = outputSchema.oneOf
|
|
320
|
+
.map((schema) => schema['x-status-code'])
|
|
321
|
+
.filter((code) => code !== undefined && code !== null);
|
|
322
|
+
if (codes.length > 0) {
|
|
323
|
+
metadata.responseStatusCodes = codes;
|
|
324
|
+
}
|
|
314
325
|
}
|
|
315
|
-
else if (outputSchema
|
|
326
|
+
else if (outputSchema &&
|
|
327
|
+
outputSchema['x-status-code'] !== undefined &&
|
|
328
|
+
outputSchema['x-status-code'] !== null) {
|
|
316
329
|
metadata.responseStatusCodes = [outputSchema['x-status-code']];
|
|
317
330
|
}
|
|
318
331
|
// External docs
|
|
@@ -332,15 +345,26 @@ class OpenAPIToolGenerator {
|
|
|
332
345
|
const securityScheme = document.components.securitySchemes[scheme];
|
|
333
346
|
// Skip if it's a reference object
|
|
334
347
|
if ((0, types_1.isReferenceObject)(securityScheme)) {
|
|
335
|
-
return { scheme, type: '
|
|
348
|
+
return { scheme, type: 'http', scopes };
|
|
336
349
|
}
|
|
337
|
-
|
|
350
|
+
const apiKeyIn = 'in' in securityScheme ? securityScheme.in : undefined;
|
|
351
|
+
const result = {
|
|
338
352
|
scheme,
|
|
339
353
|
type: securityScheme.type,
|
|
340
354
|
scopes,
|
|
341
355
|
name: 'name' in securityScheme ? securityScheme.name : undefined,
|
|
342
|
-
in: '
|
|
356
|
+
in: apiKeyIn && (apiKeyIn === 'query' || apiKeyIn === 'header' || apiKeyIn === 'cookie')
|
|
357
|
+
? apiKeyIn
|
|
358
|
+
: undefined,
|
|
343
359
|
};
|
|
360
|
+
// Add HTTP-specific metadata
|
|
361
|
+
if (securityScheme.type === 'http') {
|
|
362
|
+
result.httpScheme = 'scheme' in securityScheme ? securityScheme.scheme : undefined;
|
|
363
|
+
result.bearerFormat = 'bearerFormat' in securityScheme ? securityScheme.bearerFormat : undefined;
|
|
364
|
+
}
|
|
365
|
+
// Add description if available
|
|
366
|
+
result.description = 'description' in securityScheme ? securityScheme.description : undefined;
|
|
367
|
+
return result;
|
|
344
368
|
}));
|
|
345
369
|
}
|
|
346
370
|
}
|
package/src/generator.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generator.js","sourceRoot":"","sources":["../../src/generator.ts"],"names":[],"mappings":"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","sourcesContent":["import * as yaml from 'yaml';\nimport * as fs from 'fs/promises';\nimport * as path from 'path';\nimport $RefParser from '@apidevtools/json-schema-ref-parser';\nimport type {\n OpenAPIDocument,\n LoadOptions,\n GenerateOptions,\n McpOpenAPITool,\n ValidationResult,\n HTTPMethod,\n ParameterObject,\n} from './types';\nimport { isReferenceObject } from './types';\nimport { ParameterResolver } from './parameter-resolver';\nimport { ResponseBuilder } from './response-builder';\nimport { Validator } from './validator';\nimport { LoadError, ParseError } from './errors';\n\n/**\n * Main class for generating MCP tools from OpenAPI specifications\n */\nexport class OpenAPIToolGenerator {\n private document: OpenAPIDocument;\n private dereferencedDocument?: OpenAPIDocument;\n private options: Required<LoadOptions>;\n\n /**\n * Private constructor - use static factory methods to create instances\n */\n private constructor(document: OpenAPIDocument, options: LoadOptions = {}) {\n this.document = document;\n this.options = {\n dereference: options.dereference ?? true,\n baseUrl: options.baseUrl ?? '',\n headers: options.headers ?? {},\n timeout: options.timeout ?? 30000,\n validate: options.validate ?? true,\n followRedirects: options.followRedirects ?? true,\n };\n }\n\n /**\n * Create generator from a URL\n */\n static async fromURL(url: string, options: LoadOptions = {}): Promise<OpenAPIToolGenerator> {\n try {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), options.timeout ?? 30000);\n\n const response = await fetch(url, {\n headers: options.headers,\n signal: controller.signal,\n redirect: options.followRedirects ?? true ? 'follow' : 'manual',\n });\n\n clearTimeout(timeout);\n\n if (!response.ok) {\n throw new LoadError(`Failed to fetch OpenAPI spec from URL: ${response.status} ${response.statusText}`, {\n url,\n status: response.status,\n });\n }\n\n const contentType = response.headers.get('content-type') || '';\n const text = await response.text();\n\n let document: OpenAPIDocument;\n if (contentType.includes('yaml') || contentType.includes('yml') || url.match(/\\.ya?ml$/i)) {\n document = yaml.parse(text);\n } else {\n document = JSON.parse(text);\n }\n\n return new OpenAPIToolGenerator(document, options);\n } catch (error: unknown) {\n if (error instanceof LoadError) {\n throw error;\n }\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new LoadError(`Failed to load OpenAPI spec from URL: ${errorMessage}`, {\n url,\n originalError: error,\n });\n }\n }\n\n /**\n * Create generator from a file path\n */\n static async fromFile(filePath: string, options: LoadOptions = {}): Promise<OpenAPIToolGenerator> {\n try {\n const absolutePath = path.isAbsolute(filePath) ? filePath : path.resolve(process.cwd(), filePath);\n const content = await fs.readFile(absolutePath, 'utf-8');\n const ext = path.extname(filePath).toLowerCase();\n\n let document: OpenAPIDocument;\n if (ext === '.yaml' || ext === '.yml') {\n document = yaml.parse(content);\n } else if (ext === '.json') {\n document = JSON.parse(content);\n } else {\n // Try to parse as JSON first, then YAML\n try {\n document = JSON.parse(content);\n } catch {\n document = yaml.parse(content);\n }\n }\n\n return new OpenAPIToolGenerator(document, options);\n } catch (error: unknown) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new LoadError(`Failed to load OpenAPI spec from file: ${errorMessage}`, {\n filePath,\n originalError: error,\n });\n }\n }\n\n /**\n * Create generator from a YAML string\n */\n static async fromYAML(yamlString: string, options: LoadOptions = {}): Promise<OpenAPIToolGenerator> {\n try {\n const document = yaml.parse(yamlString);\n return new OpenAPIToolGenerator(document, options);\n } catch (error: unknown) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new ParseError(`Failed to parse YAML: ${errorMessage}`, {\n originalError: error,\n });\n }\n }\n\n /**\n * Create generator from a JSON object\n */\n static async fromJSON(json: object, options: LoadOptions = {}): Promise<OpenAPIToolGenerator> {\n // Clone to avoid mutations\n const document = JSON.parse(JSON.stringify(json));\n return new OpenAPIToolGenerator(document, options);\n }\n\n /**\n * Get the OpenAPI document\n */\n getDocument(): OpenAPIDocument {\n return this.dereferencedDocument ?? this.document;\n }\n\n /**\n * Validate the OpenAPI document\n */\n async validate(): Promise<ValidationResult> {\n const validator = new Validator();\n return validator.validate(this.document);\n }\n\n /**\n * Initialize the generator (dereference if needed)\n */\n private async initialize(): Promise<void> {\n if (this.options.validate) {\n const result = await this.validate();\n if (!result.valid) {\n throw new ParseError('Invalid OpenAPI document', { errors: result.errors });\n }\n }\n\n if (this.options.dereference && !this.dereferencedDocument) {\n try {\n this.dereferencedDocument = (await $RefParser.dereference(\n JSON.parse(JSON.stringify(this.document)),\n )) as OpenAPIDocument;\n } catch (error: unknown) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new ParseError(`Failed to dereference OpenAPI document: ${errorMessage}`, {\n originalError: error,\n });\n }\n }\n }\n\n /**\n * Generate all tools from the OpenAPI specification\n */\n async generateTools(options: GenerateOptions = {}): Promise<McpOpenAPITool[]> {\n await this.initialize();\n\n const document = this.getDocument();\n const tools: McpOpenAPITool[] = [];\n\n if (!document.paths) {\n return tools;\n }\n\n for (const [pathStr, pathItem] of Object.entries(document.paths)) {\n if (!pathItem || '$ref' in pathItem) continue;\n\n const methods: HTTPMethod[] = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace'];\n\n for (const method of methods) {\n const operation = pathItem[method];\n if (!operation) continue;\n\n // Apply filters\n if (!this.shouldIncludeOperation(operation, pathStr, method, options)) {\n continue;\n }\n\n try {\n const tool = await this.generateTool(pathStr, method, options);\n tools.push(tool);\n } catch (error: any) {\n console.warn(`Failed to generate tool for ${method.toUpperCase()} ${pathStr}:`, error.message);\n }\n }\n }\n\n return tools;\n }\n\n /**\n * Generate a specific tool for a path and method\n */\n async generateTool(pathStr: string, method: string, options: GenerateOptions = {}): Promise<McpOpenAPITool> {\n await this.initialize();\n\n const document = this.getDocument();\n\n if (!document.paths) {\n throw new Error('No paths defined in OpenAPI document');\n }\n\n const pathItem = document.paths[pathStr];\n const operation = pathItem?.[method.toLowerCase() as HTTPMethod];\n\n if (!operation) {\n throw new Error(`Operation not found: ${method.toUpperCase()} ${pathStr}`);\n }\n\n // Resolve parameters\n const parameterResolver = new ParameterResolver(options.namingStrategy);\n\n // Filter out ReferenceObjects from parameters\n let pathParameters: ParameterObject[] | undefined = undefined;\n if (pathItem.parameters) {\n pathParameters = pathItem.parameters.filter(\n (p): p is ParameterObject => !isReferenceObject(p),\n ) as ParameterObject[];\n }\n\n const { inputSchema, mapper } = parameterResolver.resolve(operation, pathParameters);\n\n // Build response schema\n const responseBuilder = new ResponseBuilder(options);\n const outputSchema = responseBuilder.build(operation.responses);\n\n // Generate tool name\n const name = this.generateToolName(pathStr, method as HTTPMethod, operation.operationId, options);\n\n // Generate description\n const description = operation.summary || operation.description || `${method.toUpperCase()} ${pathStr}`;\n\n // Extract metadata\n const metadata = this.extractMetadata(pathStr, method as HTTPMethod, operation, document, outputSchema);\n\n return {\n name,\n description,\n inputSchema,\n outputSchema,\n mapper,\n metadata,\n };\n }\n\n /**\n * Check if an operation should be included\n */\n private shouldIncludeOperation(operation: any, path: string, method: string, options: GenerateOptions): boolean {\n // Check deprecated\n if (operation.deprecated && !options.includeDeprecated) {\n return false;\n }\n\n // Check operation ID filters\n if (options.includeOperations && operation.operationId) {\n if (!options.includeOperations.includes(operation.operationId)) {\n return false;\n }\n }\n\n if (options.excludeOperations && operation.operationId) {\n if (options.excludeOperations.includes(operation.operationId)) {\n return false;\n }\n }\n\n // Custom filter\n if (options.filterFn) {\n return options.filterFn({\n ...operation,\n path,\n method,\n } as any);\n }\n\n return true;\n }\n\n /**\n * Generate a tool name\n */\n private generateToolName(\n path: string,\n method: HTTPMethod,\n operationId?: string,\n options: GenerateOptions = {},\n ): string {\n if (options.namingStrategy?.toolNameGenerator) {\n return options.namingStrategy.toolNameGenerator(path, method, operationId);\n }\n\n if (operationId) {\n return operationId;\n }\n\n // Generate from path and method\n const sanitized = path\n .replace(/\\{([^}]+)\\}/g, 'By_$1')\n .replace(/[^a-zA-Z0-9_]/g, '_')\n .replace(/_+/g, '_')\n .replace(/^_|_$/g, '');\n\n return `${method}_${sanitized}`;\n }\n\n /**\n * Extract metadata from operation\n */\n private extractMetadata(\n path: string,\n method: HTTPMethod,\n operation: any,\n document: OpenAPIDocument,\n outputSchema?: any,\n ): any {\n const metadata: any = {\n path,\n method,\n operationId: operation.operationId,\n tags: operation.tags,\n deprecated: operation.deprecated,\n };\n\n // Extract security requirements\n if (operation.security || document.security) {\n metadata.security = this.extractSecurityRequirements(operation.security ?? document.security, document);\n }\n\n // Extract servers\n if (operation.servers || document.servers) {\n metadata.servers = (operation.servers ?? document.servers).map((server: any) => ({\n url: this.options.baseUrl || server.url,\n description: server.description,\n variables: server.variables,\n }));\n } else if (this.options.baseUrl) {\n metadata.servers = [{ url: this.options.baseUrl }];\n }\n\n // Extract response status codes\n if (outputSchema && outputSchema.oneOf) {\n metadata.responseStatusCodes = outputSchema.oneOf.map((schema: any) => schema['x-status-code']).filter(Boolean);\n } else if (outputSchema?.['x-status-code']) {\n metadata.responseStatusCodes = [outputSchema['x-status-code']];\n }\n\n // External docs\n if (operation.externalDocs) {\n metadata.externalDocs = operation.externalDocs;\n }\n\n return metadata;\n }\n\n /**\n * Extract security requirements\n */\n private extractSecurityRequirements(security: Record<string, string[]>[], document: OpenAPIDocument): any[] {\n if (!security || !document.components?.securitySchemes) {\n return [];\n }\n\n return security.flatMap((req) =>\n Object.entries(req).map(([scheme, scopes]) => {\n const securityScheme = document.components!.securitySchemes![scheme];\n\n // Skip if it's a reference object\n if (isReferenceObject(securityScheme)) {\n return { scheme, type: 'unknown' as any, scopes };\n }\n\n return {\n scheme,\n type: securityScheme.type,\n scopes,\n name: 'name' in securityScheme ? securityScheme.name : undefined,\n in: 'in' in securityScheme ? securityScheme.in : undefined,\n };\n }),\n );\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"generator.js","sourceRoot":"","sources":["../../src/generator.ts"],"names":[],"mappings":"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","sourcesContent":["import * as yaml from 'yaml';\nimport * as fs from 'fs/promises';\nimport * as path from 'path';\nimport $RefParser from '@apidevtools/json-schema-ref-parser';\nimport type {\n OpenAPIDocument,\n LoadOptions,\n GenerateOptions,\n McpOpenAPITool,\n ValidationResult,\n HTTPMethod,\n ParameterObject,\n SecurityRequirement,\n SecuritySchemeObject,\n AuthType,\n} from './types';\nimport { isReferenceObject } from './types';\nimport { ParameterResolver } from './parameter-resolver';\nimport { ResponseBuilder } from './response-builder';\nimport { Validator } from './validator';\nimport { LoadError, ParseError } from './errors';\n\n/**\n * Main class for generating MCP tools from OpenAPI specifications\n */\nexport class OpenAPIToolGenerator {\n private document: OpenAPIDocument;\n private dereferencedDocument?: OpenAPIDocument;\n private options: Required<LoadOptions>;\n\n /**\n * Private constructor - use static factory methods to create instances\n */\n private constructor(document: OpenAPIDocument, options: LoadOptions = {}) {\n this.document = document;\n this.options = {\n dereference: options.dereference ?? true,\n baseUrl: options.baseUrl ?? '',\n headers: options.headers ?? {},\n timeout: options.timeout ?? 30000,\n validate: options.validate ?? true,\n followRedirects: options.followRedirects ?? true,\n };\n }\n\n /**\n * Create generator from a URL\n */\n static async fromURL(\n url: string,\n options: LoadOptions = {}\n ): Promise<OpenAPIToolGenerator> {\n try {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), options.timeout ?? 30000);\n\n const response = await fetch(url, {\n headers: options.headers,\n signal: controller.signal,\n redirect: options.followRedirects ?? true ? 'follow' : 'manual',\n });\n\n clearTimeout(timeout);\n\n if (!response.ok) {\n throw new LoadError(\n `Failed to fetch OpenAPI spec from URL: ${response.status} ${response.statusText}`,\n { url, status: response.status }\n );\n }\n\n const contentType = response.headers.get('content-type') || '';\n const text = await response.text();\n\n let document: OpenAPIDocument;\n if (contentType.includes('yaml') || contentType.includes('yml') || url.match(/\\.ya?ml$/i)) {\n document = yaml.parse(text);\n } else {\n document = JSON.parse(text);\n }\n\n return new OpenAPIToolGenerator(document, options);\n } catch (error: unknown) {\n if (error instanceof LoadError) {\n throw error;\n }\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new LoadError(`Failed to load OpenAPI spec from URL: ${errorMessage}`, {\n url,\n originalError: error,\n });\n }\n }\n\n /**\n * Create generator from a file path\n */\n static async fromFile(\n filePath: string,\n options: LoadOptions = {}\n ): Promise<OpenAPIToolGenerator> {\n try {\n const absolutePath = path.isAbsolute(filePath) ? filePath : path.resolve(process.cwd(), filePath);\n const content = await fs.readFile(absolutePath, 'utf-8');\n const ext = path.extname(filePath).toLowerCase();\n\n let document: OpenAPIDocument;\n if (ext === '.yaml' || ext === '.yml') {\n document = yaml.parse(content);\n } else if (ext === '.json') {\n document = JSON.parse(content);\n } else {\n // Try to parse as JSON first, then YAML\n try {\n document = JSON.parse(content);\n } catch {\n document = yaml.parse(content);\n }\n }\n\n return new OpenAPIToolGenerator(document, options);\n } catch (error: unknown) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new LoadError(`Failed to load OpenAPI spec from file: ${errorMessage}`, {\n filePath,\n originalError: error,\n });\n }\n }\n\n /**\n * Create generator from a YAML string\n */\n static async fromYAML(\n yamlString: string,\n options: LoadOptions = {}\n ): Promise<OpenAPIToolGenerator> {\n try {\n const document = yaml.parse(yamlString);\n return new OpenAPIToolGenerator(document, options);\n } catch (error: unknown) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new ParseError(`Failed to parse YAML: ${errorMessage}`, {\n originalError: error,\n });\n }\n }\n\n /**\n * Create generator from a JSON object\n */\n static async fromJSON(\n json: object,\n options: LoadOptions = {}\n ): Promise<OpenAPIToolGenerator> {\n // Clone to avoid mutations\n const document = JSON.parse(JSON.stringify(json));\n return new OpenAPIToolGenerator(document, options);\n }\n\n /**\n * Get the OpenAPI document\n */\n getDocument(): OpenAPIDocument {\n return this.dereferencedDocument ?? this.document;\n }\n\n /**\n * Validate the OpenAPI document\n */\n async validate(): Promise<ValidationResult> {\n const validator = new Validator();\n return validator.validate(this.document);\n }\n\n /**\n * Initialize the generator (dereference if needed)\n */\n private async initialize(): Promise<void> {\n if (this.options.validate) {\n const result = await this.validate();\n if (!result.valid) {\n throw new ParseError('Invalid OpenAPI document', { errors: result.errors });\n }\n }\n\n if (this.options.dereference && !this.dereferencedDocument) {\n try {\n this.dereferencedDocument = (await $RefParser.dereference(\n JSON.parse(JSON.stringify(this.document))\n )) as OpenAPIDocument;\n } catch (error: unknown) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new ParseError(`Failed to dereference OpenAPI document: ${errorMessage}`, {\n originalError: error,\n });\n }\n }\n }\n\n /**\n * Generate all tools from the OpenAPI specification\n */\n async generateTools(options: GenerateOptions = {}): Promise<McpOpenAPITool[]> {\n await this.initialize();\n\n const document = this.getDocument();\n const tools: McpOpenAPITool[] = [];\n\n if (!document.paths) {\n return tools;\n }\n\n for (const [pathStr, pathItem] of Object.entries(document.paths)) {\n if (!pathItem || '$ref' in pathItem) continue;\n\n const methods: HTTPMethod[] = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace'];\n\n for (const method of methods) {\n const operation = pathItem[method];\n if (!operation) continue;\n\n // Apply filters\n if (!this.shouldIncludeOperation(operation, pathStr, method, options)) {\n continue;\n }\n\n try {\n const tool = await this.generateTool(pathStr, method, options);\n tools.push(tool);\n } catch (error: any) {\n console.warn(`Failed to generate tool for ${method.toUpperCase()} ${pathStr}:`, error.message);\n }\n }\n }\n\n return tools;\n }\n\n /**\n * Generate a specific tool for a path and method\n */\n async generateTool(\n pathStr: string,\n method: string,\n options: GenerateOptions = {}\n ): Promise<McpOpenAPITool> {\n await this.initialize();\n\n const document = this.getDocument();\n\n if (!document.paths) {\n throw new Error('No paths defined in OpenAPI document');\n }\n\n const pathItem = document.paths[pathStr];\n const operation = pathItem?.[method.toLowerCase() as HTTPMethod];\n\n if (!operation) {\n throw new Error(`Operation not found: ${method.toUpperCase()} ${pathStr}`);\n }\n\n // Resolve parameters\n const parameterResolver = new ParameterResolver(options.namingStrategy);\n\n // Filter out ReferenceObjects from parameters\n let pathParameters: ParameterObject[] | undefined = undefined;\n if (pathItem.parameters) {\n pathParameters = pathItem.parameters.filter(\n (p): p is ParameterObject => !isReferenceObject(p)\n ) as ParameterObject[];\n }\n\n // Extract security requirements\n let securityRequirements: SecurityRequirement[] | undefined = undefined;\n const securitySpec = operation.security ?? document.security;\n if (securitySpec) {\n securityRequirements = this.extractSecurityRequirements(\n securitySpec as Record<string, string[]>[],\n document\n );\n }\n\n const { inputSchema, mapper } = parameterResolver.resolve(\n operation,\n pathParameters,\n securityRequirements,\n options.includeSecurityInInput\n );\n\n // Build response schema\n const responseBuilder = new ResponseBuilder(options);\n const outputSchema = responseBuilder.build(operation.responses);\n\n // Generate tool name\n const name = this.generateToolName(pathStr, method as HTTPMethod, operation.operationId, options);\n\n // Generate description\n const description = operation.summary || operation.description || `${method.toUpperCase()} ${pathStr}`;\n\n // Extract metadata\n const metadata = this.extractMetadata(pathStr, method as HTTPMethod, operation, document, outputSchema);\n\n return {\n name,\n description,\n inputSchema,\n outputSchema,\n mapper,\n metadata,\n };\n }\n\n /**\n * Check if an operation should be included\n */\n private shouldIncludeOperation(\n operation: any,\n path: string,\n method: string,\n options: GenerateOptions\n ): boolean {\n // Check deprecated\n if (operation.deprecated && !options.includeDeprecated) {\n return false;\n }\n\n // Check operation ID filters\n if (options.includeOperations && operation.operationId) {\n if (!options.includeOperations.includes(operation.operationId)) {\n return false;\n }\n }\n\n if (options.excludeOperations && operation.operationId) {\n if (options.excludeOperations.includes(operation.operationId)) {\n return false;\n }\n }\n\n // Custom filter\n if (options.filterFn) {\n return options.filterFn({\n ...operation,\n path,\n method\n } as any);\n }\n\n return true;\n }\n\n /**\n * Generate a tool name\n */\n private generateToolName(\n path: string,\n method: HTTPMethod,\n operationId?: string,\n options: GenerateOptions = {}\n ): string {\n if (options.namingStrategy?.toolNameGenerator) {\n return options.namingStrategy.toolNameGenerator(path, method, operationId);\n }\n\n if (operationId) {\n return operationId;\n }\n\n // Generate from path and method\n const sanitized = path\n .replace(/\\{([^}]+)\\}/g, 'By_$1')\n .replace(/[^a-zA-Z0-9_]/g, '_')\n .replace(/_+/g, '_')\n .replace(/^_|_$/g, '');\n\n return `${method}_${sanitized}`;\n }\n\n /**\n * Extract metadata from operation\n */\n private extractMetadata(\n path: string,\n method: HTTPMethod,\n operation: any,\n document: OpenAPIDocument,\n outputSchema?: any\n ): any {\n const metadata: any = {\n path,\n method,\n operationId: operation.operationId,\n tags: operation.tags,\n deprecated: operation.deprecated,\n };\n\n // Extract security requirements\n if (operation.security || document.security) {\n metadata.security = this.extractSecurityRequirements(\n operation.security ?? document.security,\n document\n );\n }\n\n // Extract servers\n if (operation.servers || document.servers) {\n metadata.servers = (operation.servers ?? document.servers).map((server: any) => ({\n url: this.options.baseUrl || server.url,\n description: server.description,\n variables: server.variables,\n }));\n } else if (this.options.baseUrl) {\n metadata.servers = [{ url: this.options.baseUrl }];\n }\n\n // Extract response status codes (preserve 0 for default responses)\n if (outputSchema && Array.isArray((outputSchema as any).oneOf)) {\n const codes = (outputSchema as any).oneOf\n .map((schema: any) => (schema as any)['x-status-code'])\n .filter((code: unknown) => code !== undefined && code !== null);\n if (codes.length > 0) {\n metadata.responseStatusCodes = codes;\n }\n } else if (\n outputSchema &&\n (outputSchema as any)['x-status-code'] !== undefined &&\n (outputSchema as any)['x-status-code'] !== null\n ) {\n metadata.responseStatusCodes = [(outputSchema as any)['x-status-code']];\n }\n\n // External docs\n if (operation.externalDocs) {\n metadata.externalDocs = operation.externalDocs;\n }\n\n return metadata;\n }\n\n /**\n * Extract security requirements\n */\n private extractSecurityRequirements(\n security: Record<string, string[]>[],\n document: OpenAPIDocument\n ): SecurityRequirement[] {\n if (!security || !document.components?.securitySchemes) {\n return [];\n }\n\n return security.flatMap((req) =>\n Object.entries(req).map(([scheme, scopes]): SecurityRequirement => {\n const securityScheme = document.components!.securitySchemes![scheme];\n\n // Skip if it's a reference object\n if (isReferenceObject(securityScheme)) {\n return { scheme, type: 'http', scopes };\n }\n\n const apiKeyIn = 'in' in securityScheme ? securityScheme.in : undefined;\n const result: SecurityRequirement = {\n scheme,\n type: securityScheme.type as AuthType,\n scopes,\n name: 'name' in securityScheme ? securityScheme.name : undefined,\n in: apiKeyIn && (apiKeyIn === 'query' || apiKeyIn === 'header' || apiKeyIn === 'cookie')\n ? apiKeyIn\n : undefined,\n };\n\n // Add HTTP-specific metadata\n if (securityScheme.type === 'http') {\n result.httpScheme = 'scheme' in securityScheme ? securityScheme.scheme : undefined;\n result.bearerFormat = 'bearerFormat' in securityScheme ? securityScheme.bearerFormat : undefined;\n }\n\n // Add description if available\n result.description = 'description' in securityScheme ? securityScheme.description : undefined;\n\n return result;\n })\n );\n }\n}\n"]}
|
package/src/index.d.ts
CHANGED
|
@@ -3,6 +3,8 @@ export { SchemaBuilder } from './schema-builder';
|
|
|
3
3
|
export { ParameterResolver } from './parameter-resolver';
|
|
4
4
|
export { ResponseBuilder } from './response-builder';
|
|
5
5
|
export { Validator } from './validator';
|
|
6
|
-
export {
|
|
7
|
-
export
|
|
8
|
-
export {
|
|
6
|
+
export { SecurityResolver, createSecurityContext } from './security-resolver';
|
|
7
|
+
export { OpenAPIToolError, LoadError, ParseError, ValidationError, GenerationError, SchemaError } from './errors';
|
|
8
|
+
export type { McpOpenAPITool, ParameterMapper, ToolMetadata, SerializationInfo, SecurityRequirement, SecurityParameterInfo, ServerInfo, LoadOptions, GenerateOptions, NamingStrategy, OperationWithContext, OpenAPIDocument, OpenAPIVersion, HTTPMethod, ParameterLocation, AuthType, OperationObject, ParameterObject, RequestBodyObject, ResponseObject, ResponsesObject, MediaTypeObject, HeaderObject, ExampleObject, PathItemObject, PathsObject, ServerObject, SecuritySchemeObject, ReferenceObject, TagObject, ExternalDocumentationObject, ServerVariableObject, EncodingObject, SecurityRequirementObject, SchemaObject, ValidationResult, ValidationErrorDetail, ValidationWarning, } from './types';
|
|
9
|
+
export type { SecurityContext, ResolvedSecurity, DigestAuthCredentials, ClientCertificate, AWSCredentials, SignatureData, } from './security-resolver';
|
|
10
|
+
export { isReferenceObject, toJsonSchema } from './types';
|
package/src/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.toJsonSchema = exports.isReferenceObject = exports.SchemaError = exports.GenerationError = exports.ValidationError = exports.ParseError = exports.LoadError = exports.OpenAPIToolError = exports.createSecurityContext = exports.SecurityResolver = exports.Validator = exports.ResponseBuilder = exports.ParameterResolver = exports.SchemaBuilder = exports.OpenAPIToolGenerator = void 0;
|
|
4
4
|
// Main exports
|
|
5
5
|
var generator_1 = require("./generator");
|
|
6
6
|
Object.defineProperty(exports, "OpenAPIToolGenerator", { enumerable: true, get: function () { return generator_1.OpenAPIToolGenerator; } });
|
|
@@ -12,6 +12,9 @@ var response_builder_1 = require("./response-builder");
|
|
|
12
12
|
Object.defineProperty(exports, "ResponseBuilder", { enumerable: true, get: function () { return response_builder_1.ResponseBuilder; } });
|
|
13
13
|
var validator_1 = require("./validator");
|
|
14
14
|
Object.defineProperty(exports, "Validator", { enumerable: true, get: function () { return validator_1.Validator; } });
|
|
15
|
+
var security_resolver_1 = require("./security-resolver");
|
|
16
|
+
Object.defineProperty(exports, "SecurityResolver", { enumerable: true, get: function () { return security_resolver_1.SecurityResolver; } });
|
|
17
|
+
Object.defineProperty(exports, "createSecurityContext", { enumerable: true, get: function () { return security_resolver_1.createSecurityContext; } });
|
|
15
18
|
// Error exports
|
|
16
19
|
var errors_1 = require("./errors");
|
|
17
20
|
Object.defineProperty(exports, "OpenAPIToolError", { enumerable: true, get: function () { return errors_1.OpenAPIToolError; } });
|
|
@@ -23,5 +26,5 @@ Object.defineProperty(exports, "SchemaError", { enumerable: true, get: function
|
|
|
23
26
|
// Utility exports
|
|
24
27
|
var types_1 = require("./types");
|
|
25
28
|
Object.defineProperty(exports, "isReferenceObject", { enumerable: true, get: function () { return types_1.isReferenceObject; } });
|
|
26
|
-
Object.defineProperty(exports, "
|
|
29
|
+
Object.defineProperty(exports, "toJsonSchema", { enumerable: true, get: function () { return types_1.toJsonSchema; } });
|
|
27
30
|
//# sourceMappingURL=index.js.map
|
package/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;AAAA,eAAe;AACf,yCAAmD;AAA1C,iHAAA,oBAAoB,OAAA;AAC7B,mDAAiD;AAAxC,+GAAA,aAAa,OAAA;AACtB,2DAAyD;AAAhD,uHAAA,iBAAiB,OAAA;AAC1B,uDAAqD;AAA5C,mHAAA,eAAe,OAAA;AACxB,yCAAwC;AAA/B,sGAAA,SAAS,OAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;AAAA,eAAe;AACf,yCAAmD;AAA1C,iHAAA,oBAAoB,OAAA;AAC7B,mDAAiD;AAAxC,+GAAA,aAAa,OAAA;AACtB,2DAAyD;AAAhD,uHAAA,iBAAiB,OAAA;AAC1B,uDAAqD;AAA5C,mHAAA,eAAe,OAAA;AACxB,yCAAwC;AAA/B,sGAAA,SAAS,OAAA;AAClB,yDAA8E;AAArE,qHAAA,gBAAgB,OAAA;AAAE,0HAAA,qBAAqB,OAAA;AAEhD,gBAAgB;AAChB,mCAAkH;AAAzG,0GAAA,gBAAgB,OAAA;AAAE,mGAAA,SAAS,OAAA;AAAE,oGAAA,UAAU,OAAA;AAAE,yGAAA,eAAe,OAAA;AAAE,yGAAA,eAAe,OAAA;AAAE,qGAAA,WAAW,OAAA;AA+D/F,kBAAkB;AAClB,iCAA0D;AAAjD,0GAAA,iBAAiB,OAAA;AAAE,qGAAA,YAAY,OAAA","sourcesContent":["// Main exports\nexport { OpenAPIToolGenerator } from './generator';\nexport { SchemaBuilder } from './schema-builder';\nexport { ParameterResolver } from './parameter-resolver';\nexport { ResponseBuilder } from './response-builder';\nexport { Validator } from './validator';\nexport { SecurityResolver, createSecurityContext } from './security-resolver';\n\n// Error exports\nexport { OpenAPIToolError, LoadError, ParseError, ValidationError, GenerationError, SchemaError } from './errors';\n\n// Type exports\nexport type {\n // Main MCP types\n McpOpenAPITool,\n ParameterMapper,\n ToolMetadata,\n SerializationInfo,\n SecurityRequirement,\n SecurityParameterInfo,\n ServerInfo,\n\n // Configuration types\n LoadOptions,\n GenerateOptions,\n NamingStrategy,\n OperationWithContext,\n\n // Basic types\n OpenAPIDocument,\n OpenAPIVersion,\n HTTPMethod,\n ParameterLocation,\n AuthType,\n\n // Re-exported OpenAPI types (from openapi-types package)\n OperationObject,\n ParameterObject,\n RequestBodyObject,\n ResponseObject,\n ResponsesObject,\n MediaTypeObject,\n HeaderObject,\n ExampleObject,\n PathItemObject,\n PathsObject,\n ServerObject,\n SecuritySchemeObject,\n ReferenceObject,\n TagObject,\n ExternalDocumentationObject,\n ServerVariableObject,\n EncodingObject,\n SecurityRequirementObject,\n SchemaObject,\n\n // Validation types\n ValidationResult,\n ValidationErrorDetail,\n ValidationWarning,\n} from './types';\n\n// Security resolver types\nexport type {\n SecurityContext,\n ResolvedSecurity,\n DigestAuthCredentials,\n ClientCertificate,\n AWSCredentials,\n SignatureData,\n} from './security-resolver';\n\n// Utility exports\nexport { isReferenceObject, toJsonSchema } from './types';\n"]}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
1
|
+
import type { JSONSchema } from 'zod/v4/core';
|
|
2
|
+
/** JSON Schema type from Zod v4 */
|
|
3
|
+
type JsonSchema = JSONSchema.JSONSchema;
|
|
4
|
+
import type { ParameterMapper, ParameterObject, NamingStrategy, SecurityRequirement } from './types';
|
|
3
5
|
/**
|
|
4
6
|
* Resolves parameters and handles naming conflicts
|
|
5
7
|
*/
|
|
@@ -13,8 +15,8 @@ export declare class ParameterResolver {
|
|
|
13
15
|
/**
|
|
14
16
|
* Resolve all parameters for an operation
|
|
15
17
|
*/
|
|
16
|
-
resolve(operation: any, pathParameters?: ParameterObject[]): {
|
|
17
|
-
inputSchema:
|
|
18
|
+
resolve(operation: any, pathParameters?: ParameterObject[], securityRequirements?: SecurityRequirement[], includeSecurityInInput?: boolean): {
|
|
19
|
+
inputSchema: JsonSchema;
|
|
18
20
|
mapper: ParameterMapper[];
|
|
19
21
|
};
|
|
20
22
|
/**
|
|
@@ -29,4 +31,9 @@ export declare class ParameterResolver {
|
|
|
29
31
|
* Select the most appropriate content type
|
|
30
32
|
*/
|
|
31
33
|
private selectContentType;
|
|
34
|
+
/**
|
|
35
|
+
* Process security requirements and add to mapper/inputSchema
|
|
36
|
+
*/
|
|
37
|
+
private processSecurityRequirements;
|
|
32
38
|
}
|
|
39
|
+
export {};
|
|
@@ -6,6 +6,7 @@ const types_1 = require("./types");
|
|
|
6
6
|
* Resolves parameters and handles naming conflicts
|
|
7
7
|
*/
|
|
8
8
|
class ParameterResolver {
|
|
9
|
+
namingStrategy;
|
|
9
10
|
constructor(namingStrategy) {
|
|
10
11
|
this.namingStrategy = namingStrategy ?? {
|
|
11
12
|
conflictResolver: this.defaultConflictResolver,
|
|
@@ -27,11 +28,8 @@ class ParameterResolver {
|
|
|
27
28
|
/**
|
|
28
29
|
* Resolve all parameters for an operation
|
|
29
30
|
*/
|
|
30
|
-
resolve(operation, pathParameters) {
|
|
31
|
-
const allParameters = [
|
|
32
|
-
...(pathParameters ?? []),
|
|
33
|
-
...(operation.parameters ?? []),
|
|
34
|
-
];
|
|
31
|
+
resolve(operation, pathParameters, securityRequirements, includeSecurityInInput) {
|
|
32
|
+
const allParameters = [...(pathParameters ?? []), ...(operation.parameters ?? [])];
|
|
35
33
|
const requestBody = operation.requestBody;
|
|
36
34
|
// Collect all parameter names and detect conflicts
|
|
37
35
|
const parametersByName = new Map();
|
|
@@ -40,7 +38,7 @@ class ParameterResolver {
|
|
|
40
38
|
const info = {
|
|
41
39
|
name: param.name,
|
|
42
40
|
location: param.in,
|
|
43
|
-
required: param.required ??
|
|
41
|
+
required: param.required ?? param.in === 'path',
|
|
44
42
|
schema: param.schema ?? { type: 'string' },
|
|
45
43
|
description: param.description,
|
|
46
44
|
style: param.style,
|
|
@@ -104,6 +102,10 @@ class ParameterResolver {
|
|
|
104
102
|
});
|
|
105
103
|
}
|
|
106
104
|
}
|
|
105
|
+
// Process security requirements
|
|
106
|
+
if (securityRequirements && securityRequirements.length > 0) {
|
|
107
|
+
this.processSecurityRequirements(securityRequirements, properties, required, mapper, includeSecurityInInput ?? false);
|
|
108
|
+
}
|
|
107
109
|
const inputSchema = {
|
|
108
110
|
type: 'object',
|
|
109
111
|
properties,
|
|
@@ -118,15 +120,15 @@ class ParameterResolver {
|
|
|
118
120
|
extractBodyParameters(schema, parametersByName, required, contentType, prefix = '') {
|
|
119
121
|
if (!schema || typeof schema !== 'object')
|
|
120
122
|
return;
|
|
121
|
-
// Convert to
|
|
122
|
-
const jsonSchema = (0, types_1.
|
|
123
|
+
// Convert to JsonSchema for processing
|
|
124
|
+
const jsonSchema = (0, types_1.toJsonSchema)(schema);
|
|
123
125
|
// Handle object schemas
|
|
124
126
|
if (jsonSchema.type === 'object' && jsonSchema.properties) {
|
|
125
127
|
const requiredFields = new Set(jsonSchema.required ?? []);
|
|
126
128
|
for (const [propName, propSchema] of Object.entries(jsonSchema.properties)) {
|
|
127
129
|
const fullName = prefix ? `${prefix}.${propName}` : propName;
|
|
128
130
|
const isRequired = required && requiredFields.has(propName);
|
|
129
|
-
if (typeof propSchema === 'object'
|
|
131
|
+
if (typeof propSchema === 'object') {
|
|
130
132
|
const info = {
|
|
131
133
|
name: fullName,
|
|
132
134
|
location: 'body',
|
|
@@ -166,7 +168,7 @@ class ParameterResolver {
|
|
|
166
168
|
* Build JSON Schema for a parameter
|
|
167
169
|
*/
|
|
168
170
|
buildParameterSchema(param) {
|
|
169
|
-
const schema = (0, types_1.
|
|
171
|
+
const schema = (0, types_1.toJsonSchema)(param.schema);
|
|
170
172
|
if (param.description) {
|
|
171
173
|
schema.description = param.description;
|
|
172
174
|
}
|
|
@@ -206,6 +208,87 @@ class ParameterResolver {
|
|
|
206
208
|
}
|
|
207
209
|
return firstKey;
|
|
208
210
|
}
|
|
211
|
+
/**
|
|
212
|
+
* Process security requirements and add to mapper/inputSchema
|
|
213
|
+
*/
|
|
214
|
+
processSecurityRequirements(securityRequirements, properties, required, mapper, includeInInput) {
|
|
215
|
+
for (const secReq of securityRequirements) {
|
|
216
|
+
const { scheme, type, name: apiKeyName, in: apiKeyIn, scopes } = secReq;
|
|
217
|
+
// Build security parameter info
|
|
218
|
+
const securityInfo = {
|
|
219
|
+
scheme,
|
|
220
|
+
type,
|
|
221
|
+
scopes,
|
|
222
|
+
};
|
|
223
|
+
// Determine parameter details based on security type
|
|
224
|
+
let inputKey;
|
|
225
|
+
let headerKey;
|
|
226
|
+
let paramLocation;
|
|
227
|
+
let description;
|
|
228
|
+
let schema;
|
|
229
|
+
if (type === 'http') {
|
|
230
|
+
// HTTP auth (bearer, basic, etc.)
|
|
231
|
+
inputKey = scheme;
|
|
232
|
+
headerKey = 'Authorization';
|
|
233
|
+
paramLocation = 'header';
|
|
234
|
+
const httpScheme = 'httpScheme' in secReq && secReq.httpScheme ? secReq.httpScheme : 'bearer';
|
|
235
|
+
const bearerFormat = 'bearerFormat' in secReq ? secReq.bearerFormat : undefined;
|
|
236
|
+
securityInfo.httpScheme = httpScheme;
|
|
237
|
+
if (bearerFormat) {
|
|
238
|
+
securityInfo.bearerFormat = bearerFormat;
|
|
239
|
+
}
|
|
240
|
+
description = `${httpScheme.charAt(0).toUpperCase()}${httpScheme.slice(1)} authentication token`;
|
|
241
|
+
if (bearerFormat) {
|
|
242
|
+
description += ` (${bearerFormat})`;
|
|
243
|
+
}
|
|
244
|
+
schema = {
|
|
245
|
+
type: 'string',
|
|
246
|
+
description,
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
else if (type === 'apiKey') {
|
|
250
|
+
// API Key auth
|
|
251
|
+
inputKey = scheme;
|
|
252
|
+
headerKey = apiKeyName || 'X-API-Key';
|
|
253
|
+
paramLocation = (apiKeyIn || 'header');
|
|
254
|
+
securityInfo.apiKeyName = apiKeyName;
|
|
255
|
+
securityInfo.apiKeyIn = apiKeyIn;
|
|
256
|
+
description = `API key for ${scheme}`;
|
|
257
|
+
schema = {
|
|
258
|
+
type: 'string',
|
|
259
|
+
description,
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
else if (type === 'oauth2' || type === 'openIdConnect') {
|
|
263
|
+
// OAuth2 / OpenID Connect
|
|
264
|
+
inputKey = scheme;
|
|
265
|
+
headerKey = 'Authorization';
|
|
266
|
+
paramLocation = 'header';
|
|
267
|
+
description = `OAuth2 access token${scopes && scopes.length > 0 ? ` (scopes: ${scopes.join(', ')})` : ''}`;
|
|
268
|
+
schema = {
|
|
269
|
+
type: 'string',
|
|
270
|
+
description,
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
else {
|
|
274
|
+
// Unknown type, skip
|
|
275
|
+
continue;
|
|
276
|
+
}
|
|
277
|
+
// Add to mapper (always)
|
|
278
|
+
mapper.push({
|
|
279
|
+
inputKey,
|
|
280
|
+
type: paramLocation,
|
|
281
|
+
key: headerKey,
|
|
282
|
+
required: true,
|
|
283
|
+
security: securityInfo,
|
|
284
|
+
});
|
|
285
|
+
// Add to inputSchema (only if includeInInput is true)
|
|
286
|
+
if (includeInInput) {
|
|
287
|
+
properties[inputKey] = schema;
|
|
288
|
+
required.push(inputKey);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
209
292
|
}
|
|
210
293
|
exports.ParameterResolver = ParameterResolver;
|
|
211
294
|
//# sourceMappingURL=parameter-resolver.js.map
|