一文入门 MCP(Model Context Protocol)

你是谁?

Model Context Protocol

一个约定好的协议。使得开发者能够以一致的方式将各种数据源、工具和功能连接到 AI 模型(一个中间协议层),就像 USB-C 让不同设备能够通过相同的接口连接一样。

而约定的三方分别是:

  • MCP Host 也就是用户使用的客户端,比如cursor,trae ------ 笔记本
  • MCP Client 也就是中转站 ------ 笔记本扩展坞
  • MCP server 要扩展的工具 ------ Type-C接头 这边举个例子:
组件 餐厅类比 技术职责
用户 顾客 提出自然语言请求(如"查订单123的物流")
MCP Host 服务员+厨师 1. 理解用户意图 2. 决定需要调用哪些工具 3. 整合结果生成自然响应
​​MCP Client​​ 传菜员 1. 将Host的指令转为标准协议 2. 管理连接/重试等通信细节
​​ MCP Server​​ 厨房设备 实际执行数据查询/API调用等具体操作

这三者通过约定好的协议,协调工作

从哪里来?

本质来源于人们懒地 Ctrl C V ,而前置雏形则是prompt engineering(提示词)提示词MCP的目的就是让AI更高效更准确地来工作

假如没有MCP,在使用AI的过程中,必然需要人工提取关键信息,然后提供。从提出问题到解答变成了多个步骤:

  1. 提出问题
  2. AI思考并给出初步答案
  3. 人工纠错或提供更多信息
  4. AI再思考最终给出准确答案

最关键纠错和提供信息的过程可能会持续好几个回合 而当MCP出现之后,AI会自动取寻找相关的信息,并自己去获取错误,然后再思考。分步操作瞬间变成了自动化操作

要去往何方

与AI相关的技术,最终目的只有一个:让AI代替人 所以MCP 的目标是创建一个通用标准,使 AI 应用程序的开发和集成变得更加简单和统一,让 AI 能直接调用那些它本不能调用或模糊理解的东西

如何实现的

MCP其实可以理解为协商过后定义下来的数据格式,来看一个问题到解答的流程图: 根据这张图,我们可以拆解出几个关键的地方:

  • 模型 <-------> MCP Client (为什么直接说是模型与MCP Client沟通,因为MCP Host就是客户端,就是个壳子,需要沟通的其实是模型和MCP Client)
  • MCP Client <--------> MCP Server

MCP Client 与 MCP Server 之间

clientserver 两者之间有个明确的数据格式:JSON-RPC 所以同情本质为 HTTP content-type = json-rpc

JSON-RPC规定了具体的数据规范,比如:

请求对象(Request Object)

字段名 类型 是否必须 说明
jsonrpc String 必须 协议版本,​​必须为"2.0"​​
method String 必须 调用的方法名,禁止以rpc.开头
params Array / Object 可选 方法参数,可省略
id String / Number / null 可选 请求标识符。若省略则为​​通知​​(无响应);建议不为null且数字为整数

响应对象(Response Object)​

字段名 类型 是否必须 说明
jsonrpc String 必须 协议版本,​​必须为"2.0"​​
result Any 成功时必选 方法返回值,​​与error互斥​​
error Object 失败时必选 错误信息(含code和message),​​与result互斥​​
id String / Number / null 必须 必须与请求的id一致;若请求id无效(如解析错误),则必须为null
text 复制代码
--> {"jsonrpc": "2.0", "method": "subtract", "params": {"subtrahend": 23, "minuend": 42}, "id": 3}
<-- {"jsonrpc": "2.0", "result": 19, "id": 3}

--> {"jsonrpc": "2.0", "method": "subtract", "params": {"minuend": 42, "subtrahend": 23}, "id": 4}
<-- {"jsonrpc": "2.0", "result": 19, "id": 4}

具体可以去官网中查看www.jsonrpc.org/specificati...

MCP Host(模型)与MCP Client 之间

我们直接看deepseekAPI中的请求参数: 这里 这边我们看到请求分成了四种:系统设定(System)用户输入(User)AI响应(Assistant)工具回调(Tool) 而在MCP中我们需要关注的就是工具回调(Tool),也就是MCP Server执行后的结果传入的消息。 至于怎么告诉AI模型有哪些方法可以执行呢?则是通过一下的参数tools传入

MCP Server 最小实现

相对于 MCP ClientMCP Host 来说,平常开发者其实更关注 MCP Server 的开发,毕竟不管是 AI模型开发 还是 客户端开发 都是巨大的工程,反而个人写一个MCP Server是非常现实的。

所以我们直接先看 MCP Server ,它一共有三大块功能:

  • Resources(资源):类似文件的数据,可以被客户端读取(如 API 响应或文件内容)
  • Tools(工具):可以被 LLM 调用的函数(需要用户批准)
  • Prompts(提示):预先编写的模板,帮助用户完成特定任务

下面只讲解最小实现,具体构建项目可以参考官方文档,都是简单的命令行执行

