MCP基礎學習二:MCP服務搭建與配置

文章目錄

  • MCP服務搭建與配置
    • 一,學習目標:
    • 二,學習內容:
      • 1. 如何搭建MCP服務端
        • 服務端初始化與配置
        • MCP服務架構與數據流交互圖
        • 核心實現
        • 注冊服務功能
        • 服務器啟動與API暴露
      • 2. 本地應用與MCP服務的集成
        • 客戶端SDK實現
        • 客戶端應用實現
        • 功能演示與測試
      • 3. 配置和啟動MCP服務
        • 服務器配置文件
        • 完整服務器啟動代碼
        • 部署腳本
        • 完整啟動流程
    • 三,整體實現代碼邏輯講解
      • 1. 服務端初始化與配置
      • 2. 注冊服務功能
      • 3. 客戶端SDK實現
      • 4. 安全性和性能考慮
    • 四,可擴展的內容
      • 1. 核心服務擴展
      • 2. 配置系統擴展
      • 3. 中間件擴展
      • 4. 客戶端功能擴展
      • 5. 部署與運維擴展
    • 五, 學習資源
      • 1. 搭建MCP服務的快速入門
      • 2. MCP基礎學習相關文章鏈接
      • 3. 相關代碼鏈接

MCP服務搭建與配置

一,學習目標:

  • 學會如何搭建MCP服務環境,理解MCP服務的配置方式。
  • 掌握如何在本地應用中集成MCP功能。

二,學習內容:

1. 如何搭建MCP服務端

MCP(Model Context Protocol)服務是一個用于連接客戶端應用與各種處理功能的中間層。搭建MCP服務端是構建整個系統的第一步,它將成為所有客戶端請求的處理中心。

服務端初始化與配置

MCP服務的第一步是初始化服務器環境和配置。這個過程包括:

  • 安裝必要依賴(Node.js、winston、express、dotenv)
  • 創建配置文件,管理服務器參數(端口、主機名、安全設置等)
  • 初始化MCPServer實例,準備注冊工具和資源處理器

基礎環境準備

在開始構建MCP服務前,我們需要準備基本的開發環境。MCP服務基于Node.js構建,因此需要確保系統已安裝相關環境:

  • 需要: Node.js 16.0+, npm或yarn
  • 初始化:
    # 創建項目目錄并進入
    mkdir mcp-demo && cd mcp-demo# 初始化package.json
    npm init -y# 安裝必要依賴
    npm install winston express dotenv
    

上述命令會創建一個基本的項目結構,安裝必要的依賴包:winston用于日志記錄,express用于創建HTTP服務器,dotenv用于管理環境變量。

MCP服務架構與數據流交互圖

在這里插入圖片描述

核心實現

接下來,我們需要實現MCP服務的核心功能。MCP服務的核心是一個能夠注冊和管理各種工具與資源處理器的服務器類。

核心服務類

// src/lib/mcp-sdk.js - 核心SDK
export class MCPServer {constructor(config) {// 初始化服務器實例this.resources = new Map();  // 用于存儲資源處理器的映射表this.tools = new Map();      // 用于存儲工具函數的映射表this.config = config;        // 存儲服務器配置信息}// 注冊工具函數 - 用于添加新的API功能registerTool(name, handler) {// name: 工具名稱,如'processText'、'calculate'// handler: 處理函數,接收請求參數并返回結果this.tools.set(name, handler);// 例如: server.registerTool('sum', (numbers) => numbers.reduce((a,b) => a+b));}// 注冊資源處理器 - 用于處理文件和其他資源registerResourceHandler(type, handler) {// type: 資源類型,如'file'、'database'// handler: 資源處理函數,處理資源獲取和存儲this.resources.set(type, handler);// 例如: server.registerResourceHandler('file', (path) => fs.readFile(path));}
}

這個類是整個MCP服務的核心,通過Map結構存儲注冊的工具和資源處理器,實現了可擴展的插件式架構。MCPServer類提供了兩個主要方法:

  • registerTool: 用于注冊各種工具函數,如文本處理、數學計算等
  • registerResourceHandler: 用于注冊資源處理器,如文件讀取、數據庫訪問等
注冊服務功能

MCP服務的核心是其功能注冊機制,允許以插件式架構添加各種功能:

