MCP从入门到实战

MCP介绍

大多数资料都会说是一种模型上下文协议,对!它仅仅就是一个协议,协议只是一种规范,让它变得通用,所以一些支持MCP的AI大模型的客户端也只不过是遵循了这种协议,让她得以调用MCP服务器中的工具

什么是MCP服务器呢

MCP服务器是一个符合 MCP 协议的、可被大语言模型(LLM)通过标准化方式调用的"服务提供者"或"工具接口",也就是当你向MCP服务器发送某个数据包的时候,MCP服务器会返回符合MCP协议的数据包,传输协议一般是标准输入输出stdio,或者远程的https,下面会使用Node为例搭建一个简单的MCP服务器(任何其它语言也可以,只需满足MCP的通信协议)

MCP的用处

简单来说就是为大模型赋能,因为只要你的MCP服务器可以做的功能,大模型这边就可以调用你的MCP服务器中的工具实现任何你想要的功能,比如一般来说大模型是无法操作你的电脑对文件进行操作的,但是只要在你的MCP服务器中实现一个工具:对文件进行读写等,那么你的大模型就可以调用这个工具实现对本地电脑文件的操作了,是不是很强呢

MCP基本通信格式

1. 初始化

request

json 复制代码
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "initialize",
  "params": {
    "protocolVersion": "2024-11-05",
    "capabilities": {
      "roots": {
        "listChanged": true
      },
      "sampling": {},
      "elicitation": {}
    },
    "clientInfo": {
      "name": "ExampleClient",
      "title": "Example Client Display Name",
      "version": "1.0.0"
    }
  }
}

response

json 复制代码
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "protocolVersion": "2024-11-05",
    "capabilities": {
      "logging": {},
      "prompts": {
        "listChanged": true
      },
      "resources": {
        "subscribe": true,
        "listChanged": true
      },
      "tools": {
        "listChanged": true
      }
    },
    "serverInfo": {
      "name": "ExampleServer",
      "title": "Example Server Display Name",
      "version": "1.0.0"
    },
    "instructions": "Optional instructions for the client"
  }
}

2. 工具发现

request

json 复制代码
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/list",
  "params": {
    "cursor": "optional-cursor-value"
  }
}

response

json 复制代码
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "tools": [
      {
        "name": "get_weather",
        "title": "Weather Information Provider",
        "description": "Get current weather information for a location",
        "inputSchema": {
          "type": "object",
          "properties": {
            "location": {
              "type": "string",
              "description": "City name or zip code"
            }
          },
          "required": ["location"]
        }
      }
    ],
    "nextCursor": "next-page-cursor"
  }
}

3. 工具调用

request

json 复制代码
{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tools/call",
  "params": {
    "name": "get_weather",
    "arguments": {
      "location": "New York"
    }
  }
}

response

json 复制代码
{
  "jsonrpc": "2.0",
  "id": 2,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "Current weather in New York:\nTemperature: 72°F\nConditions: Partly cloudy"
      }
    ],
    "isError": false
  }
}

Node实现一个基础的MCP服务器

javascript 复制代码
const readline = require('readline');

// 创建readline接口
const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
  terminal: false
});

// ============== 工具定义 ==============
const tools = [
  {
    name: "sum",
    title: "求和",
    description: "计算两数之和",
    inputSchema: {
      type: "object",
      properties: {
        a: { 
          type: "number", 
          description: "第一个数" 
        },
        b: { 
          type: "number", 
          description: "第二个数" 
        }
      },
      required: ["a", "b"]
    }
  }
];

// ============== 工具处理器 ==============
const toolHandlers = {
  // 计算两数之和
  sum: ({ a, b }) => {
    if (typeof a !== 'number' || typeof b !== 'number') {
      throw new Error("Both arguments must be numbers");
    }
    return `${a} + ${b} = ${a + b}`;
  }
};