javascript 复制代码
import {
  McpServer,
  ResourceTemplate,
} from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";

// 创建一个McpServer实例,名称为"Demo",版本为"1.0.0"
const server = new McpServer({
  name: "Demo",
  version: "1.0.0",
});

// 定义一个名为"add"的工具,接受两个数字参数a和b,返回它们的和
server.tool("add", { a: z.number(), b: z.number() }, async ({ a, b }) => ({
  content: [{ type: "text", text: String(a + b) }],
}));

// 定义一个名为"greeting"的资源,根据{name}参数生成问候信息
server.resource(
  "greeting",
  new ResourceTemplate("greeting://{name}", {
    list: async () => ({
      resources: [
        {
          uri: "greeting://",
          name: "这是一个描述",
        },
      ],
    }),
  }),
  async (uri, { name }) => ({
    contents: [
      {
        uri: uri.href, // 确保 uri.href 是字符串
        text: `Hello, ${name}!`,
      },
    ],
  })
);

// 定义一个名为"greet"的提示,生成问候消息,支持多种语言
server.prompt(
  "greet",
  "Generate a greeting message",
  {
    name: z.string().describe("Name to greet"),
    language: z.enum(["en", "zh", "es"]).describe("Language for greeting"),
  },
  async ({ name, language }) => {
    const greetings = {
      en: `Hello, ${name}!`,
      zh: `你好,${name}!`,
      es: `¡Hola, ${name}!`,
    };
    return {
      messages: [
        {
          role: "assistant",
          content: {
            type: "text",
            text: greetings[language],
          },
        },
      ],
    };
  }
);

// 使用StdioServerTransport创建一个传输实例,并将server连接到该传输实例
const transport = new StdioServerTransport();
await server.connect(transport);

以上可以看出要写一个简单的MCP Server是非常简单的,主要按照规定的格式和类型就不会有问题。

官方还提供了个debug的方式npx @modelcontextprotocol/inspector node main.js

MCP Client 是如何接受数据的?

javascript 复制代码
  // 列出所有提示
  async listPrompts() {
    try {
      const result = await this.mcp.listPrompts();
      console.log("Available prompts:", result);
      return result.prompts;
    } catch (e) {
      console.log("Failed to list prompts:", e);
      throw e;
    }
  }
  
  // 调用指定提示
  async callPrompt(name, language) {
    try {
      const result = await this.mcp.getPrompt({
        name: "greet",
        arguments: { name, language },
      });
      console.log("Prompt result:", result.messages);
      return result.content;
    } catch (e) {
      console.log("Failed to call prompt:", e);
      throw e;
    }
  }

// 列出所有资源
  async listResources() {
    try {
      const result = await this.mcp.listResources();
      console.log("Available resources:", result);
      return result.resources;
    } catch (e) {
      console.log("Failed to list resources:", e);
      throw e;
    }
  }

  // 读取指定资源的内容
  async readResource(resourceUri, variable) {
    try {
      const result = await this.mcp.readResource({
        uri: resourceUri,
      });
      console.log("Resource content:", result);
      return result.content;
    } catch (e) {
      console.log("Failed to read resource:", e);
      throw e;
    }
  }

  // 列出所有提示
  async listPrompts() {
    try {
      const result = await this.mcp.listPrompts();
      console.log("Available prompts:", result);
      return result.prompts;
    } catch (e) {
      console.log("Failed to list prompts:", e);
      throw e;
    }
  }
   
  // 调用指定提示
  async callPrompt(name, language) {
    try {
      const result = await this.mcp.getPrompt({
        name: "greet",
        arguments: { name, language },
      });
      console.log("Prompt result:", result.messages);
      return result.content;
    } catch (e) {
      console.log("Failed to call prompt:", e);
      throw e;
    }
  }
相关推荐
摘星编程2 小时前
MCP提示词工程:上下文注入的艺术与科学
人工智能·提示词工程·a/b测试·mcp·上下文注入
思绪漂移13 小时前
阿里云 【免费试用】MCP 赋能可视化 OLAP 智能体应用
阿里云·云计算·agent·云原生数据库·mcp
大模型真好玩14 小时前
深入浅出LangChain AI Agent智能体开发教程(五)—LangChain接入工具基本流程
人工智能·python·mcp
idolyXyz17 小时前
JSON-RPC 2.0 规范
ai·mcp
NocoBase19 小时前
GitHub 上 Star 数量前 8 的开源 MCP 项目
开源·openai·mcp
Lstmxx20 小时前
解放前端生产力:我如何用 LLM 和 Bun.js 构建一个 YApi to TypeScript 的自动化代码生成服务
前端·ai编程·mcp
裘乡20 小时前
MCP 进阶思考
mcp
CloudWeGo20 小时前
AI编程幻觉频发?字节跳动开源ABCoder:让AI深度阅读你的代码
ai编程·mcp·trae
人生都在赌1 天前
我用一个周末开发的MCP工具,让Claude帮我管理了整个项目
ai编程·claude·mcp