  • 工具注冊:使用registerTool方法注冊各種處理工具
  • 資源處理器:使用registerResourceHandler注冊資源訪問方法
  • 每個工具和資源處理器都是獨立的功能單元,支持異步操作

接下來,我們使用這個核心類來創建一個實際的服務器實例,并注冊一些基本功能:

// src/server/index.js - 服務器實現
// 創建服務器實例,配置基本參數
const server = new MCPServer({port: 3000,        // 服務器監聽端口host: 'localhost'  // 服務器主機名
});// 注冊文本處理工具 - 提供文本分析功能
server.registerTool('processText', async ({text, operation}) => {// 根據操作類型處理文本switch(operation) {case 'wordCount': // 計算文本中的單詞數量return { count: text.split(/\s+/).length };case 'charCount': // 計算文本中的字符數量return { count: text.length };case 'toUpperCase': // 將文本轉換為大寫形式return { text: text.toUpperCase() };// 可以在這里添加更多文本處理功能}
});// 注冊計算工具 - 提供數學計算功能
server.registerTool('calculate', async ({operation, numbers}) => {// 根據操作類型進行數學計算switch(operation) {case 'sum':// 計算數組元素之和return { value: numbers.reduce((a,b) => a+b, 0) };case 'average':// 計算數組元素的平均值return { value: numbers.reduce((a,b) => a+b, 0) / numbers.length };case 'max':// 找出數組中的最大值return { value: Math.max(...numbers) };case 'min':// 找出數組中的最小值return { value: Math.min(...numbers) };// 可以在這里添加更多計算功能}
});

在這段代碼中,我們創建了一個監聽在3000端口的MCP服務器,并注冊了兩個工具:

  1. processText: 提供文本處理功能,包括單詞計數、字符計數和轉換大寫
  2. calculate: 提供數學計算功能,包括求和、平均值、最大值和最小值

這些函數將作為服務的API端點,供客戶端調用。

服務器啟動與API暴露

完成配置和功能注冊后,服務器需要啟動并暴露API接口:

