MCP(Model Context Protocol)深入解析:从概念到实践

0 阅读8分钟

摘要: MCP(Model Context Protocol,模型上下文协议)是 Anthropic 提出的一种标准化协议,旨在解耦大语言模型(LLM)与外部工具(Tool)、数据源(Resource)之间的通信。本文基于 mcp-demo 项目,从问题背景出发,逐步深入 MCP 的核心概念、架构设计,并通过一个完整的 Node.js MCP Server 实战案例,带你理解 MCP 的跨进程通信机制。


目录

  1. 为什么需要 MCP?
  2. MCP 协议是什么?
  3. MCP 的核心特点
  4. 项目实战:构建一个 MCP Server
  5. MCP 的通信机制
  6. MCP Tool 的本质
  7. 总结与展望

1. 为什么需要 MCP?

在传统的 AI Agent 开发中,工具(Tool)往往与 LLM 紧密耦合,存在两个核心痛点:

  1. 工具无法跨项目复用 —— 在一个项目中编写的 Tool,很难直接迁移到另一个项目中使用。
  2. 语言绑定限制 —— 用 Node.js 写的工具,Java / Python / Rust 等其他语言的项目如何调用?

这些问题的本质是:Tool 与 LLM 之间缺乏一个标准化的通信协议

7f49bafc0e124801b519a1d7ff03c454.png

MCP 正是为了解决这些问题而生。它的核心理念是:

Tool 独立于 LLM,通过标准化协议实现本地/远程、跨进程、跨语言的调用。


2. MCP 协议是什么?

2.1 定义

MCP(Model Context Protocol,模型上下文协议) 是一种标准化 LLM 与外部工具和资源之间通信的协议。它的目标是:

  • 解耦 LLM 和 Tool,让工具可以独立开发、独立部署、跨项目复用。
  • 为 Model 扩展 Context(上下文),让它能做更多(Tool)、知道更多(Resource)。 80cb203e71e84458bc19a715950940c5.png

2.2 MCP 的定位

MCP 不是一种 API 调用方式,它和传统的 HTTP Fetch 有本质区别:

对比维度传统 API 调用 (Fetch)MCP 协议
目的获取接口数据扩展 LLM 的 Context(Tool & Resource)
通信方式单向请求-响应双向、持久化的进程通信
标准化每个 API 有自己的规范统一的协议标准
跨语言需要各自实现 HTTP 客户端基于 stdio/HTTP,天然跨语言

简而言之,MCP 的目标是:不管是本地工具还是远程工具,Agent 想跨进程调用某个工具,通过 MCP 协议就行。


3. MCP 的核心特点

3.1 跨进程调用

MCP 最大的特点就是跨进程调用工具:

  • 本地跨进程 → 使用 stdio(标准输入输出流)
  • 远程跨进程 → 使用 HTTP

MCP 跨进程通信转存失败,建议直接上传图片文件

3.2 架构角色

在 MCP 的架构中,有三个关键角色:

角色说明
MCP Host(宿主)AI Agent 本身,作为 MCP 客户端,发起工具调用请求
MCP Client(客户端)与 MCP Server 建立连接,管理通信通道
MCP Server(服务端)提供具体的 Tool 和 Resource,响应客户端请求

一个 AI Agent(MCP Host)可以通过配置多个 MCP Client,连接到不同的 MCP Server,实现跨进程工具调用。

3.3 通信原理

基于 stdio(标准输入输出流) 的通信原理:

  • 键盘输入 → 控制台输出
  • 当一个进程(Agent)调用子进程(如 node child_process)时,通过 stdio 标准输入输出流来实现通信
  • 对于远程场景,MCP 同样支持基于 HTTP 的通信方式

4. 项目实战:构建一个 MCP Server

下面我们通过 mcp-demo 项目,从零开始构建一个完整的 MCP Server。

4.1 项目初始化

首先来看项目的 package.json 配置:

{
  "name": "mcp-demo",
  "version": "1.0.0",
  "description": "MCP Demo 项目",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@langchain/core": "^1.2.3",
    "@langchain/mcp-adapters": "^1.1.3",
    "@langchain/openai": "^1.5.5",
    "@modelcontextprotocol/sdk": "^1.29.0",
    "chalk": "^5.6.2",
    "zod": "^4.4.3"
  }
}

4.2 核心依赖解析

项目依赖几个关键包,各司其职:

依赖包作用
@modelcontextprotocol/sdkMCP 官方 SDK,提供 McpServerStdioServerTransport 等核心 API
@langchain/mcp-adaptersLangChain 的 MCP 适配器,让 Agent 能以 MCP Client 身份连接 MCP Server
@langchain/coreLangChain 核心库,提供消息类型(HumanMessage、ToolMessage 等)
@langchain/openaiLangChain 的 OpenAI 兼容接口,用于连接 DeepSeek 等 LLM
zodTypeScript 优先的 Schema 声明与验证库,用于定义 Tool 的输入参数 Schema
chalk终端彩色输出工具,用于美化命令行日志

229ba4ac60a54f05b2dbeda638dfbcf2.png

4.3 MCP Server 代码详解

下面我们逐段解析 src/my-mcp-server.mjs 的实现:

4.3.1 导入依赖

import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { z } from 'zod';

关键点:

  • McpServer:MCP 服务端的核心类,用于创建服务器实例、注册工具。
  • StdioServerTransport:基于标准输入输出流的传输层,实现跨进程通信
  • z(Zod):用于声明和验证工具参数的数据结构。

4.3.2 定义数据源

