Merge branch 'feature/simplify-types' into update

This commit is contained in:
Jack Thomson 2025-12-15 11:37:55 +00:00
commit e5201f9eca
No known key found for this signature in database
GPG Key ID: 58D01BD3612EFF1C
5 changed files with 33 additions and 9 deletions

View File

@ -59,6 +59,7 @@ openapi-mcp-generator --input path/to/openapi.json --output path/to/output/dir -
| `--port` | `-p` | Port for web-based transports | `3000` |
| `--default-include` | | Default behavior for x-mcp filtering. Accepts `true` or `false` (case-insensitive). `true` = include by default, `false` = exclude by default. | `true` |
| `--force` | | Overwrite existing files in the output directory without confirmation | `false` |
| `--simplifyTypes` | `-st` | Flatten single-element type arrays in the JSON schema to their single value | `false` |
## 📦 Programmatic API

View File

@ -25,7 +25,7 @@ export function generateMcpServerCode(
serverVersion: string
): string {
// Extract tools from API
const tools = extractToolsFromApi(api, options.defaultInclude ?? true);
const tools = extractToolsFromApi(api, options.defaultInclude ?? true, options.simplifyTypes);
// Determine base URL
const determinedBaseUrl = determineBaseUrl(api, options.baseUrl);

View File

@ -87,6 +87,10 @@ program
true
)
.option('--force', 'Overwrite existing files without prompting')
.option(
'-st, --simplifyTypes',
'Flatten single-element type arrays in the JSON schema to their single value'
)
.version(pkg.version) // Match package.json version
.action((options) => {
runGenerator(options).catch((error) => {

View File

@ -15,7 +15,8 @@ import { shouldIncludeOperationForMcp } from '../utils/helpers.js';
*/
export function extractToolsFromApi(
api: OpenAPIV3.Document,
defaultInclude: boolean = true
defaultInclude: boolean = true,
simplifyTypes?: string,
): McpToolDefinition[] {
const tools: McpToolDefinition[] = [];
const usedNames = new Set<string>();
@ -80,8 +81,10 @@ export function extractToolsFromApi(
operation.description || operation.summary || `Executes ${method.toUpperCase()} ${path}`;
// Generate input schema and extract parameters
const { inputSchema, parameters, requestBodyContentType } =
generateInputSchemaAndDetails(operation);
const { inputSchema, parameters, requestBodyContentType } = generateInputSchemaAndDetails(
operation,
simplifyTypes
);
// Extract parameter details for execution
const executionParameters = parameters.map((p) => ({ name: p.name, in: p.in }));
@ -115,7 +118,10 @@ export function extractToolsFromApi(
* @param operation OpenAPI operation object
* @returns Input schema, parameters, and request body content type
*/
export function generateInputSchemaAndDetails(operation: OpenAPIV3.OperationObject): {
export function generateInputSchemaAndDetails(
operation: OpenAPIV3.OperationObject,
simplifyTypes?: string
): {
inputSchema: JSONSchema7 | boolean;
parameters: OpenAPIV3.ParameterObject[];
requestBodyContentType?: string;
@ -131,7 +137,11 @@ export function generateInputSchemaAndDetails(operation: OpenAPIV3.OperationObje
allParameters.forEach((param) => {
if (!param.name || !param.schema) return;
const paramSchema = mapOpenApiSchemaToJsonSchema(param.schema as OpenAPIV3.SchemaObject);
const paramSchema = mapOpenApiSchemaToJsonSchema(
param.schema as OpenAPIV3.SchemaObject,
undefined,
simplifyTypes
);
if (typeof paramSchema === 'object') {
paramSchema.description = param.description || paramSchema.description;
}
@ -193,7 +203,8 @@ export function generateInputSchemaAndDetails(operation: OpenAPIV3.OperationObje
*/
export function mapOpenApiSchemaToJsonSchema(
schema: OpenAPIV3.SchemaObject | OpenAPIV3.ReferenceObject,
seen: WeakSet<object> = new WeakSet()
seen: WeakSet<object> = new WeakSet(),
simplifyTypes?: string
): JSONSchema7 | boolean {
// Handle reference objects
if ('$ref' in schema) {
@ -238,6 +249,10 @@ export function mapOpenApiSchemaToJsonSchema(
} else if (!jsonSchema.type) {
jsonSchema.type = 'null';
}
} else {
if (Array.isArray(jsonSchema.type) && jsonSchema.type.length === 1 && simplifyTypes) {
jsonSchema.type = jsonSchema.type[0];
}
}
// Recursively process object properties
@ -248,7 +263,8 @@ export function mapOpenApiSchemaToJsonSchema(
if (typeof propSchema === 'object' && propSchema !== null) {
mappedProps[key] = mapOpenApiSchemaToJsonSchema(
propSchema as OpenAPIV3.SchemaObject,
seen
seen,
simplifyTypes
);
} else if (typeof propSchema === 'boolean') {
mappedProps[key] = propSchema;
@ -266,7 +282,8 @@ export function mapOpenApiSchemaToJsonSchema(
) {
jsonSchema.items = mapOpenApiSchemaToJsonSchema(
jsonSchema.items as OpenAPIV3.SchemaObject | OpenAPIV3.ReferenceObject,
seen
seen,
simplifyTypes
);
}
return jsonSchema;

View File

@ -35,6 +35,8 @@ export interface CliOptions {
* false = exclude by default unless x-mcp explicitly enables.
*/
defaultInclude?: boolean;
/** Flatten single-element type arrays in the JSON schema to their single value */
simplifyTypes?: string;
}
/**