Skip to main content
Glama
mukiwu
by mukiwu

check_browser_support

Check browser compatibility for Web APIs using Can I Use database to identify supported versions and polyfill recommendations.

Instructions

使用 Can I Use 資料庫檢查 Web API 的瀏覽器相容性,取得支援版本和 polyfill 建議

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
featureYesWeb API 功能名稱,如 "fetch", "flexbox", "css-grid", "webgl"
targetBrowsersNo目標瀏覽器版本 (預設: { chrome: "90", firefox: "88", safari: "14", edge: "90" })

Implementation Reference

  • src/server.ts:219-237 (registration)
    Registration of the 'check_browser_support' tool including its input schema and description in the ListToolsRequestSchema handler
    {
      name: 'check_browser_support',
      description: '使用 Can I Use 資料庫檢查 Web API 的瀏覽器相容性,取得支援版本和 polyfill 建議',
      inputSchema: {
        type: 'object',
        properties: {
          feature: {
            type: 'string',
            description: 'Web API 功能名稱,如 "fetch", "flexbox", "css-grid", "webgl"',
          },
          targetBrowsers: {
            type: 'object',
            description: '目標瀏覽器版本 (預設: { chrome: "90", firefox: "88", safari: "14", edge: "90" })',
            default: { chrome: '90', firefox: '88', safari: '14', edge: '90' }
          }
        },
        required: ['feature'],
      },
    },
  • Core implementation of browser support checking using Can I Use database. Matches the tool's input parameters (feature, targetBrowsers) and returns compatibility report with support status, polyfills etc.
    async checkCompatibility(
      featureId: string,
      targetBrowsers: Record<string, string> = {
        chrome: '90',
        firefox: '88',
        safari: '14',
        edge: '90'
      }
    ): Promise<CompatibilityReport> {
      const support = await this.getFeatureSupport(featureId);
    
      if (!support) {
        return {
          feature: featureId,
          globalSupport: 0,
          supported: [],
          notSupported: Object.keys(targetBrowsers),
          partialSupport: [],
          recommendation: `找不到 ${featureId} 的相容性資料,建議查詢 MDN 文件`,
          polyfillAvailable: false
        };
      }
    
      const supported: string[] = [];
      const notSupported: string[] = [];
      const partialSupport: string[] = [];
    
      for (const [browser, targetVersion] of Object.entries(targetBrowsers)) {
        const browserSupport = (support.browsers as any)[browser];
    
        if (!browserSupport) {
          notSupported.push(browser);
          continue;
        }
    
        if (browserSupport.supported) {
          if (browserSupport.sinceVersion) {
            const sinceNum = parseFloat(browserSupport.sinceVersion);
            const targetNum = parseFloat(targetVersion);
    
            if (sinceNum <= targetNum) {
              if (browserSupport.partialSupport) {
                partialSupport.push(`${browser} >= ${browserSupport.sinceVersion}`);
              } else {
                supported.push(`${browser} >= ${browserSupport.sinceVersion}`);
              }
            } else {
              notSupported.push(`${browser} < ${browserSupport.sinceVersion}`);
            }
          } else {
            supported.push(browser);
          }
        } else {
          notSupported.push(browser);
        }
      }
    
      // 生成建議
      let recommendation = '';
      if (notSupported.length === 0) {
        recommendation = '✅ 所有目標瀏覽器都支援此功能';
      } else if (supported.length === 0) {
        recommendation = '❌ 此功能在目標瀏覽器中不受支援,需要 polyfill 或替代方案';
      } else {
        recommendation = `⚠️ 部分瀏覽器不支援:${notSupported.join(', ')}。建議提供 fallback 或使用 polyfill`;
      }
    
      return {
        feature: support.title,
        globalSupport: support.usage,
        supported,
        notSupported,
        partialSupport,
        recommendation,
        polyfillAvailable: this.checkPolyfillAvailable(featureId),
        polyfillUrl: this.getPolyfillUrl(featureId)
      };
    }
  • Helper method to search for Can I Use feature IDs by name, used prior to checking support
    async searchFeature(query: string): Promise<string[]> {
      const data = await this.loadData();
      const features = data.data || {};
      const lowerQuery = query.toLowerCase();
    
      const matches: { id: string; score: number }[] = [];
    
      for (const [id, feature] of Object.entries(features) as [string, any][]) {
        let score = 0;
    
        // 完全匹配 ID
        if (id.toLowerCase() === lowerQuery) {
          score = 100;
        }
        // ID 包含查詢
        else if (id.toLowerCase().includes(lowerQuery)) {
          score = 80;
        }
        // 標題匹配
        else if (feature.title?.toLowerCase().includes(lowerQuery)) {
          score = 60;
        }
        // 描述匹配
        else if (feature.description?.toLowerCase().includes(lowerQuery)) {
          score = 40;
        }
        // 關鍵字匹配
        else if (feature.keywords?.toLowerCase().includes(lowerQuery)) {
          score = 30;
        }
    
        if (score > 0) {
          matches.push({ id, score });
        }
      }
    
      // 按分數排序並返回 ID
      return matches
        .sort((a, b) => b.score - a.score)
        .slice(0, 10)
        .map(m => m.id);
    }
  • Instantiation of CanIUseService used for browser support checks
    this.canIUseService = new CanIUseService();
    this.baselineService = new BaselineService();
  • Comprehensive handler for compatibility checks (case 'check_compatibility') that performs feature search and browser support analysis using CanIUseService, closely matching the tool's purpose despite name difference
    private async handleCompatibilityCheck(args: unknown) {
      try {
        if (!args || typeof args !== 'object') {
          throw new ValidationError('參數格式錯誤');
        }
    
        const {
          feature,
          targetBrowsers = { chrome: '90', firefox: '88', safari: '14', edge: '90' }
        } = args as Record<string, unknown>;
    
        if (typeof feature !== 'string' || !feature.trim()) {
          throw new ValidationError('feature 為必填欄位,請提供要檢查的 Web API 功能名稱');
        }
    
        // 同時查詢 Can I Use 和 Baseline
        const [caniuseMatches, baselineMatches] = await Promise.all([
          this.canIUseService.searchFeature(feature),
          this.baselineService.searchFeature(feature)
        ]);
    
        // 如果兩個來源都找不到
        if (caniuseMatches.length === 0 && baselineMatches.length === 0) {
          return {
            content: [{
              type: 'text',
              text: `🔍 相容性查詢結果\n\n找不到與 "${feature}" 相關的功能。\n\n建議:\n- 嘗試使用不同的關鍵字\n- 常見功能名稱:fetch, flexbox, css-grid, webgl, es6-module, async-functions`
            }]
          };
        }
    
        let report = `# 🌐 Web API 相容性報告: ${feature}\n\n`;
    
        // ========== Can I Use 資料 ==========
        if (caniuseMatches.length > 0) {
          const featureSupport = await this.canIUseService.getFeatureSupport(caniuseMatches[0]);
    
          if (featureSupport) {
            const compatReport = await this.canIUseService.checkCompatibility(
              caniuseMatches[0],
              targetBrowsers as Record<string, string>
            );
    
            report += `## 📊 概覽\n\n`;
            report += `- **功能**: ${featureSupport.title}\n`;
            report += `- **全球支援率**: ${compatReport.globalSupport.toFixed(1)}%\n`;
            report += `- **標準狀態**: ${this.getStatusText(featureSupport.status)}\n`;
    
            if (featureSupport.description) {
              report += `\n### 說明\n${featureSupport.description}\n`;
            }
    
            report += `\n## 🎯 目標瀏覽器相容性\n\n`;
            report += `${compatReport.recommendation}\n\n`;
    
            if (compatReport.supported.length > 0) {
              report += `### ✅ 支援的瀏覽器\n`;
              for (const browser of compatReport.supported) {
                report += `- ${browser}\n`;
              }
              report += '\n';
            }
    
            if (compatReport.partialSupport.length > 0) {
              report += `### ⚠️ 部分支援\n`;
              for (const browser of compatReport.partialSupport) {
                report += `- ${browser}\n`;
              }
              report += '\n';
            }
    
            if (compatReport.notSupported.length > 0) {
              report += `### ❌ 不支援\n`;
              for (const browser of compatReport.notSupported) {
                report += `- ${browser}\n`;
              }
              report += '\n';
            }
    
            // Polyfill 資訊
            if (compatReport.polyfillAvailable) {
              report += `## 🔧 Polyfill\n\n`;
              report += `此功能有 polyfill 可用。\n`;
              if (compatReport.polyfillUrl) {
                report += `\n\`\`\`html\n<script src="${compatReport.polyfillUrl}"></script>\n\`\`\`\n`;
              }
              report += '\n';
            }
    
            // 各瀏覽器詳細支援版本
            report += `## 📱 各瀏覽器支援版本\n\n`;
            const browsers = featureSupport.browsers;
    
            const browserNames: Record<string, string> = {
              chrome: 'Chrome',
              firefox: 'Firefox',
              safari: 'Safari',
              edge: 'Edge',
              ie: 'Internet Explorer',
              opera: 'Opera',
              ios_saf: 'iOS Safari',
              android: 'Android Browser',
              samsung: 'Samsung Internet'
            };
    
            for (const [key, name] of Object.entries(browserNames)) {
              const support = (browsers as any)[key];
              if (support) {
                const icon = support.supported ? '✅' : (support.partialSupport ? '⚠️' : '❌');
                const version = support.sinceVersion ? `v${support.sinceVersion}+` : (support.supported ? '支援' : '不支援');
                report += `| ${icon} ${name} | ${version} |\n`;
              }
            }
            report += '\n';
          }
        }
    
        // ========== Baseline 狀態 ==========
        report += `## 📊 Baseline 狀態\n\n`;
    
        if (baselineMatches.length > 0) {
          const baselineInfo = await this.baselineService.getFeature(baselineMatches[0].id) || baselineMatches[0];
    
          if (baselineInfo.baseline) {
            report += this.baselineService.formatBaselineInfo(baselineInfo);
            report += `\n${this.baselineService.getRecommendation(baselineInfo)}\n\n`;
    
            // Baseline 的瀏覽器支援資訊
            if (baselineInfo.compat) {
              report += `### Baseline 瀏覽器支援\n\n`;
              const compat = baselineInfo.compat;
    
              if (compat.chrome) {
                const since = compat.chrome.since || '未知';
                const flags = compat.chrome.flags ? ' (需要啟用實驗性功能)' : '';
                report += `- **Chrome**: ${since}${flags}\n`;
              }
              if (compat.firefox) {
                const since = compat.firefox.since || '未知';
                const flags = compat.firefox.flags ? ' (需要啟用實驗性功能)' : '';
                report += `- **Firefox**: ${since}${flags}\n`;
              }
              if (compat.safari) {
                const since = compat.safari.since || '未知';
                const flags = compat.safari.flags ? ' (需要啟用實驗性功能)' : '';
                report += `- **Safari**: ${since}${flags}\n`;
              }
              if (compat.edge) {
                const since = compat.edge.since || '未知';
                const flags = compat.edge.flags ? ' (需要啟用實驗性功能)' : '';
                report += `- **Edge**: ${since}${flags}\n`;
              }
              report += '\n';
            }
          } else {
            report += `❓ 此功能尚未有 Baseline 狀態資訊\n\n`;
          }
        } else {
          report += `❓ 在 Baseline 資料庫中找不到此功能\n\n`;
          report += `建議查閱 [web.dev/baseline](https://web.dev/baseline) 確認。\n\n`;
        }
    
        // ========== 相關連結 ==========
        report += `## 🔗 相關連結\n\n`;
        if (caniuseMatches.length > 0) {
          report += `- [Can I Use](https://caniuse.com/${caniuseMatches[0]})\n`;
        }
        if (baselineMatches.length > 0 && baselineMatches[0].mdn?.url) {
          report += `- [MDN 文件](${baselineMatches[0].mdn.url})\n`;
        }
        report += `- [Baseline 狀態](https://web.dev/baseline)\n`;
    
        // 其他相關功能
        const allMatches = [...new Set([...caniuseMatches.slice(1, 4), ...baselineMatches.slice(1, 4).map(m => m.name)])];
        if (allMatches.length > 0) {
          report += `\n## 🔍 其他相關功能\n\n`;
          report += `您可能也在尋找:\n`;
          for (const match of allMatches.slice(0, 5)) {
            report += `- \`${typeof match === 'string' ? match : match}\`\n`;
          }
        }
    
        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,
        };
      }
    }

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