Skip to main content
Glama
swagger.ts4.64 kB
import { SwaggerEndpoint, SwaggerParameter } from "./types.js"; export class SwaggerDocumentationParser { private swaggerUrl: string; private endpoints: SwaggerEndpoint[] = []; private parsed: boolean = false; constructor(swaggerUrl: string) { this.swaggerUrl = swaggerUrl; } async parseDocumentation(): Promise<void> { try { console.log(`🔍 Parsing Swagger documentation from: ${this.swaggerUrl}`); // Instead of using SwaggerParser.validate, fetch and parse the JSON directly // This avoids issues with complex $ref resolution const response = await fetch(this.swaggerUrl); if (!response.ok) { throw new Error(`HTTP ${response.status}: ${response.statusText}`); } const api = (await response.json()) as any; console.log( `📊 Swagger JSON fetched successfully. Found ${ Object.keys(api.paths || {}).length } paths` ); // Validate basic structure if (!api.openapi && !api.swagger) { throw new Error( "Invalid OpenAPI/Swagger specification: missing version field" ); } if (!api.paths) { throw new Error("Invalid OpenAPI/Swagger specification: missing paths"); } this.endpoints = this.extractEndpoints(api); console.log(`✅ Extracted ${this.endpoints.length} endpoints`); this.parsed = true; } catch (error) { console.error(`❌ Swagger parsing failed for ${this.swaggerUrl}:`, error); throw new Error( `Failed to parse Swagger documentation: ${ error instanceof Error ? error.message : "Unknown error" }` ); } } private extractEndpoints(api: any): SwaggerEndpoint[] { const endpoints: SwaggerEndpoint[] = []; if (!api.paths) { return endpoints; } for (const [path, pathItem] of Object.entries(api.paths)) { if (typeof pathItem !== "object" || pathItem === null) continue; const methods = [ "get", "post", "put", "delete", "patch", "options", "head", ]; for (const method of methods) { const operation = (pathItem as any)[method]; if (!operation) continue; const endpoint: SwaggerEndpoint = { path, method: method.toUpperCase(), summary: operation.summary, description: operation.description, parameters: this.extractParameters( operation.parameters, (pathItem as any).parameters ), requestBody: operation.requestBody, responses: operation.responses, }; endpoints.push(endpoint); } } return endpoints; } private extractParameters( operationParams: any[] = [], pathParams: any[] = [] ): SwaggerParameter[] { const allParams = [...(pathParams || []), ...(operationParams || [])]; return allParams.map((param) => ({ name: param.name, in: param.in, required: param.required || false, schema: param.schema, description: param.description, })); } getEndpoints(): SwaggerEndpoint[] { if (!this.parsed) { throw new Error( "Documentation not parsed yet. Call parseDocumentation() first." ); } return this.endpoints; } getEndpoint(path: string, method: string): SwaggerEndpoint | undefined { return this.endpoints.find( (endpoint) => endpoint.path === path && endpoint.method.toLowerCase() === method.toLowerCase() ); } getEndpointsByPath(path: string): SwaggerEndpoint[] { return this.endpoints.filter((endpoint) => endpoint.path === path); } getEndpointsByMethod(method: string): SwaggerEndpoint[] { return this.endpoints.filter( (endpoint) => endpoint.method.toLowerCase() === method.toLowerCase() ); } searchEndpoints(query: string): SwaggerEndpoint[] { const lowerQuery = query.toLowerCase(); return this.endpoints.filter( (endpoint) => endpoint.path.toLowerCase().includes(lowerQuery) || endpoint.summary?.toLowerCase().includes(lowerQuery) || endpoint.description?.toLowerCase().includes(lowerQuery) ); } getEndpointSummary(): string { if (!this.parsed) { return "Documentation not loaded"; } const summary = this.endpoints .map( (endpoint) => `${endpoint.method} ${endpoint.path}${ endpoint.summary ? ` - ${endpoint.summary}` : "" }` ) .join("\n"); return `Available endpoints (${this.endpoints.length}):\n${summary}`; } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/gyuco/mcp-http-client'

If you have feedback or need assistance with the MCP directory API, please join our Discord server