  • 配置Express中間件(JSON解析、跨域支持、請求限制)
  • 定義API路由(/tools/:name/resources/:type
  • 啟動HTTP服務器監聽指定端口
  • 創建日志目錄和啟動日志系統

最后,我們需要啟動服務器,使其能夠接收和處理請求:

# 啟動MCP服務器
node src/server/index.js# 服務器將在localhost:3000上運行
# 可以通過瀏覽器或API客戶端訪問

執行上述命令后,MCP服務將在后臺運行,等待客戶端連接和請求。

2. 本地應用與MCP服務的集成

一旦MCP服務端搭建完成,我們就需要開發客戶端應用來與之交互。本節將介紹如何創建一個客戶端SDK和應用程序,以便與MCP服務進行通信。

客戶端SDK實現

為了便于應用程序與MCP服務交互,實現了客戶端SDK:

  • 基礎客戶端類:MCPClient封裝了與服務器通信的基本方法
  • 擴展客戶端類:MCPDemoClient添加了日志、錯誤處理和功能封裝
  • 客戶端類提供語義化API,簡化服務調用流程

首先,我們需要一個客戶端SDK來簡化與MCP服務的通信。這個SDK封裝了網絡請求和錯誤處理細節,提供了一個簡潔的接口:

// src/lib/mcp-sdk.js - 客戶端SDK部分
export class MCPClient {constructor(serverUrl) {// 初始化客戶端this.serverUrl = serverUrl;  // MCP服務器地址,如'http://localhost:3000'}// 連接到MCP服務器async connect() {// 實際項目中,這里可能包含身份驗證邏輯console.log(`連接到MCP服務器: ${this.serverUrl}`);return true; // 返回連接狀態}// 調用遠程工具async callTool(name, params) {// name: 工具名稱,例如'processText'、'calculate'// params: 調用參數對象console.log(`調用工具: ${name}, 參數:`, params);// 實際項目中,這里應該是一個HTTP請求到服務器// 例如:await fetch(`${this.serverUrl}/tools/${name}`, { method: 'POST', body: JSON.stringify(params) })// 模擬返回結果,實際應該返回服務器響應switch(name) {case 'processText':if(params.operation === 'wordCount') return { count: params.text.split(/\s+/).length };if(params.operation === 'charCount') return { count: params.text.length };if(params.operation === 'toUpperCase') return { text: params.text.toUpperCase() };break;case 'calculate':if(params.operation === 'sum') return { value: params.numbers.reduce((a,b) => a+b, 0) };if(params.operation === 'average') return { value: params.numbers.reduce((a,b) => a+b, 0) / params.numbers.length };if(params.operation === 'max') return { value: Math.max(...params.numbers) };if(params.operation === 'min') return { value: Math.min(...params.numbers) };break;}return { status: 'error', message: '不支持的操作' };}// 獲取資源async getResource(type, path) {// type: 資源類型,如'file'// path: 資源路徑console.log(`獲取資源: ${type}, 路徑: ${path}`);// 實際項目中,這里應該是一個HTTP請求到服務器// 例如:await fetch(`${this.serverUrl}/resources/${type}?path=${path}`)// 模擬返回結果return { content: '資源內容示例' };}
}

這個類封裝了與服務器通信的基本方法,簡化了客戶端應用的開發流程。MCPClient類提供了以下主要功能:

  • connect(): 連接到MCP服務器
  • callTool(name, params): 調用服務器上注冊的工具
  • getResource(type, path): 獲取服務器上的資源

注意:為了簡化示例,這里使用了本地模擬實現,而不是真正的網絡請求。在實際項目中,應該使用fetch或axios等庫發送HTTP請求。

客戶端應用實現

有了基礎SDK后,我們可以創建一個更加完善的客戶端應用,它不僅封裝了與MCP服務的通信,還添加了日志記錄和錯誤處理等功能:

// src/client/index.js
import { MCPClient } from '../lib/mcp-sdk.js';
import winston from 'winston';export class MCPDemoClient {constructor() {// 初始化客戶端應用this.serverUrl = 'http://localhost:3000';  // MCP服務器地址this.setupLogger();                        // 設置日志記錄器}// 設置日志記錄系統setupLogger() {// 創建Winston日志記錄器,支持文件和控制臺輸出this.logger = winston.createLogger({level: 'info',                           // 日志級別format: winston.format.combine(winston.format.timestamp(),            // 添加時間戳winston.format.json()                  // 使用JSON格式),transports: [// 文件輸出new winston.transports.File({ filename: 'logs/client.log' }),// 控制臺輸出new winston.transports.Console()]});}// 連接到MCP服務器async connect() {try {// 創建MCP客戶端實例并連接this.client = new MCPClient(this.serverUrl);await this.client.connect();this.logger.info(`已連接到MCP服務器: ${this.serverUrl}`);return true;} catch (error) {// 記錄連接錯誤this.logger.error(`連接MCP服務器失敗: ${error.message}`);throw error;  // 重新拋出異常以便上層處理}}// 文本處理功能async processText(text, operation) {try {// 記錄操作this.logger.info(`執行文本處理: ${operation}`);// 調用MCP服務const result = await this.client.callTool('processText', {text,      // 要處理的文本operation  // 操作類型});// 根據操作類型返回相應結果switch(operation) {case 'wordCount':   // 單詞計數case 'charCount':   // 字符計數return result.count;case 'toUpperCase': // 轉換大寫return result.text;default:throw new Error('不支持的操作');}} catch (error) {// 記錄錯誤this.logger.error(`文本處理失敗: ${error.message}`);throw error;}}// 計算功能async calculate(operation, numbers) {try {// 記錄操作this.logger.info(`執行計算: ${operation}`);// 調用MCP服務const result = await this.client.callTool('calculate', {operation,  // 計算操作numbers     // 數字數組});return result.value;  // 返回計算結果} catch (error) {// 記錄錯誤this.logger.error(`計算失敗: ${error.message}`);throw error;}}// 文件讀取功能async readFile(filePath) {try {// 記錄操作this.logger.info(`讀取文件: ${filePath}`);// 調用MCP服務獲取文件內容return await this.client.getResource('file', filePath);} catch (error) {// 記錄錯誤this.logger.error(`讀取文件失敗: ${error.message}`);throw error;}}
}

這個類在基礎客戶端的基礎上添加了日志記錄、錯誤處理和功能封裝,提供了更加語義化的API。MCPDemoClient類是對基礎MCPClient的進一步封裝和擴展。它添加了以下功能:

  1. 日志系統:使用winston庫記錄操作日志和錯誤信息,支持同時輸出到文件和控制臺
  2. 錯誤處理:為每個操作添加了try-catch結構,確保異常被正確處理和記錄
  3. 功能封裝:提供了更加語義化的方法,如processTextcalculatereadFile

這種分層設計使得應用代碼更加清晰和易于維護。底層的MCPClient處理通信細節,而上層的MCPDemoClient關注業務邏輯和錯誤處理。

功能演示與測試

最后,通過演示腳本展示MCP服務的各項功能:

  • 文本處理:單詞計數、字符計數、轉換大寫
  • 數據計算:求和、平均值、最大值、最小值
  • 文件操作:讀取文件內容
  • 錯誤處理:捕獲并記錄各種異常情況

有了客戶端應用后,我們可以創建一個演示腳本來展示如何使用這些功能:

// src/client/demo.js
import { MCPDemoClient } from './index.js';async function runDemo() {try {console.log('啟動MCP客戶端演示...');// 創建客戶端并連接到服務器const client = new MCPDemoClient();await client.connect();console.log('\n=== MCP 功能演示 ===\n');// 1. 文本處理演示const text = 'Hello, MCP!';console.log('1. 文本處理功能:');console.log(`原始文本: ${text}`);// 獲取單詞數const wordCount = await client.processText(text, 'wordCount');console.log(`單詞數: ${wordCount}`);                        // 預期輸出: 2// 獲取字符數const charCount = await client.processText(text, 'charCount');console.log(`字符數: ${charCount}`);                        // 預期輸出: 10// 轉換為大寫const upperCase = await client.processText(text, 'toUpperCase');console.log(`轉換大寫: ${upperCase}`);                      // 預期輸出: HELLO, MCP!// 2. 計算功能演示const numbers = [1, 2, 3, 4, 5];console.log('\n2. 計算功能:');console.log(`數據集: ${JSON.stringify(numbers)}`);// 求和const sum = await client.calculate('sum', numbers);console.log(`sum: ${sum}`);                                // 預期輸出: 15// 平均值const avg = await client.calculate('average', numbers);console.log(`average: ${avg}`);                            // 預期輸出: 3// 最大值const max = await client.calculate('max', numbers);console.log(`max: ${max}`);                                // 預期輸出: 5// 最小值const min = await client.calculate('min', numbers);console.log(`min: ${min}`);                                // 預期輸出: 1// 3. 文件讀取演示console.log('\n3. 文件讀取功能:');const fileContent = await client.readFile('test.txt');console.log(`文件內容: ${fileContent.content}`);console.log('\n演示完成!');} catch (error) {// 捕獲并顯示所有錯誤console.error('演示過程中發生錯誤:', error);}
}// 運行演示
runDemo();

這個演示腳本展示了如何使用MCPDemoClient類的各種功能:

  1. 初始化和連接:創建客戶端實例并連接到MCP服務器
  2. 文本處理:演示三種文本操作(單詞計數、字符計數、轉大寫)
  3. 數據計算:演示四種計算操作(求和、平均值、最大值、最小值)
  4. 文件讀取:演示如何讀取文件內容

該腳本還包含了全局的錯誤處理,確保任何異常都能被捕獲并顯示給用戶。

啟動客戶端演示

要運行這個演示,只需執行以下命令:

# 確保MCP服務器已啟動后,運行客戶端演示
node src/client/demo.js# 客戶端將連接到localhost:3000的MCP服務
# 并演示各種功能調用

通過這個簡單的命令,您可以看到MCP服務的各種功能演示。確保在運行客戶端之前,MCP服務器已經啟動并正常運行。

3. 配置和啟動MCP服務

MCP服務的成功運行離不開正確的配置和啟動流程。本節將詳細介紹如何配置MCP服務、如何使用完整的服務器代碼,以及如何部署和啟動服務。

服務器配置文件

首先,我們需要創建一個配置文件來管理服務器的各種參數。這樣可以避免硬編碼,使服務更加靈活:

// src/config/server.config.js
export const serverConfig = {// 基礎配置port: 3000,                             // 服務器監聽端口host: 'localhost',                      // 服務器主機名// 自定義功能配置customFeatures: {enableCache: true,                    // 啟用緩存功能maxCacheSize: 1000,                   // 最大緩存條目數allowedTypes: ['text', 'json']        // 允許的內容類型},// 安全配置security: {allowedOrigins: ['http://localhost:8080'], // 允許的來源maxRequestSize: '1mb',                // 最大請求大小customRules: {maxRequestsPerIP: 1000,             // IP請求速率限制blacklistedIPs: []                  // 黑名單IP列表}},// 日志配置logging: {level: 'info',                        // 日志級別filename: './logs/server.log'         // 日志文件路徑}
};

這個配置文件包含了四大類設置:

  1. 基礎配置:包括服務器監聽的端口和主機名
  2. 自定義功能配置:控制緩存和內容類型等功能特性
  3. 安全配置:設置CORS、請求大小限制和IP訪問控制
  4. 日志配置:設置日志級別和輸出文件路徑

通過將這些配置抽離到單獨的文件中,我們可以根據不同環境(開發、測試、生產)使用不同的配置,而無需修改代碼。

完整服務器啟動代碼

接下來,我們來看一個更加完整的服務器實現,它使用Express框架創建HTTP服務器,并整合了之前定義的MCP功能:

// src/server/index.js - 完整實現
import { MCPServer } from '../lib/mcp-sdk.js';
import { serverConfig } from '../config/server.config.js';
import winston from 'winston';
import fs from 'fs/promises';
import express from 'express';class MCPDemoServer {constructor() {// 初始化服務器this.setupLogger();this.server = new MCPServer(serverConfig);this.app = express();this.setupMiddleware();this.setupHandlers();}// 設置日志記錄器setupLogger() {// 創建Winston日志記錄器,支持文件和控制臺輸出this.logger = winston.createLogger({level: serverConfig.logging.level,format: winston.format.combine(winston.format.timestamp(),            // 添加時間戳winston.format.json()                  // 使用JSON格式),transports: [// 文件輸出new winston.transports.File({ filename: serverConfig.logging.filename }),// 控制臺輸出new winston.transports.Console()]});}// 設置Express中間件setupMiddleware() {// 解析JSON請求體this.app.use(express.json({ limit: serverConfig.security.maxRequestSize }));// 日志中間件this.app.use((req, res, next) => {this.logger.info(`${req.method} ${req.path}`);next();});// CORS設置this.app.use((req, res, next) => {const origin = req.headers.origin;if (serverConfig.security.allowedOrigins.includes(origin)) {res.header('Access-Control-Allow-Origin', origin);}res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');res.header('Access-Control-Allow-Headers', 'Content-Type');next();});// 請求速率限制(簡化版)const requestCounts = new Map();this.app.use((req, res, next) => {const ip = req.ip;// 檢查黑名單if (serverConfig.security.customRules.blacklistedIPs.includes(ip)) {return res.status(403).json({ error: '訪問被拒絕' });}// 檢查請求速率const count = requestCounts.get(ip) || 0;if (count >= serverConfig.security.customRules.maxRequestsPerIP) {return res.status(429).json({ error: '請求過多' });}// 更新計數requestCounts.set(ip, count + 1);next();});}// 設置請求處理器setupHandlers() {// 注冊文件資源處理器this.server.registerResourceHandler('file', async (path) => {try {const content = await fs.readFile(path, 'utf-8');this.logger.info(`成功讀取文件: ${path}`);return { content };} catch (error) {this.logger.error(`讀取文件失敗: ${error.message}`);throw new Error(`無法讀取文件: ${error.message}`);}});// 注冊文本處理工具this.server.registerTool('processText', async ({ text, operation }) => {this.logger.info(`處理文本,操作: ${operation}`);try {switch(operation) {case 'wordCount':return { count: text.split(/\s+/).length };case 'charCount':return { count: text.length };case 'toUpperCase':return { text: text.toUpperCase() };default:throw new Error('不支持的操作');}} catch (error) {this.logger.error(`文本處理失敗: ${error.message}`);throw error;}});// 注冊計算工具this.server.registerTool('calculate', async ({ operation, numbers }) => {this.logger.info(`執行計算,操作: ${operation}`);try {if (!Array.isArray(numbers)) {throw new Error('輸入必須是數組');}switch(operation) {case 'sum':return { value: numbers.reduce((a, b) => a + b, 0) };case 'average':return { value: numbers.reduce((a, b) => a + b, 0) / numbers.length };case 'max':return { value: Math.max(...numbers) };case 'min':return { value: Math.min(...numbers) };default:throw new Error('不支持的操作');}} catch (error) {this.logger.error(`計算失敗: ${error.message}`);throw error;}});// 設置API路由this.app.post('/tools/:name', async (req, res) => {try {const name = req.params.name;const handler = this.server.tools.get(name);if (!handler) {return res.status(404).json({ error: '工具不存在' });}const result = await handler(req.body);res.json(result);} catch (error) {this.logger.error(`API錯誤: ${error.message}`);res.status(500).json({ error: error.message });}});this.app.get('/resources/:type', async (req, res) => {try {const type = req.params.type;const path = req.query.path;const handler = this.server.resources.get(type);if (!handler) {return res.status(404).json({ error: '資源類型不存在' });}const result = await handler(path);res.json(result);} catch (error) {this.logger.error(`資源錯誤: ${error.message}`);res.status(500).json({ error: error.message });}});}// 啟動服務器async start() {try {// 創建日志目錄try {await fs.mkdir('./logs', { recursive: true });} catch (err) {// 目錄可能已存在,忽略錯誤}// 啟動HTTP服務器const port = serverConfig.port;const host = serverConfig.host;this.app.listen(port, host, () => {this.logger.info(`MCP服務器已啟動,監聽 ${host}:${port}`);});} catch (error) {this.logger.error(`服務器啟動失敗: ${error.message}`);throw error;}}
}// 創建并啟動服務器
const server = new MCPDemoServer();
server.start().catch(error => {console.error('服務器錯誤:', error);process.exit(1);
});

這個完整的服務器實現包含了以下關鍵組件:

  1. MCPDemoServer類:封裝了服務器的全部功能

    • setupLogger(): 設置日志系統
    • setupMiddleware(): 配置Express中間件
    • setupHandlers(): 注冊工具和資源處理器
    • start(): 啟動服務器
  2. 中間件配置

    • JSON解析器:處理請求體
    • 日志中間件:記錄所有請求
    • CORS中間件:處理跨域請求
    • 速率限制中間件:防止濫用
  3. API路由

    • /tools/:name:訪問各種工具功能
    • /resources/:type:訪問各種資源

這種結構設計使得服務器代碼更加模塊化和可維護,同時提供了完善的安全和日志功能。

部署腳本

為了簡化部署過程,我們可以創建一個部署腳本,它會自動創建必要的目錄、檢查配置文件、安裝依賴并啟動服務器:

// scripts/deploy.js - 部署輔助腳本
import fs from 'fs/promises';
import { exec } from 'child_process';
import { promisify } from 'util';const execAsync = promisify(exec);async function deploy() {try {// 1. 確保目錄結構存在console.log('創建目錄結構...');await fs.mkdir('./logs', { recursive: true });await fs.mkdir('./src/config', { recursive: true });await fs.mkdir('./src/lib', { recursive: true });await fs.mkdir('./src/server', { recursive: true });await fs.mkdir('./src/client', { recursive: true });// 2. 檢查配置文件console.log('檢查配置文件...');try {await fs.access('./src/config/server.config.js');console.log('配置文件已存在');} catch {console.log('創建默認配置文件...');const defaultConfig = `export const serverConfig = {port: 3000,host: 'localhost',logging: { level: 'info', filename: './logs/server.log' }};`;await fs.writeFile('./src/config/server.config.js', defaultConfig);}// 3. 安裝依賴console.log('安裝依賴...');await execAsync('npm install');// 4. 啟動服務器console.log('啟動MCP服務器...');await execAsync('node src/server/index.js');} catch (error) {console.error('部署失敗:', error);}
}// 執行部署
deploy();

這個部署腳本執行了以下步驟:

  1. 創建必要的目錄結構
  2. 檢查并創建默認配置文件(如果不存在)
  3. 安裝項目依賴
  4. 啟動MCP服務器

通過這個腳本,您可以一鍵完成所有部署步驟,無需手動執行多個命令。

完整啟動流程

如果您想手動執行每個步驟,可以按照以下流程操作:

# 1. 安裝依賴
npm install# 2. 創建日志目錄
mkdir -p logs# 3. 檢查配置
node -e "console.log('驗證配置...')"# 4. 啟動服務器
node src/server/index.js# 5. 在新終端測試服務
curl http://localhost:3000/tools/processText -H "Content-Type: application/json" \-d '{"text":"Hello World","operation":"wordCount"}'
# 預期輸出: {"count":2}

這個流程確保了所有必要的準備工作都已完成,并驗證服務器是否正常運行。最后的curl命令測試了文本處理功能,如果一切正常,您應該能看到返回的單詞數量。

三,整體實現代碼邏輯講解

MCP服務的整體實現遵循了一種模塊化和可擴展的設計理念,主要包含以下幾個關鍵部分:

1. 服務端初始化與配置

MCP服務的第一步是初始化服務器環境和配置。這個過程包括:

  • 安裝必要依賴(Node.js、winston、express、dotenv)
  • 創建配置文件,管理服務器參數(端口、主機名、安全設置等)
  • 初始化MCPServer實例,準備注冊工具和資源處理器

服務端的核心是MCPServer類,它提供了工具和資源注冊的功能,通過Map數據結構存儲各種處理器。完整的服務器實現(MCPDemoServer類)在此基礎上添加了日志記錄、中間件配置和API路由定義,使其成為一個功能完整的HTTP服務器。

2. 注冊服務功能

MCP服務的核心是其功能注冊機制,允許以插件式架構添加各種功能:

  • 工具注冊:使用registerTool方法注冊各種處理工具
  • 資源處理器:使用registerResourceHandler注冊資源訪問方法
  • 每個工具和資源處理器都是獨立的功能單元,支持異步操作

我們在示例中注冊了兩類工具(文本處理和數值計算)和一種資源處理器(文件讀取),它們共同構成了MCP服務的基本功能。

3. 客戶端SDK實現

為了便于應用程序與MCP服務交互,實現了客戶端SDK:

  • 基礎客戶端類:MCPClient封裝了與服務器通信的基本方法
  • 擴展客戶端類:MCPDemoClient添加了日志、錯誤處理和功能封裝
  • 客戶端類提供語義化API,簡化服務調用流程

客戶端SDK采用了分層設計,底層的MCPClient負責通信細節,上層的MCPDemoClient關注業務邏輯和錯誤處理,這種設計使得應用代碼更加清晰和易于維護。

4. 安全性和性能考慮

完整的MCP服務實現考慮了多方面的安全性和性能因素:

  • CORS設置:控制跨域請求,只允許特定來源的訪問
  • 請求限制:實現IP黑名單和請求速率限制,防止服務濫用
  • 錯誤處理:全面的錯誤捕獲和日志記錄,便于問題排查
  • 配置分離:將配置項抽離到單獨文件,方便不同環境的部署

四,可擴展的內容

MCP服務設計為高度可擴展的架構,以下是可以進一步擴展的方向:

1. 核心服務擴展

MCPServer類設計為可擴展架構,允許注冊任意數量的工具和資源處理器。您可以添加新的工具功能,如:

  • 數據轉換功能(JSON、XML、CSV等格式轉換)
  • 機器學習模型集成(圖像識別、文本分類等)
  • 第三方API集成(地圖服務、支付系統等)

2. 配置系統擴展

配置文件支持多環境部署,可擴展的方面包括:

  • 多環境配置(開發、測試、生產)
  • 動態配置加載(基于環境變量或配置服務)
  • 配置驗證和自動修復機制

3. 中間件擴展

Express中間件層可以添加更多功能:

  • 身份驗證和授權(JWT、OAuth等)
  • 請求壓縮和緩存策略
  • 高級監控和性能分析

4. 客戶端功能擴展

客戶端SDK可以擴展更多功能:

  • 離線模式和數據同步
  • 批處理和隊列機制
  • 智能重試和熔斷器模式

5. 部署與運維擴展

部署腳本可以擴展為完整的CI/CD流程:

  • 容器化部署(Docker、Kubernetes)
  • 自動化測試和質量檢查
  • 監控和告警系統集成

五, 學習資源

在學習和開發MCP服務的過程中,以下資源將非常有幫助:

1. 搭建MCP服務的快速入門

快速入門資源可以幫助您迅速理解MCP服務的基本概念和使用方法:

  • MCP SDK文檔: https://docs.anthropic.com/mcp/
    這里包含了MCP SDK的完整API參考、使用示例和最佳實踐。

  • API參考: https://api.anthropic.com/mcp/
    提供了詳細的API端點說明、請求/響應格式和錯誤處理指南。

2. MCP基礎學習相關文章鏈接

  • MCP基礎學習: 從MCP入門到項目構建的全面指南

  • MCP基礎學習一: MCP概述與基礎

  • MCP基礎學習二:MCP服務搭建與配置

  • MCP基礎學習三: MCP客戶端開發與工具集成

  • MCP 服務搭建與配置學習資源部分匯總

3. 相關代碼鏈接

  • MCP 服務示例項目GitCode

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/75365.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/75365.shtml
英文地址,請注明出處:http://en.pswp.cn/web/75365.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

ZKmall開源商城服務端驗證:Jakarta Validation 詳解

ZKmall開源商城基于Spring Boot 3構建,其服務端數據驗證采用Jakarta Validation API?(原JSR 380規范),通過聲明式注解與自定義擴展機制實現高效、靈活的數據校驗體系。以下從技術實現、核心能力、場景優化三個維度展開解析&#…

使用Docker創建postgres

準備工作: 1. 檢查網絡 檢查網絡連接:確保你的服務器網絡連接正常,可嘗試使用 ping 命令測試與 Docker Hub 服務器(如 ping registry-1.docker.io)的連通性。 ping registry-1.docker.io 檢查防火墻:確…

32 python json

在辦公室忙碌的日常里,我們經常需要和各種數據打交道。想象一下,你是辦公室里負責處理員工信息、項目數據的 “數據小管家”,每天都要面對大量格式各異的數據。 這時候,JSON(JavaScript Object Notation)就像是你得力的數據助手,它是一種輕量級的數據交換格式,簡單又高…

Java 實現 List<String> 與 String 互轉

在 Java 開發過程中&#xff0c;有時需要將 List<String> 轉為 String 存儲&#xff0c;后續使用時再還原回去。此時就需要 Java 實現 List<String> 與 String 互轉。以下是一種互轉方式。 采用如下工具包實現。 <dependency><groupId>org.apache.com…

NO.87十六屆藍橋杯備戰|動態規劃-完全背包|瘋狂的采藥|Buying Hay|紀念品(C++)

完全背包 先解決第?問 狀態表?&#xff1a; dp[i][j]表?&#xff1a;從前i個物品中挑選&#xff0c;總體積不超過j&#xff0c;所有的選法中&#xff0c;能挑選出來的最?價 值。&#xff08;這?是和01背包?樣噠&#xff09; 那我們的最終結果就是dp[n][V] 。狀態轉移?…

第十三天 - Ansible基礎架構 - YAML語法與Playbook - 練習:批量配置部署

Ansible自動化運維實戰&#xff1a;從入門到批量配置部署 前言&#xff1a;自動化運維的時代選擇 在服務器規模呈指數級增長的今天&#xff0c;手工操作已無法滿足運維需求。本文將手把手教你使用Ansible這個明星級自動化工具&#xff0c;通過YAML語法和Playbook實現批量配置…

Redis的過期和內存淘汰策略

文章目錄 惰性刪除定期刪除內存滿了&#xff0c;數據淘汰策略 Redis 提供了兩種刪除策略&#xff1a; 惰性刪除 、定期刪除 惰性刪除 定期刪除 兩種清除模式: 內存滿了&#xff0c;數據淘汰策略 Redis 提供了八種數據淘汰策略&#xff1a; 1. 默認是不淘汰任何的 key&#x…

用PHPExcel 封裝的導出方法,支持導出無限列

用PHPExcel 封裝的導出方法&#xff0c;支持導出無限列 避免PHPExcel_Exception Invalid cell coordinate [1 異常錯誤 /*** EXCEL導出* param [string] $file_name 保存的文件名及表格工作區名&#xff0c;不加excel后綴名* param [array] $fields 二維數組* param [array] $…

WHAT - React 元素接收的 ref 詳解

目錄 1. ref 的基本概念2. 如何使用 ref2.1 基本用法2.2 類組件使用 createRef 3. forwardRef 轉發 ref4. ref 的應用場景5. ref 和函數組件總結 在 React 中&#xff0c;ref&#xff08;引用&#xff09;用于訪問 DOM 元素或類組件實例。它允許我們直接與元素進行交互&#xf…

【QT】QT的消息盒子和對話框(自定義對話框)

QT的消息盒子和對話框&#xff08;自定義對話框&#xff09; 一、消息盒子QMessageBox1、彈出警告盒子示例代碼&#xff1a;現象&#xff1a; 2、致命錯誤盒子示例代碼&#xff1a;現象&#xff1a; 3、幫助盒子示例代碼&#xff1a;現象&#xff1a; 4、示例代碼&#xff1a; …

依靠視頻設備軌跡回放平臺EasyCVR構建視頻監控,為幼教連鎖園區安全護航

一、項目背景 幼教行業連鎖化發展態勢越發明顯。在此趨勢下&#xff0c;幼兒園管理者對于深入了解園內日常教學與生活情況的需求愈發緊迫&#xff0c;將這些數據作為提升管理水平、優化教育服務的重要依據。同時&#xff0c;安裝監控系統不僅有效緩解家長對孩子在校安全與生活…

Stable Diffusion+Pyqt5: 實現圖像生成與管理界面(帶保存 + 歷史記錄 + 刪除功能)——我的實驗記錄(結尾附系統效果圖)

目錄 &#x1f9e0; 前言 &#x1f9fe; 我的需求 &#x1f527; 實現過程&#xff08;按功能一步步來&#xff09; &#x1f6b6;?♂? Step 1&#xff1a;基本圖像生成界面 &#x1f5c3;? Step 2&#xff1a;保存圖片并顯示歷史記錄 &#x1f4cf; Step 3&#xff1a…

量子計算未來的潛力和挑戰

據麥肯錫預測&#xff0c;到 2035 年或 2040 年&#xff0c;量子計算市場規模可能增長至約 800 億美元。目前&#xff0c;許多量子比特技術正競相成為首臺通用、無差錯量子計算機的基礎&#xff0c;但仍面臨諸多挑戰。 我們將探討量子計算的未來前景、潛力&#xff0c;以及它對…

ArcGIS 給大面內小面字段賦值

文章目錄 引言:地理數據處理中的自動化賦值為何重要?實現思路模型實現關鍵點效果實現步驟1、準備數據2、執行3、完成4、效果引言:地理數據處理中的自動化賦值為何重要? 在地理信息系統(GIS)的日常工作中,空間數據的屬性字段賦值是高頻且關鍵的操作,例如在土地利用規劃…

如何打通虛擬化-容器環境并保障流量安全?SmartX VCCI 方案升級!

為了提升資源利用率、交付效率和業務靈活性&#xff0c;不少企業用戶都在推進從傳統架構向云原生架構的演進&#xff0c;并采用虛擬機與容器共存的混合模式支持多種業務系統。由于兩個環境在業務交互層面形成高度耦合&#xff0c;企業需要具備簡單、高效方案&#xff0c;實現虛…

stable diffusion 量化加速點

文章目錄 一、導出為dynamic shape1)函數講解(函數導出、輸出檢查)2)代碼展示二、導出為static shape1)函數講解(略)2)代碼展示三、序列化為FP32測速1)測速2)代碼四、序列化為FP16測速1)測速2)代碼同上五、發現并解決解決CLIP FP16溢出,并測速1)如何找到溢出的算子…

