Skip to main content
Glama
UI_UX_DESIGN.mdβ€’21.7 kB
# 🎨 UI/UX 섀계 - WorkflowMCP Dashboard API ## 🎯 섀계 원칙 1. **κΈ°μ‘΄ μ‚¬μš©μž κ²½ν—˜ 보쑴**: ν˜„μž¬ λŒ€μ‹œλ³΄λ“œ μ‚¬μš©μžμ—κ²Œ 영ν–₯ μ—†μŒ 2. **점진적 ν™•μž₯**: κΈ°μ‘΄ κΈ°λŠ₯ μœ„μ— API κΈ°λŠ₯ λ ˆμ΄μ–΄ μΆ”κ°€ 3. **ν•˜μœ„ ν˜Έν™˜μ„±**: κΈ°μ‘΄ API μ‚¬μš©μžμ—κ²Œ λ³€κ²½ 사항 미반영 4. **자기 μ„€λͺ…적**: μƒˆ μ‚¬μš©μžλ„ μ‰½κ²Œ ν•™μŠ΅ κ°€λŠ₯ 5. **개발자 μš°μ„ **: API μ‚¬μš©μ„±κ³Ό 개발자 κ²½ν—˜ μ΅œμš°μ„  ## πŸ”„ κΈ°μ‘΄ μ‹œμŠ€ν…œ ν˜Έν™˜μ„± μ „λž΅ ### 1. κΈ°μ‘΄ API 보쑴 방식 #### ν˜„μž¬ μƒνƒœ 뢄석 ν•„μš” ```javascript // κ΅¬ν˜„ μ „ κΈ°μ‘΄ API 쑰사 ν•„μˆ˜ const existingApiAudit = { // 1. ν˜„μž¬ λŒ€μ‹œλ³΄λ“œκ°€ μ‚¬μš©ν•˜λŠ” API μ—”λ“œν¬μΈνŠΈ 식별 currentEndpoints: [ // 예: '/api/prds', '/api/tasks' 등이 이미 μ‘΄μž¬ν•  수 있음 ], // 2. ν˜„μž¬ API 응닡 ν˜•μ‹ 뢄석 currentResponseFormats: { // κΈ°μ‘΄ ν˜•μ‹μ΄ μžˆλ‹€λ©΄ λ™μΌν•˜κ²Œ μœ μ§€ }, // 3. ν˜„μž¬ URL λΌμš°νŒ… νŒ¨ν„΄ 확인 currentRouting: { // κΈ°μ‘΄ λΌμš°νŒ…κ³Ό μΆ©λŒν•˜μ§€ μ•Šλ„λ‘ } }; ``` #### ν˜Έν™˜μ„± 보μž₯ μ „λž΅ ```javascript // κΈ°μ‘΄ API λž˜ν•‘ νŒ¨ν„΄ class BackwardCompatibilityLayer { constructor() { this.legacyFormatMap = new Map(); this.versionDetection = new Map(); } // κΈ°μ‘΄ API 호좜 감지 및 κΈ°μ‘΄ ν˜•μ‹μœΌλ‘œ 응닡 detectLegacyRequest(req) { // User-Agent, Headers, URL νŒ¨ν„΄μœΌλ‘œ κΈ°μ‘΄ μ‚¬μš©μž 감지 if (req.headers['user-agent']?.includes('SvelteKit') || req.headers['x-legacy-client'] === 'true') { return true; } return false; } formatResponse(data, isLegacy = false) { if (isLegacy) { // κΈ°μ‘΄ ν˜•μ‹ μœ μ§€ return data; } else { // μƒˆλ‘œμš΄ ν‘œμ€€ ν˜•μ‹ return { success: true, data: data, links: this.generateHateoasLinks(), timestamp: new Date().toISOString() }; } } } ``` ### 2. 점진적 λ§ˆμ΄κ·Έλ ˆμ΄μ…˜ κ³„νš #### Phase 1: μƒˆ μ—”λ“œν¬μΈνŠΈλ§Œ μΆ”κ°€ ``` κΈ°μ‘΄ μœ μ§€: - /api/prds (κΈ°μ‘΄ ν˜•μ‹) - /api/tasks (κΈ°μ‘΄ ν˜•μ‹) - /api/documents (κΈ°μ‘΄ ν˜•μ‹) μƒˆλ‘œ μΆ”κ°€: - /api/v1/prds (μƒˆ ν‘œμ€€ ν˜•μ‹) - /api/v1/tasks (μƒˆ ν‘œμ€€ ν˜•μ‹) - /api/v1/documents (μƒˆ ν‘œμ€€ ν˜•μ‹) - /api/help/* (μ™„μ „ μ‹ κ·œ) - /api/discovery/* (μ™„μ „ μ‹ κ·œ) ``` #### Phase 2: κΈ°μ‘΄ API 점진적 ν™•μž₯ (선택사항) ```javascript // κΈ°μ‘΄ μ—”λ“œν¬μΈνŠΈμ— 선택적 κΈ°λŠ₯ μΆ”κ°€ app.get('/api/prds', (req, res) => { // κΈ°μ‘΄ 둜직 μœ μ§€ const legacyResult = await existingPrdHandler(req); // μƒˆλ‘œμš΄ ν΄λΌμ΄μ–ΈνŠΈ μš”μ²­ μ‹œμ—λ§Œ ν™•μž₯ κΈ°λŠ₯ 제곡 if (req.query.include_links === 'true') { legacyResult.links = generateHateoasLinks(); } if (req.query.include_help === 'true') { legacyResult.help = '/api/help/prds'; } res.json(legacyResult); }); ``` ### 3. κΈ°μ‘΄ λŒ€μ‹œλ³΄λ“œ 영ν–₯도 μ΅œμ†Œν™” #### λŒ€μ‹œλ³΄λ“œ API μ‚¬μš© νŒ¨ν„΄ 보쑴 ```javascript // λŒ€μ‹œλ³΄λ“œ μ „μš© 미듀웨어 const dashboardCompatibility = (req, res, next) => { // λŒ€μ‹œλ³΄λ“œμ—μ„œ μ˜€λŠ” μš”μ²­ 감지 if (req.headers['referer']?.includes('localhost:3301') || req.headers['x-dashboard-client'] === 'true') { // λŒ€μ‹œλ³΄λ“œμš© 응닡 ν˜•μ‹ μœ μ§€ req.useLegacyFormat = true; req.skipHateoas = true; } next(); }; // λŒ€μ‹œλ³΄λ“œ μš”μ²­μ€ κΈ°μ‘΄ ν˜•μ‹ μœ μ§€ app.use('/api', dashboardCompatibility); ``` ## πŸ–₯️ API μ‚¬μš©μ„± 섀계 ### 1. 개발자 κ²½ν—˜ (DX) μ΅œμ ν™” #### API 탐색 μΈν„°νŽ˜μ΄μŠ€ ```html <!-- /api/console - λ‚΄μž₯ API 탐색 도ꡬ --> <!DOCTYPE html> <html> <head> <title>WorkflowMCP API Console</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <style> body { font-family: -apple-system, BlinkMacSystemFont, sans-serif; margin: 0; } .container { max-width: 1200px; margin: 0 auto; padding: 20px; } .api-section { margin: 20px 0; padding: 20px; border: 1px solid #ddd; border-radius: 8px; } .endpoint { background: #f5f5f5; padding: 10px; margin: 10px 0; border-radius: 4px; } .method { display: inline-block; padding: 4px 8px; border-radius: 3px; color: white; font-weight: bold; } .get { background: #4CAF50; } .post { background: #2196F3; } .put { background: #FF9800; } .delete { background: #F44336; } .try-button { background: #007bff; color: white; border: none; padding: 8px 16px; border-radius: 4px; cursor: pointer; } .response-area { background: #f8f9fa; border: 1px solid #dee2e6; border-radius: 4px; padding: 15px; margin-top: 10px; } .help-link { color: #007bff; text-decoration: none; margin-left: 10px; } .help-link:hover { text-decoration: underline; } </style> </head> <body> <div class="container"> <h1>πŸ”Œ WorkflowMCP API Console</h1> <p>Interactive API exploration tool. No authentication required for local development.</p> <!-- API Discovery Section --> <div class="api-section"> <h2>πŸ” Start Here - API Discovery</h2> <div class="endpoint"> <span class="method get">GET</span> <strong>/api</strong> <span> - Complete API overview</span> <a href="/api/help/getting-started" class="help-link">πŸ“– Getting Started Guide</a> <br> <button class="try-button" onclick="tryEndpoint('/api')">Try It</button> </div> </div> <!-- PRD Management Section --> <div class="api-section"> <h2>πŸ“‹ PRD Management</h2> <div class="endpoint"> <span class="method get">GET</span> <strong>/api/prds</strong> <span> - List all PRDs</span> <a href="/api/help/prds/collection" class="help-link">πŸ“– Help</a> <br> <button class="try-button" onclick="tryEndpoint('/api/prds')">Try It</button> </div> <div class="endpoint"> <span class="method post">POST</span> <strong>/api/prds</strong> <span> - Create new PRD</span> <a href="/api/help/prds/examples" class="help-link">πŸ“ Examples</a> <br> <button class="try-button" onclick="showCreateForm('prd')">Create PRD</button> </div> </div> <!-- Task Management Section --> <div class="api-section"> <h2>πŸ“ Task Management</h2> <div class="endpoint"> <span class="method get">GET</span> <strong>/api/tasks</strong> <span> - List all tasks</span> <a href="/api/help/tasks/collection" class="help-link">πŸ“– Help</a> <br> <button class="try-button" onclick="tryEndpoint('/api/tasks')">Try It</button> </div> </div> <!-- Response Area --> <div class="api-section"> <h3>πŸ“€ API Response</h3> <div id="response-area" class="response-area"> <p><em>Click "Try It" on any endpoint above to see the response here.</em></p> </div> </div> <!-- Quick Help --> <div class="api-section"> <h3>πŸ†˜ Quick Help</h3> <ul> <li><a href="/api/help/getting-started">Getting Started Guide</a> - New to the API? Start here!</li> <li><a href="/api/discovery/categories">Browse by Category</a> - Explore API by functional area</li> <li><a href="/api/health">System Health</a> - Check if everything is running smoothly</li> <li><a href="/api/help/errors">Error Reference</a> - Common errors and solutions</li> </ul> </div> </div> <script> async function tryEndpoint(endpoint) { const responseArea = document.getElementById('response-area'); responseArea.innerHTML = '<p><em>Loading...</em></p>'; try { const response = await fetch(endpoint); const data = await response.json(); responseArea.innerHTML = ` <h4>Response (${response.status})</h4> <pre style="white-space: pre-wrap; overflow-x: auto;">${JSON.stringify(data, null, 2)}</pre> `; } catch (error) { responseArea.innerHTML = ` <h4>Error</h4> <p style="color: red;">${error.message}</p> `; } } function showCreateForm(type) { const responseArea = document.getElementById('response-area'); const examples = { prd: { title: "User Authentication System", description: "Implement JWT-based user authentication", priority: "high", status: "draft" } }; responseArea.innerHTML = ` <h4>Create ${type.toUpperCase()}</h4> <textarea id="create-data" style="width: 100%; height: 200px; font-family: monospace;"> ${JSON.stringify(examples[type], null, 2)} </textarea> <br><br> <button class="try-button" onclick="submitCreate('${type}')">Submit</button> <a href="/api/help/${type}s/examples" class="help-link">πŸ“ More Examples</a> `; } async function submitCreate(type) { const data = document.getElementById('create-data').value; const responseArea = document.getElementById('response-area'); try { const response = await fetch(`/api/${type}s`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: data }); const result = await response.json(); responseArea.innerHTML = ` <h4>Create Response (${response.status})</h4> <pre style="white-space: pre-wrap;">${JSON.stringify(result, null, 2)}</pre> `; } catch (error) { responseArea.innerHTML = ` <h4>Error</h4> <p style="color: red;">${error.message}</p> `; } } </script> </body> </html> ``` ### 2. 점진적 ν•™μŠ΅ κ²½ν—˜ #### ν•™μŠ΅ 경둜 섀계 ``` Level 1: κΈ°λ³Έ 탐색 β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ GET /api β”‚ ← μ‹œμž‘μ  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β–Ό β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ μΉ΄ν…Œκ³ λ¦¬ 선택 β”‚ β”‚ (prds/tasks) β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ Level 2: κΈ°λŠ₯ 이해 β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ /api/help/prds/ β”‚ ← 도움말 확인 β”‚ overview β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β–Ό β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ 예제 확인 β”‚ β”‚ /help/examples β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ Level 3: μ‹€μ œ μ‚¬μš© β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ μŠ€ν‚€λ§ˆ 확인 β”‚ β”‚ /api/schemas β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β–Ό β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ API 호좜 β”‚ β”‚ POST /api/prds β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` #### 상황별 κ°€μ΄λ“œ 제곡 ```json // GET /api/help/getting-started?context=new_session { "title": "New Session Quick Start", "estimated_time": "5 minutes", "steps": [ { "step": 1, "title": "Explore the API structure", "action": "GET /api", "why": "Understand what's available and where to find it" }, { "step": 2, "title": "Choose your area of interest", "options": [ {"area": "PRD Management", "start": "/api/help/prds/overview"}, {"area": "Task Management", "start": "/api/help/tasks/overview"}, {"area": "Document Management", "start": "/api/help/documents/overview"} ] }, { "step": 3, "title": "Try a simple operation", "suggestion": "GET /api/prds - List existing PRDs (safe, read-only)" } ], "shortcuts": { "api_console": "/api/console", "common_examples": "/api/help/examples/common", "troubleshooting": "/api/help/troubleshooting" } } ``` ### 3. μ—λŸ¬ κ²½ν—˜ κ°œμ„  #### μΉœν™”μ  μ—λŸ¬ λ©”μ‹œμ§€ ```json // 400 μ—λŸ¬ 응닡 μ˜ˆμ‹œ { "success": false, "error": { "code": "VALIDATION_ERROR", "message": "We couldn't process your request due to some validation issues", "user_friendly_message": "It looks like some required information is missing. Let me help you fix this!", "details": [ "The 'title' field is required and cannot be empty", "The 'priority' field must be one of: high, medium, low" ], "how_to_fix": { "title": "Add a descriptive title like 'User Authentication System'", "priority": "Set priority to 'high', 'medium', or 'low'" }, "helpful_links": { "examples": "/api/help/prds/examples", "schema": "/api/schemas/prd", "help": "/api/help/prds/troubleshooting" } }, "request_id": "req-123", "timestamp": "2025-09-11T16:00:00Z" } ``` #### μ—λŸ¬ 볡ꡬ κ°€μ΄λ“œ ```json // GET /api/help/errors/validation { "title": "Validation Error Solutions", "common_scenarios": [ { "error": "Field 'title' is required", "cause": "Empty or missing title in request body", "solution": "Add a title property with a non-empty string value", "example": { "wrong": "{}", "correct": "{\"title\": \"My PRD Title\"}" } }, { "error": "Invalid priority value", "cause": "Priority field contains invalid value", "solution": "Use only 'high', 'medium', or 'low'", "example": { "wrong": "{\"priority\": \"urgent\"}", "correct": "{\"priority\": \"high\"}" } } ], "prevention_tips": [ "Always check the schema first: GET /api/schemas/prd", "Use the API console for testing: /api/console", "Review examples: /api/help/prds/examples" ] } ``` ## πŸ“± λ‹€μ–‘ν•œ ν΄λΌμ΄μ–ΈνŠΈ 지원 ### 1. ν΄λΌμ΄μ–ΈνŠΈλ³„ μ΅œμ ν™” #### μ›Ή λŒ€μ‹œλ³΄λ“œ (κΈ°μ‘΄ μœ μ§€) ```javascript // λŒ€μ‹œλ³΄λ“œλŠ” κΈ°μ‘΄ νŒ¨ν„΄ μœ μ§€ const dashboardApiClient = { // κΈ°μ‘΄ ν˜•μ‹μœΌλ‘œ 계속 호좜 async getPrds() { const response = await fetch('/api/prds', { headers: { 'X-Dashboard-Client': 'true' } }); return response.json(); // κΈ°μ‘΄ ν˜•μ‹ 응닡 } }; ``` #### Claude Code μ„Έμ…˜ (μ‹ κ·œ μ΅œμ ν™”) ```javascript // Claude Code용 μ΅œμ ν™”λœ 응닡 const claudeApiClient = { async discoverApi() { // 자기 μ„€λͺ…적 응닡 const response = await fetch('/api', { headers: { 'User-Agent': 'Claude-Code-Session' } }); return response.json(); // μƒˆ ν‘œμ€€ ν˜•μ‹ }, async getHelp(topic) { const response = await fetch(`/api/help/${topic}`); return response.json(); // κ΅¬μ‘°ν™”λœ 도움말 } }; ``` #### λͺ¨λ°”일/μ¨λ“œνŒŒν‹° (ν–₯ν›„ 지원) ```javascript // λͺ¨λ°”일 μΉœν™”μ  응닡 app.get('/api/*', (req, res, next) => { if (req.headers['user-agent']?.includes('Mobile')) { req.mobileOptimized = true; // κ°„μ†Œν™”λœ 응닡 } next(); }); ``` ### 2. 응닡 ν˜•μ‹ 적응 #### μ»¨ν…μŠ€νŠΈλ³„ 응닡 μ‘°μ • ```javascript class ResponseFormatter { formatForClient(data, clientType) { switch (clientType) { case 'dashboard': // κΈ°μ‘΄ ν˜•μ‹ μœ μ§€ return data; case 'claude-code': // 자기 μ„€λͺ…적 ν˜•μ‹ return { success: true, data: data, links: this.generateHelpLinks(), guidance: this.generateGuidance(data), timestamp: new Date().toISOString() }; case 'mobile': // μ΅œμ†Œν™”λœ ν˜•μ‹ return { data: data, has_more: data.length >= this.limit }; default: // ν‘œμ€€ ν˜•μ‹ return this.standardFormat(data); } } generateGuidance(data) { // 데이터 기반 λ‹€μŒ 단계 μ œμ•ˆ if (Array.isArray(data) && data.length === 0) { return { suggestion: "No items found. Would you like to create one?", next_action: "POST " + this.getCreateEndpoint() }; } return null; } } ``` ## πŸ”§ 개발 도ꡬ 및 μœ ν‹Έλ¦¬ν‹° ### 1. API 검증 도ꡬ #### μžλ™ ν˜Έν™˜μ„± 검사기 ```javascript // GET /api/compatibility/check class CompatibilityChecker { async checkBackwardCompatibility() { const results = { dashboard_compatibility: await this.testDashboardEndpoints(), mcp_compatibility: await this.testMcpIntegration(), breaking_changes: await this.detectBreakingChanges() }; return { status: results.breaking_changes.length === 0 ? 'compatible' : 'warnings', results: results, recommendations: this.generateRecommendations(results) }; } async testDashboardEndpoints() { // λŒ€μ‹œλ³΄λ“œκ°€ μ‚¬μš©ν•˜λŠ” λͺ¨λ“  μ—”λ“œν¬μΈνŠΈ ν…ŒμŠ€νŠΈ const dashboardEndpoints = ['/api/prds', '/api/tasks', '/api/documents']; const results = []; for (const endpoint of dashboardEndpoints) { try { const response = await fetch(endpoint, { headers: { 'X-Dashboard-Client': 'true' } }); results.push({ endpoint, status: response.status, compatible: response.ok }); } catch (error) { results.push({ endpoint, status: 'error', compatible: false, error: error.message }); } } return results; } } ``` ### 2. λ§ˆμ΄κ·Έλ ˆμ΄μ…˜ 도ꡬ #### 점진적 μ—…κ·Έλ ˆμ΄λ“œ λ„μš°λ―Έ ```javascript // GET /api/migration/status class MigrationHelper { checkCurrentUsage() { return { legacy_endpoints_usage: this.analyzeLegacyUsage(), new_endpoints_adoption: this.analyzeNewEndpointUsage(), migration_readiness: this.assessMigrationReadiness() }; } generateMigrationPlan() { return { phases: [ { phase: 1, description: "Add new v1 endpoints alongside existing", impact: "Zero - existing functionality unchanged", duration: "1 day" }, { phase: 2, description: "Enhance existing endpoints with optional features", impact: "Minimal - opt-in only", duration: "2 days" }, { phase: 3, description: "Deprecate old formats (optional)", impact: "Planned migration required", duration: "Planned timeline" } ] }; } } ``` ## πŸ“Š μ‚¬μš©μ„± λ©”νŠΈλ¦­ ### 1. API μ‚¬μš© νŒ¨ν„΄ 뢄석 #### μ‚¬μš©μ„± μ§€ν‘œ μˆ˜μ§‘ ```javascript class UsabilityMetrics { trackApiDiscovery(session) { return { discovery_path: session.endpoints_visited, time_to_first_success: session.first_successful_call_time, help_usage: session.help_endpoints_accessed, error_recovery_rate: session.errors_resolved / session.total_errors }; } generateUsabilityReport() { return { top_entry_points: [ { endpoint: '/api', usage_count: 1245 }, { endpoint: '/api/help/getting-started', usage_count: 892 } ], common_user_journeys: [ ['GET /api', 'GET /api/help/prds', 'GET /api/prds', 'POST /api/prds'], ['GET /api/console', 'Try PRD creation', 'GET /api/help/prds/examples'] ], drop_off_points: [ { endpoint: '/api/prds', reason: 'validation_errors' } ] }; } } ``` ### 2. ν”Όλ“œλ°± μˆ˜μ§‘ μ‹œμŠ€ν…œ #### μ‚¬μš©μž κ²½ν—˜ ν”Όλ“œλ°± ```json // POST /api/feedback { "type": "usability", "rating": 4, "category": "api_discovery", "feedback": "Help system is very useful, but could use more examples", "context": { "user_journey": ["GET /api", "GET /api/help/prds", "POST /api/prds"], "session_duration": 1200, "successful_operations": 3, "errors_encountered": 1 }, "suggestions": [ "More real-world examples in help docs", "Interactive tutorials" ] } ``` ## 🎯 성곡 μ§€ν‘œ ### 개발자 κ²½ν—˜ KPI - **Time to First Success**: μ‹ κ·œ μ‚¬μš©μžκ°€ 첫 API 호좜 μ„±κ³΅κΉŒμ§€ μ‹œκ°„ (λͺ©ν‘œ: 5λΆ„ 이내) - **Help System Usage**: 도움말 μ‹œμŠ€ν…œ μ‚¬μš©λ₯  (λͺ©ν‘œ: μ‹ κ·œ μ‚¬μš©μž 80% 이상) - **Error Recovery Rate**: μ—λŸ¬ λ°œμƒ ν›„ 성곡적 ν•΄κ²°λ₯  (λͺ©ν‘œ: 90% 이상) - **API Discovery Success**: `/api` μ§„μž… ν›„ μ›ν•˜λŠ” κΈ°λŠ₯ μ°ΎκΈ° 성곡λ₯  (λͺ©ν‘œ: 95% 이상) ### ν˜Έν™˜μ„± μ§€ν‘œ - **Legacy Compatibility**: κΈ°μ‘΄ μ‹œμŠ€ν…œ ν˜Έν™˜μ„± (λͺ©ν‘œ: 100%) - **Zero Breaking Changes**: κΈ°μ‘΄ μ‚¬μš©μž 영ν–₯도 (λͺ©ν‘œ: 0%) - **Performance Impact**: κΈ°μ‘΄ μ‹œμŠ€ν…œ μ„±λŠ₯ 영ν–₯ (λͺ©ν‘œ: <5% 증가) --- **μž‘μ„±μΌ**: 2025-09-11 **μž‘μ„±μž**: UX μ„€κ³„μž (Claude Code) **κ²€ν† μž**: ν”„λ‘ νŠΈμ—”λ“œ 개발자, κΈ°μ‘΄ μ‹œμŠ€ν…œ κ΄€λ¦¬μž **버전**: 1.0 **μƒνƒœ**: 기술 μŠ€νƒ λ¬Έμ„œ λŒ€κΈ°

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/foswmine/workflow-mcp'

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