🚀 使用Model Context Protocol構建一個簡單的服務器
本項目展示瞭如何藉助 TypeScript SDK 搭建一個基礎的 MCP 服務器。此服務器具備資源管理、工具交互和提示指導等功能,能有效輔助 AI 客戶端與工具、資源進行交互。
🚀 快速開始
運行服務器
-
克隆項目倉庫到本地:
git clone https://github.com/yourusername/css-tutor-server.git
cd css-tutor-server
-
安裝依賴項:
npm install
-
啟動服務器:
npm start
調試工具
為了幫助開發者調試,項目提供了以下調試工具:
npx @modelcontextprotocol/inspector
運行上述命令後,將在瀏覽器中打開一個界面,允許您查看和測試服務器的狀態、資源、工具以及提示。
✨ 主要特性
- 資源管理:定義了一個簡單的資源 (
css_knowledge_memory
) 來存儲已知的 CSS 概念。
- 工具交互:實現了三個工具,分別為
read_from_memory
(從內存中讀取數據)、write_to_memory
(向內存中寫入數據)和 get_latest_updates
(調用 OpenRouter API 獲取最新的更新)。
- 提示指導:定義了一個靜態提示 (
css-tutor-guidance
) 來指導 AI 客戶端如何有效地與工具和資源交互。
📦 安裝指南
環境變量
為了使服務器正常運行,您需要在環境中設置以下變量:
OPENROUTER_API_KEY=your_api_key_here
可以將此環境變量添加到 .env
文件中,或者直接設置在操作系統環境中。
項目配置
package.json
配置
{
"name": "css_tutor_server",
"version": "1.0.0",
"description": "CSS 教學輔助服務器,基於Model Context Protocol構建。",
"scripts": {
"start": "ts-node src/index.ts"
},
"dependencies": {
"@modelcontextprotocol/sdk": "^0.5.0",
"ts-node": "^10.9.2",
"typescript": "^5.3.3",
"zod": "^1.24.0"
}
}
tsconfig.json
配置
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true
},
"include": ["**/*.ts"],
"exclude": ["node_modules"]
}
💻 使用示例
基礎用法
const server = await createServer({
prompts: [css_tutor_guidance],
tools: [
read_from_memory,
write_to_memory,
get_latest_updates
],
});
await server.start();
📚 詳細文檔
項目結構
項目的文件結構如下:
project-root/
├── data/ # 數據目錄,包含memory.json數據庫文件
├── src/
│ ├── resources/ # 資源定義目錄
│ ├── tools/ # 工具定義目錄
│ ├── prompts/ # 提示定義目錄
│ └── index.ts # 主程序入口文件
├── package.json # 項目依賴和腳本配置
├── tsconfig.json # TypeScript編譯器配置
└── .gitignore # 代碼庫忽略規則
項目文件結構說明
data/memory.json
:存儲已知的 CSS 概念。
src/resources/
:包含內存資源的讀寫邏輯。
src/tools/
:包含可執行的具體功能工具。
src/prompts/
:定義了教學提示內容。
src/index.ts
:服務器入口文件,負責初始化和啟動服務。
代碼實現
資源定義 (src/resources/index.ts
)
import { readFileSync, writeFileSync } from 'fs';
import { resource, ResourceHandler } from '@modelcontextprotocol/sdk';
const memorySchema = z.object({
concepts: z.record(z.string()),
});
export async function readMemory(): Promise<unknown> {
try {
const data = readFileSync('./data/memory.json', 'utf8');
return JSON.parse(data);
} catch (error) {
console.error('讀取內存錯誤:', error);
throw error;
}
}
export async function writeMemory(data: unknown): Promise<void> {
try {
const isValid = memorySchema.safeParse(data).success;
if (!isValid) {
throw new Error('數據格式無效');
}
writeFileSync('./data/memory.json', JSON.stringify(data, null, 2));
} catch (error) {
console.error('寫入內存錯誤:', error);
throw error;
}
}
resource({
name: 'css_knowledge_memory',
uriPrefix: 'memory://',
readHandler: async () => await readMemory(),
writePermission: true,
writeHandler: async (data) => await writeMemory(data),
});
工具定義 (src/tools/index.ts
)
import { resource } from '@modelcontextprotocol/sdk';
import { readMemory, writeMemory } from './resources';
import { z } from 'zod';
export const read_from_memory = tool({
name: 'read_from_memory',
description: '讀取內存中的知識庫數據',
handler: async () => await readMemory(),
});
export const write_to_memory = tool({
name: 'write_to_memory',
description: '向內存中寫入新的知識',
parameters: {
concept: z.string().describe('要標記為已知的CSS概念'),
known: z.boolean().describe('指示該概念是否已知')
},
handler: async ({ concept, known }) => {
const currentData = await readMemory();
if (known) {
currentData.concepts[concept] = true;
} else {
delete currentData.concepts[concept];
}
return await writeMemory(currentData);
},
});
export const get_latest_updates = tool({
name: 'get_latest_updates',
description: '獲取最新的CSS更新信息',
handler: async () => {
try {
return {
updates: ['新增了 CSS Grid 的新佈局模式', '修復了 Flexbox 中的一個已知問題']
};
} catch (error) {
console.error('獲取更新失敗:', error);
throw error;
}
},
});
提示定義 (src/prompts/index.ts
)
import { prompt } from '@modelcontextprotocol/sdk';
export const css_tutor_guidance = prompt({
name: 'css_tutor_guidance',
description: '指導學習者如何掌握CSS核心概念',
content: `作為經驗豐富的CSS開發者,幫助學習者理解和掌握關鍵的CSS概念。請以清晰、有條理的方式進行教學。`
});
主程序 (src/index.ts
)
import { createServer } from '@modelcontextprotocol/sdk';
import { css_tutor_guidance } from './prompts';
import { read_from_memory, write_to_memory, get_latest_updates } from './tools';
async function main() {
try {
const server = await createServer({
prompts: [css_tutor_guidance],
tools: [
read_from_memory,
write_to_memory,
get_latest_updates
],
});
console.log('服務器已啟動,監聽地址:', server.url);
await server.start();
} catch (error) {
console.error('服務器啟動失敗:', error);
}
}
main().catch(console.error);
🔧 技術細節
錯誤處理
在 src/tools/index.ts
中,我們已經為每個工具添加了錯誤捕獲和處理機制。生產環境中建議增加額外的錯誤監控和報告功能。
擴展功能
未來可以考慮以下擴展:
- 數據持久化:使用數據庫替代本地文件存儲。
- 日誌系統:集成專業的日誌管理工具。
- 認證授權:為不同的用戶角色分配權限。
- 國際化支持:支持多語言教學內容。
- 進度跟蹤:記錄學習者的學習進展和成果。
📄 許可證
文檔未提及相關信息,故跳過該章節。
🔗 參考資料