Skip to main content
Glama
mcp-swagger-ui-technical-documentation.md16.1 kB
# MCP Swagger UI 技术文档 ## 概述 MCP Swagger UI 是一个基于 Vue 3 的现代化前端应用,用于将 OpenAPI/Swagger 规范转换为 Model Context Protocol (MCP) 格式。该应用采用 Apple 风格的设计理念,提供简洁、直观的用户界面。 ## 技术栈 ### 核心框架 - **Vue 3.4+**: 采用 Composition API,提供更好的类型推断和代码组织 - **TypeScript**: 全面的类型安全保障 - **Vite 5.0+**: 现代化的构建工具,提供快速的开发体验 ### UI 框架 - **Element Plus 2.4+**: Vue 3 的企业级 UI 组件库 - **Element Plus Icons**: 丰富的图标组件 - **Apple 风格自定义样式**: 渐变背景、圆角卡片、柔和阴影 ### 状态管理 - **Pinia 2.1+**: Vue 3 官方推荐的状态管理库 - **TypeScript 接口**: 强类型状态定义 ### 网络请求 - **Axios 1.6+**: HTTP 客户端,支持请求/响应拦截器 - **代理配置**: 开发环境自动代理到后端服务 ### 开发工具 - **ESLint + Prettier**: 代码规范和格式化 - **Vue TSC**: TypeScript 类型检查 - **Unplugin Auto Import**: 自动导入 Vue APIs - **Unplugin Vue Components**: 自动导入组件 ## 项目结构 ``` packages/mcp-swagger-ui/ ├── public/ # 静态资源 ├── src/ │ ├── components/ # 可复用组件 │ │ ├── ApiPreview.vue # API 预览组件 │ │ ├── ConfigSection.vue # 配置面板组件 │ │ ├── PageHeader.vue # 页面头部组件 │ │ └── ResultSection.vue # 结果展示组件 │ ├── router/ # Vue Router 配置 │ │ └── index.ts # 路由定义 │ ├── stores/ # Pinia 状态管理 │ │ └── app.ts # 应用全局状态 │ ├── types/ # TypeScript 类型定义 │ │ └── index.ts # 接口和类型声明 │ ├── utils/ # 工具函数 │ │ ├── api.ts # API 调用封装 │ │ └── demo-data.ts # 演示数据 │ ├── views/ # 页面组件 │ │ └── Home.vue # 主页面 │ ├── App.vue # 根组件 │ └── main.ts # 应用入口 ├── .env.development # 开发环境配置 ├── .env.production # 生产环境配置 ├── package.json # 项目依赖和脚本 ├── vite.config.ts # Vite 配置 └── tsconfig.json # TypeScript 配置 ``` ## 核心模块详解 ### 1. 主页面组件 (Home.vue) `Home.vue` 是应用的核心组件,采用 Apple 风格设计,集成了所有主要功能。 #### 组件结构 ```vue <template> <div class="container"> <!-- 头部:品牌展示和功能介绍 --> <div class="header"> <!-- 应用标题和描述 --> </div> <div class="main-content"> <!-- 输入部分:多标签页输入 --> <div class="input-section"> <!-- URL/文件/文本输入 --> </div> <!-- API 预览:解析后的信息展示 --> <div class="preview-section"> <!-- API 基本信息和端点列表 --> </div> <!-- 配置部分:转换参数设置 --> <div class="config-section"> <!-- HTTP 方法过滤、高级选项、传输协议 --> </div> <!-- 结果部分:转换结果展示 --> <div class="results-section"> <!-- MCP 配置文件预览和下载 --> </div> </div> <!-- 页脚:版权信息 --> <div class="footer"> </div> </div> </template> ``` #### 关键功能实现 **1. 多输入源支持** ```typescript // 状态管理 const activeTab = ref('url') const urlInput = ref('https://petstore.swagger.io/v2/swagger.json') const authInput = ref('') const textInput = ref('') const fileName = ref('') // 输入处理逻辑 const handleConvert = async () => { let content = '' let type: 'url' | 'file' | 'text' = 'url' switch (activeTab.value) { case 'url': content = urlInput.value type = 'url' break case 'file': content = textInput.value // 文件内容读取到 textInput type = 'file' break case 'text': content = textInput.value type = 'text' break } // 设置输入源并调用转换 appStore.setInputSource({ type, content, auth: authInput.value ? { type: 'bearer', token: authInput.value } : undefined }) await appStore.previewApi() await appStore.convertToMcp() } ``` **2. 文件拖放功能** ```typescript // 文件拖放状态 const isDragOver = ref(false) // 拖放事件处理 const handleFileDrop = (event: DragEvent) => { isDragOver.value = false const file = event.dataTransfer?.files[0] if (file) { fileName.value = file.name const reader = new FileReader() reader.onload = (e) => { textInput.value = e.target?.result as string } reader.readAsText(file) } } ``` **3. 进度指示器** ```typescript // 进度状态 const progressPercentage = ref(0) // 监听加载状态,模拟进度 watch(() => appStore.loading, (loading) => { if (loading) { progressPercentage.value = 0 const timer = setInterval(() => { progressPercentage.value += Math.random() * 15 if (progressPercentage.value >= 95) { progressPercentage.value = 95 clearInterval(timer) } }, 200) } else { progressPercentage.value = 100 } }) ``` ### 2. 状态管理 (stores/app.ts) 使用 Pinia 进行全局状态管理,包含输入源、配置、API 信息、转换结果等。 #### 状态结构 ```typescript interface AppState { inputSource: InputSource; // 输入源(URL/文件/文本) config: ConvertConfig; // 转换配置 apiInfo: OpenApiInfo | null; // API 基本信息 endpoints: ApiEndpoint[]; // API 端点列表 convertResult: ConvertResult | null; // 转换结果 loading: boolean; // 加载状态 error: string | null; // 错误信息 } ``` #### 核心 Actions **1. setInputSource() - 设置输入源** ```typescript setInputSource(source: Partial<InputSource>) { this.inputSource = { ...this.inputSource, ...source } this.clearResults() // 清除之前的结果 } ``` **2. previewApi() - 预览 API** ```typescript async previewApi() { if (!this.isValidInput) { throw new Error('请提供有效的输入内容') } this.loading = true this.error = null try { const result = await previewApi(this.inputSource) if (result.success && result.data) { this.apiInfo = result.data.apiInfo this.endpoints = result.data.endpoints || [] } else { this.error = result.error || '预览失败' } } catch (error) { this.error = error instanceof Error ? error.message : '预览失败' } finally { this.loading = false } } ``` **3. convertToMcp() - 转换为 MCP 格式** ```typescript async convertToMcp() { if (!this.isValidInput) { throw new Error('请提供有效的输入内容') } this.loading = true this.error = null try { const result = await convertApi({ source: this.inputSource, config: this.config }) if (result.success && result.data) { this.convertResult = result.data // 如果还没有预览数据,更新预览信息 if (!this.apiInfo && result.data.metadata) { this.apiInfo = result.data.metadata.apiInfo } } else { this.error = result.error || '转换失败' } } catch (error) { this.error = error instanceof Error ? error.message : '转换失败' } finally { this.loading = false } } ``` #### Getters **1. availableTags - 获取可用标签** ```typescript availableTags: (state) => { const tags = new Set<string>() state.endpoints.forEach(endpoint => { endpoint.tags?.forEach(tag => tags.add(tag)) }) return Array.from(tags) } ``` **2. filteredEndpoints - 过滤后的端点** ```typescript filteredEndpoints: (state) => { return state.endpoints.filter(endpoint => { // 方法过滤 if (!state.config.filters.methods.includes(endpoint.method.toUpperCase())) { return false } // 标签过滤 if (state.config.filters.tags.length > 0) { const hasMatchingTag = endpoint.tags?.some(tag => state.config.filters.tags.includes(tag) ) if (!hasMatchingTag) return false } // 是否包含已弃用的端点 if (!state.config.filters.includeDeprecated && endpoint.deprecated) { return false } return true }) } ``` ### 3. API 层 (utils/api.ts) 封装了与后端服务的交互逻辑,支持演示模式。 #### Axios 实例配置 ```typescript const api = axios.create({ baseURL: import.meta.env.VITE_API_BASE_URL || '/api', timeout: 30000, headers: { 'Content-Type': 'application/json' } }) // 响应拦截器 api.interceptors.response.use( (response: any) => response.data, (error: any) => { console.error('API Error:', error) return Promise.reject(error) } ) ``` #### 核心 API 函数 **1. validateApi() - 验证 OpenAPI 规范** ```typescript export async function validateApi(source: InputSource): Promise<ApiResponse> { try { if (isDemoMode) { await delay(1000) // 模拟网络延迟 return { success: true, data: { valid: true }, message: '验证成功' } } const response = await api.post('/validate', { source }) return response } catch (error) { return { success: false, error: error instanceof Error ? error.message : '验证失败' } } } ``` **2. previewApi() - 预览 API 信息** ```typescript export async function previewApi(source: InputSource): Promise<ApiResponse> { try { if (isDemoMode) { await delay(1500) // 模拟网络延迟 return { success: true, data: { apiInfo: demoApiInfo, endpoints: demoEndpoints }, message: '预览成功' } } const response = await api.post('/preview', { source }) return response } catch (error) { return { success: false, error: error instanceof Error ? error.message : '预览失败' } } } ``` **3. convertApi() - 转换为 MCP 格式** ```typescript export async function convertApi(params: { source: InputSource config: ConvertConfig }): Promise<ApiResponse> { try { if (isDemoMode) { await delay(2000) // 模拟网络延迟 return { success: true, data: demoConvertResult, message: '转换成功' } } const response = await api.post('/convert', params) return response } catch (error) { return { success: false, error: error instanceof Error ? error.message : '转换失败' } } } ``` ### 4. 类型定义 (types/index.ts) 定义了完整的 TypeScript 接口,确保类型安全。 #### 核心接口 **1. InputSource - 输入源类型** ```typescript export interface InputSource { type: 'url' | 'file' | 'text'; content: string; auth?: { type: 'bearer' | 'apikey' | 'basic'; token: string; }; } ``` **2. ConvertConfig - 转换配置** ```typescript export interface ConvertConfig { filters: { methods: string[]; // HTTP 方法过滤 tags: string[]; // 标签过滤 includeDeprecated: boolean; // 是否包含已弃用端点 }; transport: 'stdio' | 'sse' | 'streamable'; // 传输协议 optimization: { generateValidation: boolean; // 生成参数验证 includeExamples: boolean; // 包含示例 optimizeNames: boolean; // 优化名称 }; } ``` **3. ConvertResult - 转换结果** ```typescript export interface ConvertResult { mcpConfig: { mcpServers: any; // MCP 服务器配置 tools: McpToolConfig[]; // MCP 工具列表 }; metadata: { apiInfo: OpenApiInfo; // API 基本信息 stats: { totalEndpoints: number; // 总端点数 convertedTools: number; // 转换的工具数 skippedEndpoints: number; // 跳过的端点数 }; }; processingTime: number; // 处理时间 } ``` ### 5. 工具函数 #### 文件下载 ```typescript export function downloadFile(content: string, filename: string, type = 'application/json') { const blob = new Blob([content], { type }) const url = URL.createObjectURL(blob) const link = document.createElement('a') link.href = url link.download = filename document.body.appendChild(link) link.click() document.body.removeChild(link) URL.revokeObjectURL(url) } ``` #### 剪贴板操作 ```typescript export async function copyToClipboard(text: string): Promise<boolean> { try { await navigator.clipboard.writeText(text) return true } catch (error) { console.error('复制失败:', error) return false } } ``` ## 样式设计 ### Apple 风格设计原则 1. **极简主义**: 清洁的界面,没有多余的视觉元素 2. **渐变背景**: 使用柔和的蓝紫色渐变 3. **圆角设计**: 所有卡片和按钮使用 8-15px 圆角 4. **柔和阴影**: 0 20px 40px rgba(0,0,0,0.1) 类型的阴影 5. **响应式设计**: 移动端友好的布局 ### 核心样式类 **1. 容器和布局** ```css .container { max-width: 1200px; margin: 0 auto; background: white; border-radius: 15px; box-shadow: 0 20px 40px rgba(0,0,0,0.1); overflow: hidden; } .main-content { padding: 40px; } ``` **2. 渐变和颜色** ```css .header { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 30px; text-align: center; } .btn-primary { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; } ``` **3. 动画效果** ```css .fade-in-up { animation: fadeInUp 0.6s ease-out; } @keyframes fadeInUp { from { opacity: 0; transform: translateY(30px); } to { opacity: 1; transform: translateY(0); } } ``` ## 配置文件 ### Vite 配置 (vite.config.ts) ```typescript export default defineConfig({ plugins: [ vue(), AutoImport({ resolvers: [ElementPlusResolver()], imports: ['vue', 'vue-router', 'pinia'], dts: true }), Components({ resolvers: [ElementPlusResolver()], dts: true }) ], resolve: { alias: { '@': resolve(__dirname, 'src') } }, server: { port: 3000, host: true, proxy: { '/api': { target: 'http://localhost:3322', changeOrigin: true, rewrite: (path) => path.replace(/^\/api/, '/api') } } } }) ``` ### 环境配置 ```bash # .env.development VITE_APP_TITLE=MCP Swagger Server VITE_API_BASE_URL=http://localhost:3000/api VITE_ENABLE_DEMO_MODE=true ``` ## 开发和构建 ### 开发环境启动 ```bash npm run dev ``` ### 类型检查 ```bash npm run type-check ``` ### 构建生产版本 ```bash npm run build ``` ### 代码规范检查 ```bash npm run lint ``` ## 主要特性 1. **响应式设计**: 支持桌面端和移动端 2. **多输入源**: URL、文件上传、文本粘贴 3. **实时预览**: 解析 OpenAPI 规范并展示信息 4. **配置灵活**: 支持端点过滤、传输协议选择等 5. **演示模式**: 支持离线演示,便于开发和测试 6. **类型安全**: 全面的 TypeScript 类型定义 7. **现代化构建**: 基于 Vite 的快速开发体验 ## 扩展建议 1. **多语言支持**: 添加 i18n 国际化 2. **主题切换**: 支持暗色主题 3. **历史记录**: 保存转换历史 4. **批量处理**: 支持批量转换多个 API 5. **导出格式**: 支持多种配置文件格式 6. **在线编辑**: 集成 Monaco Editor 进行在线编辑 7. **测试工具**: 集成 API 测试功能 这个技术文档涵盖了 MCP Swagger UI 项目的核心架构、主要模块、关键函数和设计思路,为进一步开发提供了详细的技术指南。

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

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