diff --git a/src/parser/extract-tools.ts b/src/parser/extract-tools.ts index 6371623..4e4f63c 100644 --- a/src/parser/extract-tools.ts +++ b/src/parser/extract-tools.ts @@ -81,7 +81,7 @@ export function extractToolsFromApi( // Generate input schema and extract parameters const { inputSchema, parameters, requestBodyContentType } = - generateInputSchemaAndDetails(operation); + generateInputSchemaAndDetails(operation, pathItem.parameters); // Extract parameter details for execution const executionParameters = parameters.map((p) => ({ name: p.name, in: p.in })); @@ -113,9 +113,13 @@ export function extractToolsFromApi( * Generates input schema and extracts parameter details from an operation * * @param operation OpenAPI operation object + * @param pathParameters Optional path-level parameters that apply to all operations in the path * @returns Input schema, parameters, and request body content type */ -export function generateInputSchemaAndDetails(operation: OpenAPIV3.OperationObject): { +export function generateInputSchemaAndDetails( + operation: OpenAPIV3.OperationObject, + pathParameters?: (OpenAPIV3.ParameterObject | OpenAPIV3.ReferenceObject)[] +): { inputSchema: JSONSchema7 | boolean; parameters: OpenAPIV3.ParameterObject[]; requestBodyContentType?: string; @@ -123,11 +127,32 @@ export function generateInputSchemaAndDetails(operation: OpenAPIV3.OperationObje const properties: { [key: string]: JSONSchema7 | boolean } = {}; const required: string[] = []; - // Process parameters - const allParameters: OpenAPIV3.ParameterObject[] = Array.isArray(operation.parameters) + // Process parameters - merge path parameters with operation parameters + const operationParameters: OpenAPIV3.ParameterObject[] = Array.isArray(operation.parameters) ? operation.parameters.map((p) => p as OpenAPIV3.ParameterObject) : []; + const pathParametersResolved: OpenAPIV3.ParameterObject[] = Array.isArray(pathParameters) + ? pathParameters.map((p) => p as OpenAPIV3.ParameterObject) + : []; + + // Combine path parameters and operation parameters + // Operation parameters override path parameters if they have the same name/location + const allParameters: OpenAPIV3.ParameterObject[] = [...pathParametersResolved]; + + operationParameters.forEach(opParam => { + const existingIndex = allParameters.findIndex( + pathParam => pathParam.name === opParam.name && pathParam.in === opParam.in + ); + if (existingIndex >= 0) { + // Override path parameter with operation parameter + allParameters[existingIndex] = opParam; + } else { + // Add new operation parameter + allParameters.push(opParam); + } + }); + allParameters.forEach((param) => { if (!param.name || !param.schema) return;