UNPKG

@smartbear/mcp

Version:

MCP server for interacting SmartBear Products

72 lines (71 loc) 2.78 kB
import yaml from "js-yaml"; // @ts-expect-error missing type declarations import Swagger from "swagger-client"; import { ToolError } from "../../common/types.js"; import { RemoteOpenAPIDocumentSchema, } from "./ai.js"; /** * Resolve the OpenAPI specification from the provided input. * * @param remoteOpenAPIDocument The remote OpenAPI document to resolve. * @returns The resolved OpenAPI document. * @throws Error if the resolution fails. */ export async function resolveOpenAPISpec(remoteOpenAPIDocument) { const openAPISchema = RemoteOpenAPIDocumentSchema.safeParse(remoteOpenAPIDocument); if (openAPISchema.error || !remoteOpenAPIDocument) { throw new ToolError(`Invalid RemoteOpenAPIDocument: ${JSON.stringify(openAPISchema.error?.issues)}`); } const unresolvedSpec = await getRemoteSpecContents(openAPISchema.data); const resolvedSpec = await Swagger.resolve({ spec: unresolvedSpec }); if (resolvedSpec.errors?.length) { throw new ToolError(`Failed to resolve OpenAPI document: ${resolvedSpec.errors?.join(", ")}`); } return resolvedSpec.spec; } /** * Fetch the contents of a remote OpenAPI document. * * @param openAPISchema The schema for the remote OpenAPI document. * @returns A promise that resolves to a map of the OpenAPI document contents. * @throws Error if the URL is not provided or the fetch fails. */ export async function getRemoteSpecContents(openAPISchema) { if (!openAPISchema.url) { throw new ToolError("'url' must be provided."); } let headers = {}; if (openAPISchema.authToken) { headers = { Authorization: `${openAPISchema.authScheme ?? "Bearer"} ${openAPISchema.authToken}`, }; } const remoteSpec = await fetch(openAPISchema.url, { headers, method: "GET", }); const specRawBody = await remoteSpec.text(); try { return JSON.parse(specRawBody); } catch (jsonError) { try { return yaml.load(specRawBody); } catch (yamlError) { throw new ToolError(`Unsupported Content-Type: ${remoteSpec.headers.get("Content-Type")} for remote OpenAPI document. Found following parse errors:-\nJSON parse error: ${jsonError}\nYAML parse error: ${yamlError}`); } } } /** * Adds the OpenAPI specification to the input schema if a remote document is provided. * * @param inputSchema The input schema to modify. * @returns The modified input schema with the OpenAPI specification added. */ export async function addOpenAPISpecToSchema(inputSchema) { if (inputSchema.remoteDocument) { const resolvedSpec = await resolveOpenAPISpec(inputSchema.remoteDocument); inputSchema.document = resolvedSpec; } return inputSchema; }