7-openwrt-one通過web頁面配置訪客網絡、無線中繼等功能

前幾個章節一直在介紹編譯、分區之類的,都還沒正常開始使用這個路由器的wifi。默認wifi是沒有啟動的,前面還是通過手動修改uci配置啟動的,這個章節介紹下官方web頁面的使用。特別是訪客網絡、無線中繼 1、開啟wifi,配置wifi基本信息 我們使用有線連接路由器,通過192.168.…

AcWing 6099. 座位

原題目鏈接 問題描述 有 n 頭奶牛&#xff08;n ≥ 5&#xff09;&#xff0c;編號為 1 ~ n&#xff0c;按照某種順序圍著一張圓桌坐成一圈。 奶牛之間存在如下的朋友關系&#xff1a; 如果兩頭奶牛相鄰&#xff0c;則它們是朋友&#xff1b;如果兩頭奶牛之間只隔著一頭奶…

44、Spring Boot 詳細講義(一)

Spring Boot 詳細講義 目錄 Spring Boot 簡介Spring Boot 快速入門Spring Boot 核心功能Spring Boot 技術棧與集成Spring Boot 高級主題Spring Boot 項目實戰Spring Boot 最佳實踐總結 一、Spring Boot 簡介 1. Spring Boot 概念和核心特點 1.1、什么是 Spring Boot&#…

配置mac mini M4 的一些軟件

最近更換了 mac mini M4 &#xff0c;想要重新下載配置軟件 &#xff0c;記錄一下。 Homebrew是什么&#xff1f; homebrew是一款Mac OS平臺下的軟件包管理工具&#xff0c;擁有安裝、卸載、更新、查看、搜索等功能。通過簡單的指令可以實現包管理&#xff0c;而不用關心各種…