// 假数据,未来可以走数据库
const database = {
    users: {
        '001': { id: '001', name: '张三', email: 'zs@qq.com', role: 'admin' },
        '002': { id: '002', name: '李四', email: 'ls@qq.com', role: 'user' },
        '003': { id: '003', name: '王五', email: 'wu@qq.com', role: 'user' },
    }
}

这里使用内存中的静态数据模拟数据库。在实际项目中,这里可以替换为真实的数据库连接(MySQL、PostgreSQL、MongoDB 等)。这正是 MCP 的优势所在:工具的实现细节对 LLM 完全透明

4.3.3 创建 MCP Server 实例

const server = new McpServer({
    name: 'my-mcp-server',
    version: '1.0.0',
});

每个 MCP Server 都有自己的名称版本号,这是 MCP 协议规范的一部分,便于 MCP Client 识别和管理多个 Server。

4.3.4 注册工具(Tool)

server.registerTool('query-user', {
    description: `查询数据库中的用户信息。输入用户ID,返回该用户的详细信息(姓名、邮箱、角色)`,
    inputSchema: {
        user_id: z.string().describe('用户ID,例如:001,002,003')
    }
}, async (userId) => {
    const user = database.users[userId];
    if (!user) {
        return {
            content: [
                { type: 'text', text: `用户 ID ${userId} 不存在。可用的ID:001, 002, 003` }
            ]
        }
    }
    return {
        content: [
            {
                type: 'text',
                text: `用户 ${user.id}的信息是:
                    姓名:${user.name},邮箱:${user.email},角色:${user.role}`
            }
        ]
    }
})

这是 MCP Server 的核心registerTool 方法接收三个参数:

参数说明
工具名称 ('query-user')Tool 的唯一标识符,LLM 通过名称来调用工具
工具元数据包含 description(描述,供 LLM 理解工具用途)和 inputSchema(输入参数的 Zod Schema,供 LLM 知道如何传参)
处理函数异步函数,接收参数并返回执行结果,结果以 { content: [...] } 格式返回

关键设计思想:

  • description 是写给 LLM 看的 —— LLM 通过描述来判断何时调用该工具。
  • inputSchema 使用 Zod 定义,LLM 根据 Schema 生成结构化的参数。
  • 返回值遵循 MCP 协议的 content 格式,支持多种内容类型(text、image 等)。

4.3.5 启动传输层

// 跨进程通信方式 stdio
const transport = new StdioServerTransport();
await server.connect(transport);

这是整个 Server 的最后一步,也是最关键的一步:

  • StdioServerTransport() 创建一个基于标准输入输出流的传输层。
  • server.connect(transport) 将 Server 绑定到该传输层,开始监听来自 MCP Client 的请求。

这意味着: 任何能够启动子进程并与其 stdio 通信的程序(Node.js、Python、Java、Rust 等),都可以作为 MCP Client 来调用这个 Server 中的工具。这就是 MCP 跨语言、跨进程的核心实现。


5. MCP 的通信机制

5.1 Stdio 通信模型

┌──────────────┐    stdin    ┌──────────────┐
│              │  ─────────> │              │
│  MCP Client  │             │  MCP Server  │
│  (Agent)     │  <───────── │  (Tool 提供) │
│              │    stdout   │              │
└──────────────┘             └──────────────┘
  1. MCP Client(Agent 端)通过 child_process 启动 MCP Server 子进程。
  2. Client 通过 stdin 向 Server 发送 JSON-RPC 格式的请求(如:调用工具 query-user,参数 {user_id: "001"})。
  3. Server 处理请求后,通过 stdout 返回 JSON-RPC 格式的响应。
  4. Client 接收响应,将其传递给 LLM 进行下一步推理。

5.2 HTTP 通信模型

对于远程工具调用,MCP 同样支持基于 HTTP 的传输方式,允许 Agent 调用部署在远程服务器上的工具。

80cb203e71e84458bc19a715950940c5.png


6. MCP Tool 的本质

在 MCP 的视角下,Tool 的本质可以概括为:

Tool = 描述(Description) + 输入约束(Input Schema) + 执行逻辑(Handler)

组成部分作用面向对象
Description用自然语言描述工具的功能面向 LLM,让模型理解何时使用
Input Schema用结构化 Schema 定义输入参数面向 LLM,让模型知道如何传参
Handler实际的业务逻辑代码面向 开发者,执行真实的操作

这种设计将 语义层(给 LLM 看)和 执行层(给机器跑)清晰地分离开来,实现了 LLM 与 Tool 的彻底解耦。


7. 总结与展望

7.1 本文要点回顾

  1. MCP 解决了什么问题? —— Tool 无法跨项目复用、跨语言调用的痛点。
  2. MCP 是什么? —— 一种标准化 LLM 与 Tool/Resource 通信的协议,核心是解耦扩展 Context
  3. MCP 的核心特点 —— 跨进程调用(本地 stdio + 远程 HTTP)。
  4. 如何构建 MCP Server? —— 使用 @modelcontextprotocol/sdk,通过 McpServer + registerTool + StdioServerTransport 三步即可完成。
  5. Tool 的本质 —— Description + Input Schema + Handler 三位一体。

7.2 未来展望

MCP 作为 AI Agent 生态的关键基础设施,未来有望在以下方向持续发展:

  • 多语言 SDK 生态 —— 随着 Python、Java、Rust 等语言的 SDK 成熟,跨语言工具调用将更加便捷。
  • 工具市场(Tool Marketplace) —— 标准化的 MCP Server 可以被发布和共享,形成类似 npm/PyPI 的工具生态。
  • 企业级 MCP 网关 —— 统一管理、鉴权、监控企业内部的各种 MCP Server。
  • 与 Agent 框架深度集成 —— LangChain、AutoGen、CrewAI 等框架将 MCP 作为一等公民支持。