Compare commits

...

3 Commits

Author SHA1 Message Date
copilot-swe-agent[bot]
d943231672 Implement BYO OpenAPIV3.Document support in getToolsFromOpenApi
Co-authored-by: harsha-iiiv <31560965+harsha-iiiv@users.noreply.github.com>
2025-08-18 04:33:51 +00:00
copilot-swe-agent[bot]
99d3ba15d2 Initial plan for BYO OpenAPIV3.Document support
Co-authored-by: harsha-iiiv <31560965+harsha-iiiv@users.noreply.github.com>
2025-08-18 04:29:37 +00:00
copilot-swe-agent[bot]
8949a0290c Initial plan 2025-08-18 04:26:56 +00:00
3 changed files with 43 additions and 9 deletions

View File

@ -22,7 +22,7 @@ This function extracts an array of tools from an OpenAPI specification.
**Parameters:**
- `specPathOrUrl`: Path to a local OpenAPI spec file or URL to a remote spec
- `specPathOrUrl`: Path to a local OpenAPI spec file, URL to a remote spec, or a pre-parsed OpenAPIV3.Document
- `options`: (Optional) Configuration options
**Options:**
@ -62,6 +62,17 @@ for (const tool of filteredTools) {
console.log(` Method: ${tool.method.toUpperCase()} ${tool.pathTemplate}`);
console.log(` OperationId: ${tool.operationId}`);
}
// Using a pre-parsed OpenAPI document (helpful when @apidevtools/swagger-parser fails)
import { parse } from '@readme/openapi-parser';
import { OpenAPIV3 } from 'openapi-types';
const api = await parse<OpenAPIV3.Document>(
'https://problematic-api-spec.com/openapi.json',
{ dereference: { circular: true } }
);
const tools = await getToolsFromOpenApi(api);
```
## Tool Definition Structure

4
package-lock.json generated
View File

@ -1,12 +1,12 @@
{
"name": "openapi-mcp-generator",
"version": "3.1.2",
"version": "3.1.4",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "openapi-mcp-generator",
"version": "3.1.2",
"version": "3.1.4",
"license": "MIT",
"dependencies": {
"@apidevtools/swagger-parser": "^10.1.1",

View File

@ -9,6 +9,16 @@ import { extractToolsFromApi } from './parser/extract-tools.js';
import { McpToolDefinition } from './types/index.js';
import { determineBaseUrl } from './utils/url.js';
/**
* Type guard to check if the input is an OpenAPI document
*
* @param spec Input that could be a string or OpenAPIV3.Document
* @returns True if input is an OpenAPIV3.Document, false otherwise
*/
function isOpenApiDocument(spec: string | OpenAPIV3.Document): spec is OpenAPIV3.Document {
return typeof spec === 'object' && spec !== null && 'openapi' in spec;
}
/**
* Options for generating the MCP tools
*/
@ -29,19 +39,32 @@ export interface GetToolsOptions {
/**
* Get a list of tools from an OpenAPI specification
*
* @param specPathOrUrl Path or URL to the OpenAPI specification
* @param specPathOrUrl Path or URL to the OpenAPI specification, or a pre-parsed OpenAPI document
* @param options Options for generating the tools
* @returns Promise that resolves to an array of tool definitions
*/
export async function getToolsFromOpenApi(
specPathOrUrl: string,
specPathOrUrl: string | OpenAPIV3.Document,
options: GetToolsOptions = {}
): Promise<McpToolDefinition[]> {
try {
// Parse the OpenAPI spec
const api = options.dereference
// Parse the OpenAPI spec or use the provided document
let api: OpenAPIV3.Document;
if (isOpenApiDocument(specPathOrUrl)) {
// Input is already a parsed OpenAPI document
api = specPathOrUrl;
// If dereference option is requested, apply it to the document
if (options.dereference) {
api = (await SwaggerParser.dereference(api)) as OpenAPIV3.Document;
}
} else {
// Input is a string path or URL, parse it
api = options.dereference
? ((await SwaggerParser.dereference(specPathOrUrl)) as OpenAPIV3.Document)
: ((await SwaggerParser.parse(specPathOrUrl)) as OpenAPIV3.Document);
}
// Extract tools from the API
const allTools = extractToolsFromApi(api);