Skip to main content
Glama
mukiwu
by mukiwu

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