Skip to main content
Glama

Basic Math MCP Server

by bahfahh
explain.md9.17 kB
# MCP Server 開發完整指南 ## 什麼是 Model Context Protocol (MCP)? MCP 是一個開放協議,標準化了 AI 應用程式和大型語言模型如何連接到外部數據源和工具。它讓 AI 能夠: - 調用外部工具(如計算器、API 調用) - 讀取資源(文件、數據庫) - 使用提示模板 ## 核心概念 ### MCP 架構 ```mermaid graph TB AI[AI Client<br/>Claude Desktop] MCP[MCP Protocol<br/>JSON-RPC over stdio] Server[MCP Server<br/>Your Custom Tools] AI <--> MCP MCP <--> Server subgraph "MCP Server Components" Tools[Tools<br/>可調用函數] Resources[Resources<br/>可讀取數據] Prompts[Prompts<br/>模板] end Server --> Tools Server --> Resources Server --> Prompts ``` ### 通信流程 ```mermaid sequenceDiagram participant AI as AI Client participant MCP as MCP Protocol participant Server as MCP Server AI->>MCP: 初始化連接 MCP->>Server: initialize request Server->>MCP: capabilities response MCP->>AI: 可用工具列表 AI->>MCP: 調用工具 "sum" MCP->>Server: tool call with parameters Server->>Server: 執行計算 Server->>MCP: 結果返回 MCP->>AI: 格式化結果 ``` ## 實作步驟 ### 1. 項目初始化 ```json // package.json { "name": "basic-math-mcp-server", "type": "module", // ✅ 使用 ES modules "dependencies": { "@modelcontextprotocol/sdk": "^1.12.1", "zod": "^3.22.0" // ✅ 關鍵依賴 } } ``` ### 2. 基本服務器結構 ```typescript // ✅ 正確的 ES modules 導入方式 import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { z } from "zod"; // 服務器實例 const server = new McpServer({ name: "basic-math-server", version: "1.0.0" }, { capabilities: { tools: {} // 聲明支持工具 } }); ``` ### 3. 工具定義 ```typescript // ✅ 正確的工具定義 server.tool( "sum", // 工具名稱 "Add two numbers together", // 描述 { // 參數 schema (使用 zod) a: z.number().describe("First number"), b: z.number().describe("Second number") }, async ({ a, b }: { a: number; b: number }) => { // 類型註解 const result = a + b; return { content: [ { type: "text", text: `The sum of ${a} and ${b} is: ${result}` } ] }; } ); ``` ## 遇到的重要問題與解決 ### 問題 1: 參數傳遞失敗 (NaN 結果) **錯誤現象:** ``` The sum of undefined and undefined is: NaN ``` **原因分析:** ```mermaid graph LR A[AI 傳遞參數] --> B{參數 Schema 定義} B -->|❌ 普通對象| C[參數解析失敗] B -->|✅ Zod Schema| D[參數正確解析] C --> E[undefined values] D --> F[正確的數值] ``` **錯誤代碼:** ```typescript // ❌ 錯誤:使用普通對象定義參數 { a: { type: "number", description: "First number" } } ``` **正確代碼:** ```typescript // ✅ 正確:使用 zod schema { a: z.number().describe("First number"), b: z.number().describe("Second number") } ``` ### 問題 2: ES Modules vs CommonJS **更新: 官方推薦使用 ES Modules** **正確配置:** ```json // ✅ 使用 ES modules (官方推薦) { "type": "module", "compilerOptions": { "module": "ESNext" } } ``` **正確的導入語法:** ```typescript // ✅ ES modules 導入 import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { z } from "zod"; ``` ### 問題 3: TypeScript 嚴格模式類型錯誤 **錯誤:** ``` Binding element 'a' implicitly has an 'any' type ``` **解決:** ```typescript // ✅ 添加類型註解 async ({ a, b }: { a: number; b: number }) => { ``` ## Zod 參數 Schema 詳解 ### 為什麼需要 Zod? ```mermaid graph TD A[AI 發送 JSON 參數] --> B[MCP Protocol] B --> C{Schema 驗證} C -->|Zod Schema| D[類型安全轉換] C -->|無 Schema| E[參數丟失/類型錯誤] D --> F[正確的 TypeScript 參數] E --> G[undefined/NaN 錯誤] ``` ### Zod Schema 語法 ```typescript // 基本類型 z.number() // 數字 z.string() // 字符串 z.boolean() // 布爾值 // 添加描述 z.number().describe("這是一個數字參數") // 可選參數 z.number().optional() // 默認值 z.number().default(0) // 數組 z.array(z.number()) // 對象 z.object({ name: z.string(), age: z.number() }) ``` ## 配置 AI 客戶端連接 ### Claude Desktop 配置 ```json { "mcpServers": { "basic-math-server": { "command": "node", "args": ["C:\\path\\to\\your\\project\\build\\index.js"], "description": "A basic math server providing sum and subtraction operations" } } } ``` ### 配置流程 ```mermaid graph LR A[編寫 MCP Server] --> B[編譯 TypeScript] B --> C[創建配置文件] C --> D[添加到 Claude Desktop] D --> E[重啟 Claude] E --> F[AI 可調用工具] ``` ## 調試和測試 ### 本地測試腳本 ```javascript import { Client } from '@modelcontextprotocol/sdk/client/index.js'; import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js'; // 創建客戶端測試 const transport = new StdioClientTransport({ command: 'node', args: ['build/index.js'] }); const client = new Client({ name: 'test-client', version: '1.0.0' }); await client.connect(transport); // 測試工具調用 const result = await client.callTool({ name: 'sum', arguments: { a: 20.12, b: 123456 } }); ``` ## 最佳實踐 ### 1. 錯誤處理 ```typescript server.tool("divide", { a: z.number(), b: z.number() }, async ({ a, b }) => { if (b === 0) { return { content: [{ type: "text", text: "Error: Division by zero" }], isError: true }; } return { content: [{ type: "text", text: String(a / b) }] }; } ); ``` ### 2. 參數驗證 ```typescript server.tool("factorial", { n: z.number().int().min(0).max(20) }, // 限制範圍 async ({ n }) => { // 實現階乘 } ); ``` ### 3. 異步操作 ```typescript server.tool("fetch-data", { url: z.string().url() }, async ({ url }) => { try { const response = await fetch(url); const data = await response.text(); return { content: [{ type: "text", text: data }] }; } catch (error) { return { content: [{ type: "text", text: `Error: ${error.message}` }], isError: true }; } } ); ``` ## 常見陷阱 1. **忘記使用 zod schema** → 參數無法正確傳遞 2. **模塊系統配置錯誤** → 運行時錯誤 3. **缺少類型註解** → TypeScript 編譯錯誤 4. **路徑配置錯誤** → AI 客戶端無法找到服務器 5. **忘記重新編譯** → 修改未生效 ## 擴展方向 ### 添加更多工具類型 ```mermaid graph TB MCP[MCP Server] --> Math[數學工具] MCP --> File[文件操作] MCP --> API[API 調用] MCP --> DB[數據庫查詢] Math --> Sum[加法] Math --> Sub[減法] Math --> Complex[復雜運算] File --> Read[讀取文件] File --> Write[寫入文件] API --> HTTP[HTTP 請求] API --> Auth[認證] DB --> Query[查詢] DB --> Update[更新] ``` ### 資源定義 ```typescript // 添加可讀取的資源 server.resource( "config", "config://settings", async (uri) => ({ contents: [{ uri: uri.href, text: JSON.stringify(settings, null, 2) }] }) ); ``` ## ES Modules 更新說明 (2025年1月) ### 更新摘要 我們已成功將項目從 CommonJS 轉換為 ES Modules,符合官方最佳實踐: ### 主要更改 1. **package.json** ```json { "type": "module" // 新增此行 } ``` 2. **tsconfig.json** ```json { "compilerOptions": { "module": "ESNext", // 從 CommonJS 改為 ESNext "allowSyntheticDefaultImports": true // 新增此選項 } } ``` 3. **src/index.ts** ```typescript // 從 require 改為 import import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { z } from "zod"; ``` 4. **test.js** ```javascript // 測試文件也更新為 ES modules import { Client } from '@modelcontextprotocol/sdk/client/index.js'; import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js'; ``` ### 驗證結果 - ✅ TypeScript 編譯成功 - ✅ 服務器正常啟動 - ✅ 工具調用功能正常 - ✅ 測試腳本運行成功 ### 優勢 - 符合現代 JavaScript 標準 - 更好的樹搖 (tree-shaking) 支持 - 與官方 MCP SDK 完全兼容 - 為 Next.js 等現代框架做好準備 通過這個完整的指南,開發者可以理解 MCP Server 的核心概念、實作步驟、常見問題及解決方案,並使用現代的 ES Modules 標準,從而成功創建自己的 MCP 工具。

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/bahfahh/mcptest'

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