// ============== 请求处理器 ==============
const requestHandlers = {
  // 处理初始化请求
  "initialize": (params, id) => ({
    jsonrpc: "2.0",
    id,
    result: {
      protocolVersion: params.protocolVersion,
      capabilities: {
        prompts: { listChanged: true },
        resources: { subscribe: true, listChanged: true },
        tools: { listChanged: true }
      },
      serverInfo: {
        name: "XiaoZheMCP",
        title: "XiaoZhe MCP Server",
        version: "0.0.0"
      },
      instructions: "测试"
    }
  }),
  
  // 返回工具列表
  "tools/list": (_, id) => ({
    jsonrpc: "2.0",
    id,
    result: { tools }
  }),
  
  // 处理工具调用
  "tools/call": async (params, id) => {
    const { name, arguments: args } = params;
    const handler = toolHandlers[name];
    
    try {
      // 检查工具是否存在
      if (!handler) {
        throw new Error(`Tool '${name}' not found`);
      }
      
      // 执行工具处理
      const result = await handler(args);
      
      return {
        jsonrpc: "2.0",
        id,
        result: {
          content: [{ type: "text", text: result }],
          isError: false
        }
      };
    } catch (error) {
      return {
        jsonrpc: "2.0",
        id,
        error: {
          code: -32000,
          message: "Tool execution failed",
          data: error.message
        }
      };
    }
  }
};

// ============== 主处理逻辑 ==============
rl.on('line', async (line) => {
  try {
    const request = JSON.parse(line);
    const handler = requestHandlers[request.method];
    
    if (!handler) {
      throw new Error(`Unsupported method: ${request.method}`);
    }
    
    // 处理请求并发送响应
    const response = await handler(request.params, request.id);
    console.log(JSON.stringify(response));
    
  } catch (error) {
    // 处理解析错误
    const errorResponse = {
      jsonrpc: "2.0",
      id: null,
      error: {
        code: -32700,
        message: "Parse error",
        data: error.message
      }
    };
    console.error(JSON.stringify(errorResponse));
  }
});

MCP调试工具

sh 复制代码
npx @modelcontextprotocol/inspector

执行后完成后会自动打开一个网页,然后就可以愉快的测试了

官方库快速开发MCP服务器

安装依赖包:

sh 复制代码
npm i @modelcontextprotocol/sdk
sh 复制代码
npm i zod

示例代码:

javascript 复制代码
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: "XiaoZheMCP",
  title: "XiaoZhe MCP Server",
  version: "1.0.0",
});

// 创建工具
server.registerTool(
    'sum',
    {
        title: '求和',
        description: '计算两数之和',
        inputSchema: {
            a: z.number().describe('第一个数'),
            b: z.number().describe('第二个数')
        }
    },
    ({a, b})=>{
        return {
            content: [
                {
                    type: 'text',
                    text: `${a} + ${b} = ${a + b}`
                }
            ]
        }
    }
)

const transport = new StdioServerTransport();
server.connect(transport);

最后

可以使用任意支持MCP服务器和大模型的客户端,这样就可以使用对话的方式和自己的MCP服务器交互了!!

相关推荐
dasseinzumtode7 小时前
nestJS 使用ExcelJS 实现数据的excel导出功能
前端·后端·node.js
库森学长7 小时前
2025年,你不能错过Spring AI,那个汲取了LangChain灵感的家伙!
后端·openai·ai编程
梅孔立11 小时前
服务器不支持node.js16以上版本安装?用Docker轻松部署Node.js 20+环境运行Strapi项目
服务器·docker·node.js
XiaoMu_00111 小时前
基于Node.js和Three.js的3D模型网页预览器
javascript·3d·node.js
卿·静11 小时前
Node.js对接即梦AI实现“千军万马”视频
前端·javascript·人工智能·后端·node.js
lvlv_feifei12 小时前
N8N macOS (Apple Silicon) 完整安装配置教程
node.js·workflow
Larkin12 小时前
AI辅助编程实战:从零到一开发Swift性能框架的经验分享
ai编程
ITZHIHONH12 小时前
FastGPT源码解析 Agent知识库文本资料处理详解和代码分析
数据库·ai编程
SamDeepThinking12 小时前
在 Cursor IDE 中配置 SQLTools 连接 MySQL 数据库指南(Windows 11)
后端·ai编程·cursor