Skip to main content
Glama

recommend_api_combination

Recommends optimal Web API combinations based on functional requirements, browser compatibility, and performance needs for JavaScript/TypeScript projects.

Instructions

根據自然語言描述的需求,推薦最佳的 API 技術組合

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
requirementYes功能需求描述 (例如:背景擷取影片畫面並分析)
targetBrowsersNo目標瀏覽器支援 (預設: 現代瀏覽器)
performanceRequirementsNo效能需求 (low/medium/high)medium

Implementation Reference

  • src/server.ts:145-170 (registration)
    Registration of the 'recommend_api_combination' tool in the ListTools handler, including its name, description, and input schema.
    { name: 'recommend_api_combination', description: '根據自然語言描述的需求,推薦最佳的 API 技術組合', inputSchema: { type: 'object', properties: { requirement: { type: 'string', description: '功能需求描述 (例如:背景擷取影片畫面並分析)', }, targetBrowsers: { type: 'array', items: { type: 'string' }, description: '目標瀏覽器支援 (預設: 現代瀏覽器)', default: ['chrome>=90', 'firefox>=88', 'safari>=14', 'edge>=90'] }, performanceRequirements: { type: 'string', description: '效能需求 (low/medium/high)', enum: ['low', 'medium', 'high'], default: 'medium' } }, required: ['requirement'], }, },
  • Main handler function for the 'recommend_api_combination' tool. Validates input, matches categories using CanIUseService, recommends APIs using ApiRecommendationKnowledge, fetches compatibility and baseline info, generates comprehensive report.
    private async handleApiRecommendation(args: unknown) { try { const validatedArgs = this.validateApiRecommendationArgs(args); const { requirement, targetBrowsers, performanceRequirements } = validatedArgs; // 步驟 1: 先取得所有可用的 API 類別 let allCategories: Array<{ name: string; count: number; description?: string }> = []; let matchedCategories: string[] = []; try { allCategories = await this.canIUseService.getAllCategories(); // 根據需求描述匹配相關的類別 const lowerReq = requirement.toLowerCase(); matchedCategories = allCategories .filter(cat => { const catName = cat.name.toLowerCase(); const catDesc = (cat.description || '').toLowerCase(); return lowerReq.includes(catName) || catName.includes(lowerReq) || catDesc.includes(lowerReq) || this.matchCategoryKeywords(lowerReq, cat.name); }) .map(cat => cat.name); } catch (error) { console.warn('無法取得類別列表,將使用預定義知識庫:', error); } // 步驟 2: 從匹配的類別中找出相關的 API const apisFromCategories = new Set<string>(); for (const category of matchedCategories) { try { const featureIds = await this.canIUseService.getFeaturesByCategory(category); // 將 feature ID 轉換為 API 名稱(如果知識庫中有對應的) for (const featureId of featureIds.slice(0, 10)) { // 限制每個類別最多 10 個 const api = this.apiKnowledge.getApiByCaniuseId(featureId); if (api) { apisFromCategories.add(api.name); } } } catch (error) { console.warn(`無法取得類別 ${category} 的 API:`, error); } } // 步驟 3: 從知識庫中推薦 API(原有邏輯) const recommendedApis = this.apiKnowledge.recommendApis( requirement, performanceRequirements ); // 步驟 4: 合併結果,優先使用知識庫的推薦,補充類別匹配的結果 const apiMap = new Map<string, RecommendedApi>(); // 先加入知識庫推薦的 API for (const api of recommendedApis) { apiMap.set(api.name, api); } // 補充從類別匹配找到的 API(如果不在知識庫推薦中) for (const apiName of apisFromCategories) { const api = this.apiKnowledge.getApi(apiName); if (api && !apiMap.has(apiName)) { // 檢查是否符合需求描述 const lowerReq = requirement.toLowerCase(); if (api.description.toLowerCase().includes(lowerReq) || api.useCases.some(uc => lowerReq.includes(uc.toLowerCase()))) { apiMap.set(apiName, api); } } } const finalRecommendedApis = Array.from(apiMap.values()); if (finalRecommendedApis.length === 0) { let suggestionText = `# 🔍 API 推薦結果\n\n找不到與「${requirement}」相關的 API 推薦。\n\n`; if (matchedCategories.length > 0) { suggestionText += `**相關類別**: ${matchedCategories.join(', ')}\n\n`; } suggestionText += `**建議:**\n`; suggestionText += `- 嘗試使用更具體的描述\n`; suggestionText += `- 使用英文關鍵字(如 fetch, animation, storage)\n`; suggestionText += `- 描述具體的使用場景\n`; suggestionText += `- 使用 \`list_api_categories\` 工具查看所有可用的 API 類別\n`; return { content: [{ type: 'text', text: suggestionText }] }; } // 解析目標瀏覽器版本 const browserVersions = this.parseBrowserVersions(targetBrowsers); // 為每個推薦的 API 查詢相容性 const apiWithCompatibility = await this.fetchApiCompatibility( finalRecommendedApis, browserVersions ); // 生成報告(包含類別資訊) const report = this.generateApiRecommendationReport( requirement, apiWithCompatibility, browserVersions, performanceRequirements, matchedCategories, allCategories.length ); return { content: [{ type: 'text', text: report }] }; } catch (error) { const errorMessage = error instanceof ValidationError ? `參數驗證失敗: ${error.message}` : `推薦失敗: ${error instanceof Error ? error.message : String(error)}`; return { content: [{ type: 'text', text: errorMessage }], isError: true, }; } }
  • Input schema definition for the recommend_api_combination tool.
    inputSchema: { type: 'object', properties: { requirement: { type: 'string', description: '功能需求描述 (例如:背景擷取影片畫面並分析)', }, targetBrowsers: { type: 'array', items: { type: 'string' }, description: '目標瀏覽器支援 (預設: 現代瀏覽器)', default: ['chrome>=90', 'firefox>=88', 'safari>=14', 'edge>=90'] }, performanceRequirements: { type: 'string', description: '效能需求 (low/medium/high)', enum: ['low', 'medium', 'high'], default: 'medium' } }, required: ['requirement'],
  • Core recommendation logic using keyword mappings and API knowledge base. Called by the handler.
    recommendApis(requirement: string, performanceLevel?: 'low' | 'medium' | 'high'): RecommendedApi[] { const lowerReq = requirement.toLowerCase(); const matchedApiNames = new Set<string>(); // 根據關鍵字匹配 for (const mapping of this.keywordMappings) { for (const keyword of mapping.keywords) { if (lowerReq.includes(keyword.toLowerCase())) { for (const apiName of mapping.apis) { matchedApiNames.add(apiName); } } } } // 直接搜尋 API 名稱 for (const [name, api] of this.apis) { if (lowerReq.includes(name.toLowerCase()) || api.useCases.some(uc => lowerReq.includes(uc.toLowerCase())) || api.description.toLowerCase().includes(lowerReq)) { matchedApiNames.add(name); } } // 取得匹配的 API 資料 let results: RecommendedApi[] = []; for (const name of matchedApiNames) { const api = this.apis.get(name); if (api) { results.push(api); } } // 根據效能需求過濾 if (performanceLevel === 'high') { results = results.filter(api => api.performanceLevel === 'high'); } else if (performanceLevel === 'low') { // low 需求可以使用任何 API } return results; }
  • Helper function that formats the final recommendation report with detailed API info, browser compatibility, and categorized suggestions.
    private generateApiRecommendationReport( requirement: string, apiWithCompatibility: Array<{ api: RecommendedApi; compatibility: { globalSupport: number; supported: string[]; notSupported: string[]; partialSupport: string[]; recommendation: string; polyfillAvailable: boolean; polyfillUrl?: string; } | null; baseline: { status: string; label: string; description: string; icon: string; safeToUse: boolean; recommendation: string; } | null; }>, targetBrowsers: Record<string, string>, performanceLevel?: string, matchedCategories?: string[], totalCategoriesCount?: number ): string { let report = `# 🎯 API 組合推薦\n\n`; report += `**需求**: ${requirement}\n`; report += `**目標瀏覽器**: ${Object.entries(targetBrowsers).map(([b, v]) => `${b} >= ${v}`).join(', ')}\n`; if (performanceLevel) { report += `**效能需求**: ${performanceLevel}\n`; } // 顯示類別分析資訊 if (matchedCategories && matchedCategories.length > 0) { report += `**相關類別**: ${matchedCategories.join(', ')}\n`; } if (totalCategoriesCount) { report += `**可用類別總數**: ${totalCategoriesCount} 個(從 Can I Use 資料庫分析)\n`; } report += `\n---\n\n`; // 按類別分組 const byCategory = new Map<string, typeof apiWithCompatibility>(); for (const item of apiWithCompatibility) { const category = item.api.category; if (!byCategory.has(category)) { byCategory.set(category, []); } byCategory.get(category)!.push(item); } report += `## 📋 推薦 API 列表\n\n`; report += `共找到 **${apiWithCompatibility.length}** 個相關 API:\n\n`; for (const [category, items] of byCategory) { report += `### 📁 ${category}\n\n`; for (const { api, compatibility, baseline } of items) { // API 標題和支援狀態 const supportIcon = compatibility ? (compatibility.notSupported.length === 0 ? '✅' : compatibility.supported.length > 0 ? '⚠️' : '❌') : '❓'; // 如果有 Baseline 狀態,優先使用 Baseline 圖示 const displayIcon = baseline ? baseline.icon : supportIcon; report += `#### ${displayIcon} ${api.name}\n\n`; report += `${api.description}\n\n`; // Baseline 狀態 if (baseline) { report += `**📊 Baseline 狀態**: ${baseline.icon} **${baseline.label}**\n\n`; report += `${baseline.description}\n\n`; if (baseline.safeToUse) { report += `✅ **可安全使用** - 此 API 在所有核心瀏覽器中都支援\n\n`; } else { report += `⚠️ **需謹慎使用** - 建議檢查目標瀏覽器支援情況\n\n`; } } // 用途 report += `**適用場景**: ${api.useCases.join('、')}\n\n`; // 程式碼範例 report += `**程式碼範例**:\n\`\`\`javascript\n${api.codeExample}\n\`\`\`\n\n`; // 可取代的函式庫 if (api.replacesLibraries && api.replacesLibraries.length > 0) { report += `**可取代函式庫**: ${api.replacesLibraries.map(l => `\`${l}\``).join(', ')}\n\n`; } // 相容性資訊 if (compatibility) { report += `**🌐 瀏覽器相容性**:\n\n`; report += `- 全球支援率: **${compatibility.globalSupport.toFixed(1)}%**\n`; if (compatibility.supported.length > 0) { report += `- ✅ 支援: ${compatibility.supported.join(', ')}\n`; } if (compatibility.partialSupport.length > 0) { report += `- ⚠️ 部分支援: ${compatibility.partialSupport.join(', ')}\n`; } if (compatibility.notSupported.length > 0) { report += `- ❌ 不支援: ${compatibility.notSupported.join(', ')}\n`; } report += `\n${compatibility.recommendation}\n\n`; // Polyfill 資訊 if (compatibility.polyfillAvailable) { report += `**🔧 Polyfill 可用**`; if (compatibility.polyfillUrl) { report += `:\n\`\`\`html\n<script src="${compatibility.polyfillUrl}"></script>\n\`\`\``; } report += '\n\n'; } } else { report += `**🌐 瀏覽器相容性**: 無法取得相容性資料,請參考 [Can I Use](https://caniuse.com/?search=${encodeURIComponent(api.caniuseId)})\n\n`; } // 相關 API if (api.relatedApis && api.relatedApis.length > 0) { report += `**相關 API**: ${api.relatedApis.join(', ')}\n\n`; } report += `---\n\n`; } } // 總結建議 report += `## 💡 實作建議\n\n`; // 添加類別分析說明 if (matchedCategories && matchedCategories.length > 0) { report += `### 📊 類別分析\n\n`; report += `本推薦基於以下分析流程:\n\n`; report += `1. ✅ 從 Can I Use 資料庫取得所有 ${totalCategoriesCount || '可用'} 個 API 類別\n`; report += `2. ✅ 根據需求描述匹配相關類別:**${matchedCategories.join('**, **')}**\n`; report += `3. ✅ 從匹配類別中找出相關 API\n`; report += `4. ✅ 結合預定義知識庫的推薦結果\n`; report += `5. ✅ 查詢瀏覽器相容性並生成最終推薦\n\n`; report += `---\n\n`; } const fullySupported = apiWithCompatibility.filter( item => item.compatibility && item.compatibility.notSupported.length === 0 ); const needsPolyfill = apiWithCompatibility.filter( item => item.compatibility && item.compatibility.notSupported.length > 0 && item.compatibility.polyfillAvailable ); const notSupported = apiWithCompatibility.filter( item => item.compatibility && item.compatibility.notSupported.length > 0 && !item.compatibility.polyfillAvailable ); if (fullySupported.length > 0) { report += `### ✅ 可直接使用 (${fullySupported.length})\n`; report += `以下 API 在所有目標瀏覽器中都完全支援:\n`; for (const { api } of fullySupported) { report += `- ${api.name}\n`; } report += '\n'; } if (needsPolyfill.length > 0) { report += `### ⚠️ 需要 Polyfill (${needsPolyfill.length})\n`; report += `以下 API 在部分目標瀏覽器中需要 polyfill:\n`; for (const { api, compatibility } of needsPolyfill) { report += `- ${api.name}`; if (compatibility?.polyfillUrl) { report += ` - [Polyfill](${compatibility.polyfillUrl})`; } report += '\n'; } report += '\n'; } if (notSupported.length > 0) { report += `### ❌ 需要替代方案 (${notSupported.length})\n`; report += `以下 API 在部分目標瀏覽器中不支援且無 polyfill:\n`; for (const { api } of notSupported) { report += `- ${api.name} - 建議尋找替代方案或調整目標瀏覽器\n`; } report += '\n'; } return report; }

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/mukiwu/dev-advisor-mcp'

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