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服务器交互了!!

相关推荐
用户47949283569151 天前
都说node.js是事件驱动的,什么是事件驱动?
前端·node.js
用户4099322502121 天前
Vue 3中watch侦听器的正确使用姿势你掌握了吗?深度监听、与watchEffect的差异及常见报错解析
前端·ai编程·trae
yaocheng的ai分身1 天前
【转载】我如何用Superpowers MCP强制Claude Code在编码前进行规划
ai编程·claude
重铸码农荣光1 天前
从逐行编码到「氛围编程」:Trae 带你进入 AI 编程新纪元
ai编程·trae·vibecoding
Juchecar1 天前
Spring是Java语境下的“最优解”的原因与启示
java·spring·node.js
Juchecar1 天前
利用AI辅助"代码考古“操作指引
人工智能·ai编程
Juchecar1 天前
AI时代,如何在人机协作中保持代码的清晰性与一致性
人工智能·ai编程
玲小珑1 天前
LangChain.js 完全开发手册(十八)AI 应用安全与伦理实践
前端·langchain·ai编程
飞哥数智坊1 天前
11月12日,TRAE SOLO 正式版发布
人工智能·ai编程·solo
前端双越老师1 天前
等 AI 编程普及后,我该何去何从?
人工智能·ai编程