Skip to main content
Glama
tuskermanshu

Swagger MCP Server

by tuskermanshu

generate-api-client

Create API client code in TypeScript for Axios, Fetch, or React Query from any Swagger/OpenAPI document. Customize output directory, file structure, and tags for efficient integration.

Instructions

Generate API client code from Swagger/OpenAPI document.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
clientTypeNoAPI client technology stack
excludeTagsNoExclude tags filter
filePrefixNoFile prefix
fileSuffixNoFile suffix
generateTypeImportsNoWhether to generate type imports
groupByNoGrouping method
headersNoRequest headers
includeTagsNoInclude tags filter
outputDirNoOutput directory
overwriteNoWhether to overwrite existing files
swaggerUrlYesSwagger/OpenAPI document URL
typesImportPathNoTypes import path

Implementation Reference

  • The execute method implements the handler logic for the 'generate-api-client' MCP tool. It instantiates ApiClientGenerator, calls its generate method, and formats the response for MCP.
    async execute(params: z.infer<typeof this.optimizedSchema>) { try { console.log(`[ApiClientGeneratorTool] 开始生成API客户端: ${params.swaggerUrl}`); // 创建生成器实例 const generator = new ApiClientGenerator(); // 记录进度的函数 let progressUpdates: { progress: number, message: string }[] = []; const progressCallback = (progress: number, message: string) => { progressUpdates.push({ progress, message }); }; // 执行生成 const result = await generator.generate({ ...params, progressCallback } as ApiClientGeneratorOptions); // 处理结果 if (result.success) { console.log(`[ApiClientGeneratorTool] 客户端生成成功,生成了 ${result.files.length} 个文件`); return { content: [ { type: 'text' as const, text: JSON.stringify({ success: true, files: result.files, warnings: result.warnings, progress: progressUpdates }, null, 2) } ] }; } else { console.error(`[ApiClientGeneratorTool] 客户端生成失败: ${result.error}`); return { content: [ { type: 'text' as const, text: JSON.stringify({ success: false, error: result.error, progress: progressUpdates }, null, 2) } ] }; } } catch (error) { console.error(`[ApiClientGeneratorTool] 执行异常:`, error); // 返回错误结果 return { content: [ { type: 'text' as const, text: JSON.stringify({ success: false, error: error instanceof Error ? error.message : String(error) }, null, 2) } ] }; } }
  • Zod schema defining the input parameters and validation for the 'generate-api-client' tool.
    schema = z.object({ /** * Swagger/OpenAPI document URL */ swaggerUrl: z.string().describe('Swagger/OpenAPI document URL'), /** * Output directory */ outputDir: z.string().optional().describe('Output directory'), /** * Whether to overwrite existing files */ overwrite: z.boolean().optional().describe('Whether to overwrite existing files'), /** * File prefix */ filePrefix: z.string().optional().describe('File prefix'), /** * File suffix */ fileSuffix: z.string().optional().describe('File suffix'), /** * API client technology stack */ clientType: z.enum(['axios', 'fetch', 'react-query']).optional().describe('API client technology stack'), /** * Whether to generate type imports */ generateTypeImports: z.boolean().optional().describe('Whether to generate type imports'), /** * Types import path */ typesImportPath: z.string().optional().describe('Types import path'), /** * Grouping method */ groupBy: z.enum(['tag', 'path', 'none']).optional().describe('Grouping method'), /** * Include tags filter */ includeTags: z.array(z.string()).optional().describe('Include tags filter'), /** * Exclude tags filter */ excludeTags: z.array(z.string()).optional().describe('Exclude tags filter'), /** * Request headers */ headers: z.record(z.string()).optional().describe('Request headers') });
  • MCP tool registration for 'generate-api-client' using server.tool with name, description, schema, and handler.
    server.tool( this.name, this.description, this.schema.shape, async (params) => { return await this.execute(params); } );
  • src/index.ts:61-62 (registration)
    Invocation of the tool's register method on the MCP server during server setup in the main entry point.
    new TypeScriptTypesGeneratorTool().register(server); new ApiClientGeneratorTool().register(server);
  • The generate method of ApiClientGenerator class, which contains the detailed logic for parsing OpenAPI spec, grouping operations, and generating TypeScript API client code files. Called by the tool handler.
    async generate(options: ApiClientGeneratorOptions): Promise<CodeGenerationResult> { try { // 确保选项有效 if (!this.validateOptions(options)) { return { files: [], success: false, error: 'Invalid options. swaggerUrl is required.' }; } // 设置默认值 const outputDir = options.outputDir || './generated/api'; const overwrite = options.overwrite || false; const filePrefix = options.filePrefix || ''; const fileSuffix = options.fileSuffix || ''; const clientType = options.clientType || 'axios'; const generateTypeImports = options.generateTypeImports !== false; const typesImportPath = options.typesImportPath || '../types'; const groupBy = options.groupBy || 'tag'; const useCache = options.useCache !== false; const cacheTTLMinutes = options.cacheTTLMinutes || 60; const skipValidation = options.skipValidation || false; const lazyLoading = options.lazyLoading !== false; // 创建输出目录 await this.ensureDirectoryExists(outputDir); // 解析Swagger文档 console.log(`[ApiClientGenerator] 解析Swagger文档: ${options.swaggerUrl}`); // 设置进度日志 const logProgress = (progress: number, message: string) => { console.log(`[ApiClientGenerator] 进度 ${Math.round(progress * 100)}%: ${message}`); if (options.progressCallback) { options.progressCallback(progress, message); } }; // 使用优化的解析器 const parser = new OptimizedSwaggerApiParser({ url: options.swaggerUrl, headers: options.headers, useCache, cacheTTL: cacheTTLMinutes * 60 * 1000, // 转换为毫秒 skipValidation, lazyLoading, progressCallback: logProgress }); logProgress(0.1, '开始获取API文档'); const api = await parser.fetchApi(); logProgress(0.3, 'API文档获取完成,开始获取操作列表'); const operations = await parser.getAllOperations(); if (!operations || operations.length === 0) { return { files: [], success: false, error: 'No API operations found in Swagger document' }; } logProgress(0.4, `找到 ${operations.length} 个API操作,准备生成代码`); // 过滤操作 const filteredOperations = this.filterOperations(operations, options.includeTags, options.excludeTags); logProgress(0.5, `过滤后剩余 ${filteredOperations.length} 个API操作`); // 分组操作 const groupedOperations = this.groupOperations(filteredOperations, groupBy); // 生成客户端代码 const generatedFiles: string[] = []; const warnings: string[] = []; // 获取所有用到的模式 logProgress(0.6, '加载模式定义'); const schemas = await parser.getAllSchemas(); // 为每个分组生成文件 let fileCount = 0; const totalGroups = Object.keys(groupedOperations).length; for (const [groupName, operations] of Object.entries(groupedOperations)) { try { // 格式化分组名称 const formattedGroupName = this.formatGroupName(groupName); // 生成文件名 const fileName = `${filePrefix}${formattedGroupName}${fileSuffix}.ts`; const filePath = path.join(outputDir, fileName); // 检查文件是否存在 const fileExists = await this.fileExists(filePath); if (fileExists && !overwrite) { warnings.push(`跳过已存在的文件: ${fileName}`); continue; } // 生成客户端代码 const clientCode = this.generateClientCode({ groupName: formattedGroupName, operations, schemas, clientType, generateTypeImports, typesImportPath }); // 写入文件 await fs.writeFile(filePath, clientCode, 'utf8'); generatedFiles.push(filePath); // 更新进度 fileCount++; const progress = 0.6 + (0.3 * fileCount / totalGroups); logProgress(progress, `生成文件 ${fileCount}/${totalGroups}: ${fileName}`); } catch (err) { warnings.push(`无法处理分组 ${groupName}: ${err instanceof Error ? err.message : String(err)}`); } } // 生成索引文件 if (generatedFiles.length > 0) { const indexContent = this.generateIndexFile(generatedFiles, outputDir); const indexPath = path.join(outputDir, 'index.ts'); await fs.writeFile(indexPath, indexContent, 'utf8'); generatedFiles.push(indexPath); logProgress(0.95, `已生成索引文件: ${indexPath}`); } // 生成基础客户端配置文件 if (clientType === 'axios' || clientType === 'fetch') { const configFileName = `${clientType}-client.ts`; const configFilePath = path.join(outputDir, configFileName); if (!await this.fileExists(configFilePath) || overwrite) { const configCode = this.generateClientConfigCode(clientType); await fs.writeFile(configFilePath, configCode, 'utf8'); generatedFiles.push(configFilePath); logProgress(0.98, `已生成客户端配置文件: ${configFilePath}`); } } logProgress(1.0, `代码生成完成,共生成 ${generatedFiles.length} 个文件`); return { files: generatedFiles, success: true, warnings: warnings.length > 0 ? warnings : undefined }; } catch (error) { return { files: [], success: false, error: error instanceof Error ? error.message : String(error) }; } }

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/tuskermanshu/swagger-mcp-server'

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