精選
MCP TypeScript 教學 實作 測試
建立您的第一個 MCP Server:Director Mode Assistant
透過建置實用的 MCP Server 學習 MCP 開發,展示 TDD、Auto-Cycle 和 SpecKit 概念。包含完整 TypeScript、測試和最佳實踐。
2026年1月15日 • 15 分鐘閱讀 • 作者:Claude World
🎯 您將建什麼
在本教學中,您將從頭開始建立一個完整的 MCP Server,展示三個核心 Director Mode 概念:
- TDD 循環管理 - 追蹤並引導您的 Red-Green-Refactor 工作流程
- Auto-Cycle 進度 - 監控自動化開發迭代
- SpecKit 驗證 - 驗證規格與實作的一致性
這個 server 將包含 9 個工具 和 3 個資源,具備完整 TypeScript 支援、全面測試和詳細文檔。
最終專案: github.com/claude-world/mcp-director-mode-server
📚 前置準備
開始之前,請確保您有:
# 檢查 Node.js 版本(需要 18+)
node --version # v18.0.0 或更高
# 檢查 TypeScript
npm install -g typescript
# 驗證 Claude Code MCP 支援
claude --mcp list
所需知識:
- 基礎 TypeScript/JavaScript
- 熟悉命令列工具
- 瞭解 TDD 概念(有幫助但非必需)
🚀 快速開始
步驟 1:初始化專案
建立新目錄並初始化:
mkdir mcp-director-mode-server
cd mcp-director-mode-server
# 初始化 npm 專案
npm init -y
# 安裝相依套件
npm install @modelcontextprotocol/sdk
npm install --save-dev typescript @types/node vitest
# 初始化 TypeScript
npx tsc --init
更新 package.json:
{
"name": "mcp-director-mode-server",
"version": "1.0.0",
"type": "module",
"scripts": {
"build": "tsc",
"test": "vitest",
"start": "node dist/index.js"
}
}
步驟 2:配置 TypeScript
建立 tsconfig.json:
{
"compilerOptions": {
"target": "ES2022",
"module": "Node16",
"moduleResolution": "Node16",
"strict": true,
"outDir": "./dist",
"rootDir": "./src",
"esModuleInterop": true,
"skipLibCheck": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "tests"]
}
🛠️ 建置 MCP Server
步驟 3:建立 Server 入口點
建立 src/index.ts:
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import {
CallToolRequestSchema,
ListToolsRequestSchema,
} from '@modelcontextprotocol/sdk/types.js';
// 建立 server 實例
const server = new Server(
{
name: 'director-mode-assistant',
version: '1.0.0',
},
{
capabilities: {
tools: {},
resources: {},
},
}
);
// 註冊工具(接下來會新增)
server.setRequestHandler(ListToolsRequestSchema, async () => ({
tools: [
{
name: 'check_tdd_status',
description: '檢查當前 TDD 循環狀態(RED/GREEN/REFACTOR)',
inputSchema: {
type: 'object',
properties: {
projectPath: {
type: 'string',
description: '專案目錄路徑',
},
},
required: ['projectPath'],
},
},
// ... 更多工具將在此新增
],
}));
// 處理工具呼叫
server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
switch (name) {
case 'check_tdd_status':
// 實作接下來會新增
return {
content: [{
type: 'text',
text: 'TDD 狀態:RED - 測試失敗中',
}],
};
default:
throw new Error(`未知工具:${name}`);
}
});
// 啟動 server
async function main() {
const transport = new StdioServerTransport();
await server.connect(transport);
console.error('Director Mode Assistant MCP Server 執行中...');
}
main().catch(console.error);
步驟 4:實作 TDD 工具
建立 src/tools/tdd.ts:
import { execSync } from 'child_process';
import { readFileSync, existsSync } from 'fs';
import { join } from 'path';
export interface TDDStatus {
phase: 'RED' | 'GREEN' | 'REFACTOR';
testCount: number;
passingTests: number;
failingTests: number;
lastRun: Date;
}
export function checkTDDStatus(projectPath: string): TDDStatus {
// 檢查測試檔案
const testDir = join(projectPath, 'tests');
if (!existsSync(testDir)) {
return {
phase: 'RED',
testCount: 0,
passingTests: 0,
failingTests: 0,
lastRun: new Date(),
};
}
// 執行測試並解析輸出
try {
const output = execSync('npm test', {
cwd: projectPath,
encoding: 'utf-8',
});
// 解析測試結果(Jest 範例)
const match = output.match(/(\d+) passed, (\d+) failed/);
if (match) {
const passing = parseInt(match[1]);
const failing = parseInt(match[2]);
return {
phase: failing > 0 ? 'RED' : 'GREEN',
testCount: passing + failing,
passingTests: passing,
failingTests: failing,
lastRun: new Date(),
};
}
} catch (error: any) {
// 測試失敗
const output = error.stdout || error.message;
const match = output.match(/(\d+) passed, (\d+) failed/);
if (match) {
return {
phase: 'RED',
testCount: parseInt(match[1]) + parseInt(match[2]),
passingTests: parseInt(match[1]),
failingTests: parseInt(match[2]),
lastRun: new Date(),
};
}
}
return {
phase: 'RED',
testCount: 0,
passingTests: 0,
failingTests: 0,
lastRun: new Date(),
};
}
export function suggestTDDNextStep(status: TDDStatus): string {
switch (status.phase) {
case 'RED':
return '撰寫最小程式碼讓測試通過';
case 'GREEN':
return '所有測試通過!是時候重構以提升整潔度';
case 'REFACTOR':
return '重構完成。執行測試以確保沒有破壞任何功能';
default:
return '從撰寫失敗的測試開始';
}
}
步驟 5:新增資源用於狀態管理
建立 src/resources/index.ts:
import { readFileSync, writeFileSync, existsSync } from 'fs';
import { join } from 'path';
export interface ProjectState {
currentPhase: string;
lastUpdate: Date;
metrics: {
totalTests: number;
testPassRate: number;
lastCommit: string;
};
}
const STATE_FILE = '.director-mode-state.json';
export function getProjectState(projectPath: string): ProjectState {
const statePath = join(projectPath, STATE_FILE);
if (!existsSync(statePath)) {
return {
currentPhase: '初始化中',
lastUpdate: new Date(),
metrics: {
totalTests: 0,
testPassRate: 0,
lastCommit: '無',
},
};
}
const data = readFileSync(statePath, 'utf-8');
return JSON.parse(data);
}
export function updateProjectState(
projectPath: string,
updates: Partial<ProjectState>
): void {
const current = getProjectState(projectPath);
const updated = {
...current,
...updates,
lastUpdate: new Date(),
};
const statePath = join(projectPath, STATE_FILE);
writeFileSync(statePath, JSON.stringify(updated, null, 2));
}
🧪 測試您的 MCP Server
步驟 6:建立測試
建立 tests/tdd.test.ts:
import { describe, it, expect } from 'vitest';
import { checkTDDStatus, suggestTDDNextStep } from '../src/tools/tdd.js';
describe('TDD 工具', () => {
it('應該在 RED 階段偵測到失敗的測試', () => {
const status = {
phase: 'RED',
testCount: 10,
passingTests: 7,
failingTests: 3,
lastRun: new Date(),
};
const suggestion = suggestTDDNextStep(status);
expect(suggestion).toContain('撰寫最小程式碼');
});
it('應該在 GREEN 階段建議重構', () => {
const status = {
phase: 'GREEN',
testCount: 10,
passingTests: 10,
failingTests: 0,
lastRun: new Date(),
};
const suggestion = suggestTDDNextStep(status);
expect(suggestion).toContain('重構');
});
});
執行測試:
npm test
🚀 執行 Server
步驟 7:建置並測試
# 建置 TypeScript
npm run build
# 啟動 server
npm start
步驟 8:從 Claude Code 連接
建立或更新 ~/.claude.json:
{
"mcpServers": {
"director-mode": {
"command": "node",
"args": ["/path/to/mcp-director-mode-server/dist/index.js"]
}
}
}
重啟 Claude Code 並驗證 server 已載入:
claude mcp list
📖 使用範例
範例 1:檢查 TDD 狀態
在 Claude Code 中:
使用 director-mode server 檢查我目前專案的 TDD 狀態
Claude 將呼叫 check_tdd_status 工具並報告:
當前 TDD 階段:GREEN
測試:15 個通過,0 個失敗
下一步:考慮重構以提升程式碼整潔度
範例 2:取得 TDD 指導
我在 RED 階段。下一步該做什麼?
Claude 將使用 server 建議:
撰寫最小程式碼讓測試通過。
現在不要擔心完美——專注於讓測試通過。
一旦所有測試都綠了,就可以重構。
🎓 展示的核心 MCP 概念
1. 工具設計
工具是 MCP server 暴露功能的主要方式:
{
name: 'check_tdd_status',
description: '檢查當前 TDD 循環狀態',
inputSchema: {
type: 'object',
properties: {
projectPath: { type: 'string' }
},
required: ['projectPath']
}
}
最佳實踐:
- 清晰、描述性的名稱
- 詳細的輸入驗證(JSON Schema)
- 有幫助的描述讓 Claude 理解
2. 資源管理
資源提供狀態和配置:
export function getProjectState(projectPath: string): ProjectState
export function updateProjectState(path, updates): void
最佳實踐:
- 跨 session 的持久化狀態
- 不可變更新(建立新狀態,不要變更原狀態)
- JSON 序列化以保持相容性
3. 錯誤處理
總是優雅地處理錯誤:
try {
const output = execSync('npm test', { cwd: projectPath });
return parseSuccess(output);
} catch (error) {
return parseFailure(error.stdout);
}
最佳實踐:
- 永遠不要讓錯誤導致 server 當機
- 提供有意義的錯誤訊息
- 記錄錯誤到 stderr 以便除錯
🏗️ 專案結構
mcp-director-mode-server/
├── src/
│ ├── index.ts # Server 入口點
│ ├── tools/
│ │ ├── tdd.ts # TDD 循環工具
│ │ ├── cycle.ts # Auto-cycle 工具
│ │ └── spec.ts # SpecKit 工具
│ └── resources/
│ └── index.ts # 狀態管理
├── tests/
│ ├── tdd.test.ts # 工具測試
│ └── integration.test.ts # 整合測試
├── examples/
│ ├── basic-usage.md # 使用範例
│ └── tdd-workflow.md # TDD 工作流程指南
├── docs/
│ └── ARCHITECTURE.md # 設計決策
├── package.json
├── tsconfig.json
└── vitest.config.ts
🚦 下一步
增強您的 Server
-
新增更多工具
validate_refactor- 檢查重構是否安全generate_tests- 產生測試腳手架run_cycle_step- 執行 Auto-Cycle 迭代
-
新增資源
project://state- 當前專案狀態project://metrics- 品質指標儀表板cycle://history- Auto-Cycle 歷史記錄
-
改善測試
- 新增與 mock MCP 用戶端的整合測試
- 測試錯誤情境
- 新增與真實 Claude Code 連線的 E2E 測試
發布您的 Server
# 發布到 npm
npm publish
# 或透過 GitHub 分享
git init
git add .
git commit -m "Initial MCP server"
git remote add origin https://github.com/YOUR_USERNAME/your-mcp-server.git
git push -u origin main
📚 更多學習
💡 實戰技巧
技巧 1:從簡單開始
不要一次建立所有 9 個工具。先從:
- ✅ 一個簡單工具(例如
check_tdd_status) - ✅ 基礎錯誤處理
- ✅ 一個測試
然後從那裡迭代。
技巧 2:使用 TypeScript Strict Mode
{
"compilerOptions": {
"strict": true # 早期捕獲錯誤
}
}
技巧 3:記錄所有內容
console.error('DEBUG: 檢查 TDD 狀態', projectPath);
記錄到 stderr 有助於除錯,而不會干擾 MCP 通訊。
技巧 4:先在本地測試
# 測試您的工具邏輯
node -e "import('./dist/tools/tdd.js').then(m => console.log(m.checkTDDStatus('.')))"
🎉 恭喜!
您已經從頭建立了一個完整的 MCP Server!您現在理解:
- ✅ 如何使用 TypeScript 建立 MCP Server
- ✅ 工具設計和實作
- ✅ 資源管理模式
- ✅ 測試策略
- ✅ 生產就緒 server 的最佳實踐
接下來做什麼?
- 與社群分享您的 server
- 探索更多進階 MCP 功能
- 為您的特定工作流程建構工具
祝您開發愉快!🚀