Skip to main content
Glama
tuskermanshu

Swagger MCP Server

by tuskermanshu

generate-typescript-types

Generate TypeScript type definitions from Swagger/OpenAPI documents to ensure type safety in API integrations.

Instructions

Generate TypeScript type definitions from Swagger/OpenAPI document.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
swaggerUrlYesSwagger/OpenAPI document URL
outputDirNoOutput directory
overwriteNoWhether to overwrite existing files
filePrefixNoFile prefix
fileSuffixNoFile suffix
useNamespaceNoWhether to use namespace for wrapping types
namespaceNoNamespace name
generateEnumsNoWhether to generate enum types
strictTypesNoWhether to use strict types
excludeSchemasNoArray of schema names to exclude
includeSchemasNoArray of schema names to include
generateIndexNoWhether to generate an index file
headersNoRequest headers
useCacheNoWhether to use cache
cacheTTLMinutesNoCache TTL in minutes
skipValidationNoWhether to skip validation
lazyLoadingNoWhether to use lazy loading

Implementation Reference

  • src/index.ts:59-64 (registration)
    Registers all MCP tools including TypeScriptTypesGeneratorTool on the main MCP server instance.
    new SwaggerParserTool().register(server); new OptimizedSwaggerParserTool().register(server); new TypeScriptTypesGeneratorTool().register(server); new ApiClientGeneratorTool().register(server); new FileWriterTool().register(server); new TemplateManagerTool().register(server);
  • Registers the 'generate-typescript-types' tool on the MCP server using server.tool() with schema and handler.
    server.tool( this.name, this.description, this.schema.shape, async (params) => { // 使用默认参数 const options = { ...params, useCache: true, skipValidation: true, lazyLoading: false }; return await this.execute(options); } );
  • Zod input schema defining parameters for the generate-typescript-types tool, including swaggerUrl, outputDir, options like useNamespace, excludeSchemas, etc.
    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'), /** * Whether to use namespace */ useNamespace: z.boolean().optional().describe('Whether to use namespace for wrapping types'), /** * Namespace name */ namespace: z.string().optional().describe('Namespace name'), /** * Whether to generate enums */ generateEnums: z.boolean().optional().describe('Whether to generate enum types'), /** * Whether to use strict types */ strictTypes: z.boolean().optional().describe('Whether to use strict types'), /** * Excluded schema names */ excludeSchemas: z.array(z.string()).optional().describe('Array of schema names to exclude'), /** * Included schema names */ includeSchemas: z.array(z.string()).optional().describe('Array of schema names to include'), /** * Whether to generate index file */ generateIndex: z.boolean().optional().describe('Whether to generate an index file'), /** * Request headers */ headers: z.record(z.string()).optional().describe('Request headers'), /** * Whether to use cache */ useCache: z.boolean().optional().describe('Whether to use cache'), /** * Cache TTL in minutes */ cacheTTLMinutes: z.number().optional().describe('Cache TTL in minutes'), /** * Whether to skip validation */ skipValidation: z.boolean().optional().describe('Whether to skip validation'), /** * Whether to use lazy loading */ lazyLoading: z.boolean().optional().describe('Whether to use lazy loading') });
  • Handler function that executes the tool: creates TypeScriptTypesGenerator instance, calls its generate method with parameters, handles progress, success/error, and formats MCP response.
    async execute(params: z.infer<typeof this.schema>) { let progress = 0; let progressMessage = ''; // 定义进度回调 const progressCallback = (newProgress: number, message: string) => { progress = newProgress; progressMessage = message; console.log(`[Progress] ${Math.round(newProgress * 100)}%: ${message}`); }; try { console.log(`[TypeScriptTypesGeneratorTool] 开始生成TypeScript类型: ${params.swaggerUrl}`); console.log(`[TypeScriptTypesGeneratorTool] 缓存: ${params.useCache ? '启用' : '禁用'}, 懒加载: ${params.lazyLoading ? '启用' : '禁用'}`); // 创建生成器实例 const generator = new TypeScriptTypesGenerator(); // 执行生成 const result = await generator.generate({ ...params, progressCallback } as TypeScriptTypesGeneratorOptions); // 处理结果 if (result.success) { console.log(`[TypeScriptTypesGeneratorTool] 类型生成成功,生成了 ${result.files.length} 个文件`); return { content: [ { type: 'text' as const, text: JSON.stringify({ success: true, files: result.files, warnings: result.warnings, progress: 1.0, progressMessage: '完成' }, null, 2) } ] }; } else { console.error(`[TypeScriptTypesGeneratorTool] 类型生成失败: ${result.error}`); return { content: [ { type: 'text' as const, text: JSON.stringify({ success: false, error: result.error, progress: progress, progressMessage: progressMessage }, null, 2) } ] }; } } catch (error) { console.error(`[TypeScriptTypesGeneratorTool] 执行异常:`, error); // 返回错误结果 return { content: [ { type: 'text' as const, text: JSON.stringify({ success: false, error: error instanceof Error ? error.message : String(error), progress: progress, progressMessage: progressMessage }, null, 2) } ] }; } }
  • Core helper: TypeScriptTypesGenerator.generate() - parses OpenAPI, generates TS types/enums/interfaces from schemas, writes files.
    async generate(options: TypeScriptTypesGeneratorOptions): Promise<CodeGenerationResult> { try { // 确保选项有效 if (!this.validateOptions(options)) { return { files: [], success: false, error: 'Invalid options. swaggerUrl is required.' }; } // 设置默认值 const outputDir = options.outputDir || './generated'; const overwrite = options.overwrite || false; const filePrefix = options.filePrefix || ''; const fileSuffix = options.fileSuffix || ''; const useNamespace = options.useNamespace || false; const namespace = options.namespace || 'API'; const generateEnums = options.generateEnums !== false; const strictTypes = options.strictTypes || true; const generateIndex = options.generateIndex !== false; const useCache = options.useCache !== false; const skipValidation = options.skipValidation !== false; const lazyLoading = options.lazyLoading || false; const cacheTTLMinutes = options.cacheTTLMinutes || 60; // 创建输出目录 await this.ensureDirectoryExists(outputDir); // 定义进度回调 const progressCallback = options.progressCallback || ((progress: number, message: string) => { console.log(`[TypeScriptTypesGenerator] 进度: ${Math.round(progress * 100)}%, ${message}`); }); // 解析Swagger文档 console.log(`[TypeScriptTypesGenerator] 解析Swagger文档: ${options.swaggerUrl}`); // 使用优化的Swagger解析器 const parser = new OptimizedSwaggerApiParser({ url: options.swaggerUrl, headers: options.headers, skipValidation, useCache, cacheTTL: cacheTTLMinutes * 60 * 1000, lazyLoading, progressCallback }); // 获取API文档 const api = await parser.fetchApi(); // 获取模式定义 const schemas = await parser.getAllSchemas(); if (!schemas || Object.keys(schemas).length === 0) { return { files: [], success: false, error: 'No schemas found in Swagger document' }; } console.log(`[TypeScriptTypesGenerator] 找到 ${Object.keys(schemas).length} 个模式定义`); // 过滤模式 const filteredSchemas = this.filterSchemas(schemas, options.includeSchemas, options.excludeSchemas); console.log(`[TypeScriptTypesGenerator] 过滤后剩余 ${Object.keys(filteredSchemas).length} 个模式定义`); // 生成类型定义 const generatedFiles: string[] = []; const warnings: string[] = []; // 处理每个模式 for (const [schemaName, schema] of Object.entries(filteredSchemas)) { try { // 转换为TypeScript类型 const typeDefinition = this.convertSchemaToTypeScript(schemaName, schema, { schemas: filteredSchemas, useNamespace, namespace, generateEnums, strictTypes, typeMapping: options.typeMapping }); // 生成文件名 const fileName = `${filePrefix}${this.formatSchemaNameToFileName(schemaName)}${fileSuffix}.ts`; const filePath = path.join(outputDir, fileName); // 检查文件是否存在 const fileExists = await this.fileExists(filePath); if (fileExists && !overwrite) { warnings.push(`跳过已存在的文件: ${fileName}`); continue; } // 写入文件 await fs.writeFile(filePath, typeDefinition, 'utf8'); generatedFiles.push(filePath); console.log(`[TypeScriptTypesGenerator] 已生成: ${filePath}`); } catch (err) { warnings.push(`无法处理模式 ${schemaName}: ${err instanceof Error ? err.message : String(err)}`); } } // 生成索引文件 if (generateIndex && 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); console.log(`[TypeScriptTypesGenerator] 已生成索引文件: ${indexPath}`); } 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