目录

        一、什么是 MCP

1.1 定义

1.2 为什么需要 MCP

1.3 核心架构:Client-Host-Server 模型

1.4 MCP 协议层详解

1.5 服务端三大原语:Tools、Resources、Prompts

二、Function Call 与 MCP 的区别(面试重点)

2.1 两者定义

2.2 多维度对比

2.3 两者关系

三、MCP 生态:主流平台与市场

四、Cherry Studio 中使用 MCP

4.1 基本流程

4.2 高德地图 MCP 配置示例

五、MCP 的通信传输方式

5.1 stdio(标准输入/输出)

5.2 SSE(Server-Sent Events)

5.3 Streamable HTTP(可流式 HTTP)

5.4 三种方式对比总结

六、MCP 初始化与生命周期

阶段一:初始化(Initialize)

阶段二:运行(Operation)

阶段三:关闭(Shutdown)

七、实战:编写 MCP 服务器

7.1 准备工作

7.1 stdio 模式

7.2 SSE 模式

7.3 Streamable HTTP 模式

7.4 注册 Resource 与 Prompt

八、实战:编写 MCP 客户端

8.1 安装依赖

8.1 stdio 方式连接

8.2 SSE 方式连接

8.3 Streamable HTTP 方式连接

8.4 同时连接多个 MCP Server

九、总结与展望

核心要点回顾

适用场景

未来展望


一、什么是 MCP

1.1 定义

MCP(Model Context Protocol,模型上下文协议) 是由 Anthropic 于 2024 年 11 月底 推出的一种开放标准协议,旨在为大语言模型(LLM)提供统一的、标准化的方式与外部数据源和工具之间进行通信。

官方将 MCP 类比为 "AI 应用的 USB-C 接口"——正如 USB-C 为电子设备提供了统一的连接方式,MCP 为 AI 应用与外部系统之间提供了标准化的连接协议。

MCP 的核心目标是让 LLM 跳出静态知识库的限制,能够 主动、实时地获取外部数据、调用外部工具,从而将 AI 的能力从"对话"延伸到"行动"。

┌─────────────────────────────────────────────────┐
│                   MCP 架构全景                     │
│                                                   │
│  ┌──────────┐    ┌──────────┐    ┌──────────────┐│
│  │  数据源   │◄──►│ MCP 服务 │◄──►│   AI 应用    ││
│  │(数据库/   │    │  Server  │    │  (Host端)    ││
│  │ 文件/API) │    └──────────┘    └──────────────┘│
│  └──────────┘          ▲                ▲         │
│                        │                │         │
│                   MCP 协议层        MCP 客户端     │
│                  (JSON-RPC 2.0)    (嵌入Host中)    │
└─────────────────────────────────────────────────┘

1.2 为什么需要 MCP

传统 AI 集成面临的问题:

问题 描述
架构碎片化 每接入一个外部服务,就需要一套独立的集成代码,N 个服务对应 N 套代码
难以扩展 新增工具或数据源需要重新开发适配层,维护成本高
上下文受限 模型只能依赖训练数据和有限的 prompt 内容,无法访问实时外部信息
缺乏标准 各厂商各做各的集成方案,互不兼容

MCP 的解决方案:

  • 提供 统一的协议规范,一次接入,处处可用
  • 支持 动态发现和调用工具,无需提前硬编码
  • 实现 标准化的双向通信,模型既能读取数据也能执行操作
  • 开放生态,任何人可以开发 MCP Server 并被任意 MCP Client 调用

1.3 核心架构:Client-Host-Server 模型

MCP 采用三层架构设计,各角色职责清晰:

┌──────────────────────────────────────────────────────────┐
│                        Host(宿主应用)                     │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐       │
│  │ MCP Client  │  │ MCP Client  │  │ MCP Client  │       │
│  │     #1      │  │     #2      │  │     #3      │       │
│  └──────┬──────┘  └──────┬──────┘  └──────┬──────┘       │
│         │                │                │               │
└─────────┼────────────────┼────────────────┼───────────────┘
          │                │                │
          ▼                ▼                ▼
   ┌─────────────┐  ┌─────────────┐  ┌─────────────┐
   │ MCP Server  │  │ MCP Server  │  │ MCP Server  │
   │    (本地)    │  │   (远程)    │  │   (远程)    │
   └──────┬──────┘  └──────┬──────┘  └──────┬──────┘
          │                │                │
          ▼                ▼                ▼
   ┌─────────────┐  ┌─────────────┐  ┌─────────────┐
   │  本地文件/   │  │  远程API/   │  │  数据库/    │
   │  CLI 工具    │  │  云服务     │  │  第三方服务  │
   └─────────────┘  └─────────────┘  └─────────────┘
  • Host(宿主):AI 应用本身(如 Claude Desktop、Cherry Studio、自定义 Agent 程序),负责管理整体交互流程和安全策略
  • MCP Client(客户端):嵌入在 Host 内部,每个 Client 与一个 MCP Server 建立一对一连接,负责协议层面的消息收发
  • MCP Server(服务端):轻量级程序,对外暴露 Tools、Resources、Prompts 三类能力,通过标准化协议被 Client 调用

1.4 MCP 协议层详解

MCP 底层通信基于 JSON-RPC 2.0 协议,所有消息都遵循请求-响应模式:

// 请求示例
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "add",
    "arguments": { "a": 5, "b": 3 }
  }
}

// 响应示例
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "content": [
      { "type": "text", "text": "8" }
    ]
  }
}

MCP 支持三种消息类型:

消息类型 方向 说明
Request(请求) 双向 期望对方返回响应,包含 idmethodparams
Response(响应) 双向 对请求的应答,包含 idresulterror
Notification(通知) 双向 单向消息,不需要响应,无 id 字段

1.5 服务端三大原语:Tools、Resources、Prompts

MCP Server 对外暴露三种标准化能力原语:

原语 控制方 描述 类比
Tools 模型控制 可执行的函数/操作,由 LLM 自主决定何时调用 函数调用(Function Call)
Resources 应用控制 可读取的数据源,由应用程序决定如何使用 GET 请求获取数据
Prompts 用户控制 预定义的提示词模板,由用户主动选择触发 快捷指令/模板
  • Tools 是最常用的能力,例如"查询天气"、"发送邮件"、"操作数据库"
  • Resources 类似于只读数据接口,例如"读取配置文件"、"获取数据库 schema"
  • Prompts 是可复用的提示词模板,例如"代码审查模板"、"数据分析模板"

二、Function Call 与 MCP 的区别(面试重点)

这是高频面试题,需要从多个维度理解两者的差异。

2.1 两者定义

Function Call 是大模型自带的一种能力,允许模型在对话过程中决定是否需要调用外部函数,并自动生成结构化的调用参数(函数名 + JSON 参数)。通常在本地代码中直接执行。

MCP 是一种标准化的通信协议,定义了 AI 应用与外部工具/服务之间如何发现、调用和交互。可以跨进程、跨系统、跨网络。

2.2 多维度对比

维度 Function Call MCP
本质 模型的一种能力 一套通信协议标准
定位 "模型如何发起调用" "系统之间如何规范调用"
偏重 模型能力层 工程架构层
调用方式 通常本地执行 支持本地和远程调用
标准化程度 各厂商实现不同(OpenAI、Anthropic、Google 各有差异) 统一的协议规范
工具发现 需要在 prompt 中预定义函数 schema Server 自动注册,Client 动态发现
跨系统 难以跨进程/跨网络 原生支持分布式调用
生态复用 函数定义与具体应用绑定 一个 Server 可被任意 Client 复用
协议基础 无统一协议 基于 JSON-RPC 2.0

2.3 两者关系

MCP 并非要替代 Function Call,而是在其之上构建了更完整的工程化方案:

┌──────────────────────────────────────────────┐
│              AI 应用 (Host)                    │
│  ┌────────────────────────────────────────┐   │
│  │        大语言模型 (LLM)                 │   │
│  │   ┌──────────────────────────┐        │   │
│  │   │   Function Call 能力     │        │   │
│  │   │  (模型决定调用哪个工具)    │        │   │
│  │   └────────────┬─────────────┘        │   │
│  └────────────────┼──────────────────────┘   │
│                   ▼                           │
│  ┌────────────────────────────────────────┐   │
│  │     MCP Client / MCP Protocol          │   │
│  │   (标准化的调用通道与工具发现)           │   │
│  └────────────────┬──────────────────────┘   │
└───────────────────┼──────────────────────────┘
                    ▼
           ┌─────────────────┐
           │   MCP Server    │
           │ (标准化工具服务)  │
           └─────────────────┘

简单来说:Function Call 负责"决定调用",MCP 负责"规范执行"。在实际应用中,模型通过 Function Call 机制识别到需要调用工具,然后通过 MCP 协议去标准化地调用对应的 MCP Server。


三、MCP 生态:主流平台与市场

截至目前,MCP 生态已初具规模,以下是主要的 MCP 资源平台:

平台 地址 说明
Model Context Protocol 官网 https://modelcontextprotocol.io 官方文档与规范定义
MCP.so https://mcp.so/ 社区驱动的 MCP Server 聚合平台
Smithery https://smithery.ai/ MCP 工具市场,支持自动化 OAuth 认证,提供 CLI 工具链
魔搭社区(ModelScope) https://www.modelscope.cn/mcp 阿里达摩院的 MCP 市场,中文生态友好
MCP Marketplace https://mcp.higress.ai/ 阿里云 Higress 提供的 MCP 市场
Glama https://glama.ai/mcp/servers MCP Server 目录与搜索平台
PulseMCP https://www.pulsemcp.com/ MCP 生态新闻与 Server 目录
Cline Marketplace https://cline.bot/mcp-marketplace Cline 编程助手内置的 MCP 市场

Smithery 使用示例(CLI 工具链):

# 登录认证
npx smithery auth login

# 添加 MCP 服务(以 Notion 为例,会触发 OAuth 授权流程)
npx smithery mcp add notion
# → auth_required
# → https://auth.smithery.ai/...
# 访问授权 URL 完成认证

# 列出可用工具
npx smithery tool list

# 调用工具
npx smithery tool call \
  notion notion-create-pages \
  '{"pages": [{"properties": {"title": "Q4 Investor Update"}}]}'

Smithery 的核心优势是 "Zero auth plumbing"——当请求需要认证时,它自动处理 OAuth 流程、凭证注入和重试,开发者无需编写任何认证代码。


四、Cherry Studio 中使用 MCP

Cherry Studio 是一款支持 MCP 协议的 AI 桌面客户端,可以零代码地配置和使用 MCP Server。

4.1 基本流程

第一步:下载并注册

前往 https://www.cherry-ai.com/download 下载最新版本(当前 v1.9.5),完成注册和登录。

第二步:配置大模型

在设置中配置你的 LLM API Key 和模型信息(支持 OpenAI、Anthropic 等多种模型提供商)。

第三步:配置 MCP 环境

在 Cherry Studio 的 MCP 设置面板中,可以通过以下两种方式添加 MCP Server:

  • 手动配置:直接填写 MCP Server 的启动命令或连接地址
  • JSON 导入:粘贴 MCP Server 的 JSON 配置文件,一键导入

第四步:高德地图实战示例

  1. 1.前往 https://lbs.amap.com/ 注册并申请 API Key
  2. 2.在 Cherry Studio 中配置高德地图的 MCP Server 地址
  3. 3.在对话中直接使用自然语言查询地址、搜索附近美食等

4.2 高德地图 MCP 配置示例

在 Cherry Studio 的 MCP 配置中,添加如下 JSON 配置:

{
  "mcpServers": {
    "amap": {
      "command": "npx",
      "args": [
        "-y",
        "@amap/amap-maps-mcp-server"
      ],
      "env": {
        "AMAP_MAPS_API_KEY": "你的高德API密钥"
      }
    }
  }
}

配置完成后,在对话中即可直接提问,例如:

  • "帮我查一下北京市朝阳区望京SOHO的具体地址"
  • "搜索我附近的火锅店"
  • "从北京南站到首都机场怎么走"

五、MCP 的通信传输方式

MCP 的传输层与协议层是解耦的。协议层统一使用 JSON-RPC 2.0,传输层则可根据场景选择不同方式。目前官方支持三种传输机制:

5.1 stdio(标准输入/输出)

类型:经典的进程间通信(IPC)方式

工作原理

┌────────────────┐         stdin/stdout        ┌────────────────┐
│  MCP Client    │  ◄───── (管道) ─────►        │  MCP Server    │
│  (父进程)      │                              │  (子进程)      │
└────────────────┘                              └────────────────┘
                   不经过网络,本地直连
  • 客户端将 MCP Server 启动为一个 子进程
  • 通过 stdin(标准输入) 向服务端发送请求
  • 通过 stdout(标准输出) 接收服务端响应
  • 整个过程 不经过网络,完全在本地完成
  • stderr 用于传输日志等诊断信息

适用场景

  • 本地开发和调试
  • 将 CLI 工具快速封装为 MCP Server
  • 对安全性要求高、不希望暴露网络端口的场景

一句话理解:本地进程之间的"直接对话",简单高效。

5.2 SSE(Server-Sent Events)

类型:基于 HTTP 的单向流式推送协议

工作原理

┌────────────┐                          ┌────────────┐
│ MCP Client │ ──── HTTP GET /sse ────► │ MCP Server │
│            │ ◄── text/event-stream ── │            │
│            │                          │            │
│            │ ──── HTTP POST /msg ───► │            │
└────────────┘                          └────────────┘
  1. 1.客户端通过 HTTP GET 请求连接到服务端的 SSE 端点(通常为 /sse
  2. 2.服务端保持连接不断开,以 text/event-stream 格式持续推送数据
  3. 3.客户端需要发送消息时,通过单独的 HTTP POST 请求发送到 /message 端点

特点

  • 服务端到客户端的推送是 持续的、单向的流
  • 客户端到服务端需要通过 额外的 HTTP POST 请求
  • 基于标准 HTTP,天然支持跨网络和跨域

适用场景

  • 分布式系统
  • 远程 MCP Server 调用
  • 需要流式输出的场景(如 AI 逐字生成)

一句话理解:服务器不断"推消息"给客户端。

注意:SSE 传输方式已被 MCP 官方标记为 deprecated(弃用),推荐使用 Streamable HTTP 替代。但对于已有的 Server 实现,SSE 仍然被广泛支持。

5.3 Streamable HTTP(可流式 HTTP)

类型:基于 HTTP 的双向流式通信方式

工作原理

┌────────────┐                              ┌────────────┐
│ MCP Client │ ──── HTTP POST /mcp ───────► │ MCP Server │
│            │ ◄── JSON 或 SSE 响应 ──────── │            │
│            │                              │            │
│            │ ──── GET /mcp (可选) ───────► │            │
│            │ ◄── SSE 流式推送 ──────────── │            │
└────────────┘                              └────────────┘
  • 客户端通过 HTTP POST 到 /mcp 端点发送请求
  • 服务端可返回 普通 JSON 响应SSE 流式响应
  • 支持通过 GET 请求建立可选的 SSE 连接,用于服务端主动推送(如通知)
  • 一个端点处理所有通信,简化了部署

特点

  • 支持 双向通信
  • 不限于 SSE 格式,支持灵活的数据格式
  • 无状态友好,便于水平扩展和负载均衡
  • 是 MCP 传输层的 未来推荐方案

适用场景

  • 分布式应用
  • AI 服务的远程调用
  • Agent / MCP 远程工具链

一句话理解:可以"边问边答"的 HTTP 通信,最灵活、最通用。

5.4 三种方式对比总结

特性 stdio SSE Streamable HTTP
通信方向 双向(管道) 服务端单向推 + 客户端 POST 双向
网络支持 仅本地 支持远程 支持远程
协议基础 stdin/stdout HTTP HTTP
流式支持
状态管理 有状态 有状态 无状态友好
部署复杂度
扩展性 差(单机) 一般
推荐程度 本地开发首选 已 deprecated 官方推荐

六、MCP 初始化与生命周期

MCP 客户端与服务端之间有一个规范化的 连接生命周期,分为三个阶段:

 ┌─────────────┐     ┌─────────────┐     ┌─────────────┐
 │  初始化阶段  | ────►│  运行阶段    │────►│  关闭阶段     │
 │(Initialize) │     │ (Operation) │     │  (Shutdown) │
 └─────────────┘     └─────────────┘     └─────────────┘

阶段一:初始化(Initialize)

Client                          Server
  │                                │
  │ ──── initialize 请求 ────────► │  (发送协议版本和客户端能力)
  │                                │
  │ ◄─── initialize 响应 ──────── │  (返回服务端能力)
  │                                │
  │ ──── initialized 通知 ───────► │  (确认初始化完成)
  │                                │

双方在此阶段进行 能力协商(Capability Negotiation)

// 客户端发送的 initialize 请求
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "initialize",
  "params": {
    "protocolVersion": "2025-03-26",
    "capabilities": {
      "tools": {},
      "sampling": {}
    },
    "clientInfo": {
      "name": "MyAgent",
      "version": "1.0.0"
    }
  }
}

// 服务端返回的 initialize 响应
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "protocolVersion": "2025-03-26",
    "capabilities": {
      "tools": { "listChanged": true },
      "resources": { "subscribe": true },
      "prompts": { "listChanged": true }
    },
    "serverInfo": {
      "name": "Demo",
      "version": "1.0.0"
    }
  }
}

阶段二:运行(Operation)

初始化完成后,客户端与服务端进入正常交互阶段:

  • 客户端可以调用 tools/listresources/listprompts/list 来发现服务端提供的能力
  • 客户端可以通过 tools/call 调用工具
  • 服务端可以通过通知(Notification)告知客户端能力变化

阶段三:关闭(Shutdown)

任何一方都可以发起关闭,通常是客户端发起:

Client                          Server
  │                                │
  │ ──── close 通知 ─────────────►  │
  │                                │
  │      连接关闭,释放资源           │

七、实战:编写 MCP 服务器

7.1 准备工作

# 安装 MCP Python SDK
pip install mcp

7.1 stdio 模式

这是最简单的入门方式,MCP Server 作为本地子进程运行。

文件:mcp_server_stdio.py

from mcp.server.fastmcp import FastMCP

# 创建一个 FastMCP 实例,参数为服务名称
mcp = FastMCP("Demo")


# ── 注册工具(Tools) ──────────────────────────────────

@mcp.tool()
def add(a: int, b: int) -> int:
    """计算两个数的和"""
    return a + b


@mcp.tool()
def mul(a: int, b: int) -> int:
    """计算两个数的积"""
    return a * b


@mcp.tool()
def subtract(a: int, b: int) -> int:
    """计算两个数的差"""
    return a - b


@mcp.tool()
def divide(a: float, b: float) -> float:
    """计算两个数的商,除数不能为零"""
    if b == 0:
        raise ValueError("除数不能为零")
    return a / b


if __name__ == "__main__":
    # 以 stdio 模式运行
    mcp.run("stdio")

启动方式

python mcp_server_stdio.py 

7.2 SSE 模式

将 MCP Server 暴露为 HTTP 服务,支持远程调用。

文件:mcp_server_sse.py

from mcp.server.fastmcp import FastMCP

mcp = FastMCP("Demo-SSE")


@mcp.tool()
def add(a: int, b: int) -> int:
    """计算两个数的和"""
    return a + b


@mcp.tool()
def mul(a: int, b: int) -> int:
    """计算两个数的积"""
    return a * b


@mcp.tool()
def greet(name: str) -> str:
    """向指定的人打招呼"""
    return f"你好,{name}!欢迎使用 MCP 服务。"


if __name__ == "__main__":
    # 以 SSE 模式运行,默认监听 0.0.0.0:8000
    mcp.run("sse")

启动方式

python mcp_server_sse.py
# 服务将在 http://0.0.0.0:8000/sse 上监听

7.3 Streamable HTTP 模式

官方推荐的新一代传输方式。

文件:mcp_server_http.py

from mcp.server.fastmcp import FastMCP

mcp = FastMCP("Demo-HTTP")


@mcp.tool()
def add(a: int, b: int) -> int:
    """计算两个数的和"""
    return a + b


@mcp.tool()
def mul(a: int, b: int) -> int:
    """计算两个数的积"""
    return a * b


@mcp.tool()
def calculate_total(items: list[float]) -> float:
    """计算一组金额的总和"""
    return sum(items)


if __name__ == "__main__":
    # 以 Streamable HTTP 模式运行,默认端口 8000,路径 /mcp
    mcp.run("streamable-http")

启动方式

python mcp_server_http.py
# 服务将在 http://0.0.0.0:8000/mcp 上监听

7.4 注册 Resource 与 Prompt

除了 Tools,MCP Server 还可以注册 Resources 和 Prompts:

from mcp.server.fastmcp import FastMCP

mcp = FastMCP("FullDemo")


# ── Tools(工具) ──────────────────────────────────

@mcp.tool()
def add(a: int, b: int) -> int:
    """计算两个数的和"""
    return a + b


# ── Resources(资源) ──────────────────────────────

@mcp.resource("config://app")
def get_config() -> str:
    """返回应用配置信息"""
    return '{"version": "1.0.0", "author": "MCP Demo", "debug": false}'


@mcp.resource("greeting://{name}")
def get_greeting(name: str) -> str:
    """根据用户名返回个性化问候"""
    return f"Hello, {name}! Welcome to the MCP world."


# ── Prompts(提示词模板) ──────────────────────────

@mcp.prompt()
def review_code(code: str) -> str:
    """代码审查提示词模板"""
    return f"""请对以下代码进行审查,关注以下方面:
1. 代码质量与可读性
2. 潜在的 Bug 或边界情况
3. 性能优化建议
4. 安全性问题

待审查代码:
```{code}```
"""


@mcp.prompt()
def analyze_data(data_description: str) -> str:
    """数据分析提示词模板"""
    return f"""请对以下数据进行分析:
数据描述:{data_description}

请提供:
1. 数据概览与关键指标
2. 趋势分析
3. 异常检测
4. 可操作的建议
"""


if __name__ == "__main__":
    mcp.run("stdio")

八、实战:编写 MCP 客户端

客户端使用 langchain-mcp-adapters 库将 MCP Server 的工具无缝集成到 LangChain Agent 中。

8.1 安装依赖

pip install langchain-openai langchain-mcp-adapters langchain langgraph 

8.1 stdio 方式连接

客户端启动 MCP Server 作为子进程,通过 stdin/stdout 通信。

import asyncio
import os

from langchain_core.messages import HumanMessage
from langchain_openai import ChatOpenAI
from langchain_mcp_adapters.client import MultiServerMCPClient
from langgraph.prebuilt import create_react_agent

# 加载环境变量(根据你的项目结构调整)
# from config import load_project_env
# load_project_env()

# 初始化 LLM
my_llm = ChatOpenAI(
    api_key=os.getenv("MODEL_API_KEY"),
    base_url=os.getenv("MODEL_BASE_URL"),
    model=os.getenv("MODEL_NAME"),
)


async def get_agent():
    """创建 Agent,通过 stdio 连接 MCP Server"""
    client = MultiServerMCPClient(
        {
            "demo": {
                "command": "python",          # Python 解释器路径
                "args": ["mcp_server_stdio.py"],  # MCP Server 脚本路径
                "transport": "stdio",
            }
        }
    )

    tools = await client.get_tools()
    print("可用工具:", [tool.name for tool in tools])

    agent = create_react_agent(
        my_llm,
        tools,
    )
    return agent, client


async def chat(user_input: str) -> str:
    """与 Agent 对话"""
    agent, client = await get_agent()
    try:
        state = await agent.ainvoke(
            {"messages": [HumanMessage(content=user_input)]}
        )
        messages = state.get("messages", [])
        if messages:
            return messages[-1].content
        return "未获得结果"
    finally:
        # 关闭客户端连接
        await client.close()


def main():
    print("MCP Client (stdio) 已就绪,输入 exit 退出。")
    while True:
        user_input = input("\n用户: ").strip()
        if user_input.lower() == "exit":
            break
        if not user_input:
            continue
        result = asyncio.run(chat(user_input))
        print(f"助手: {result}")


if __name__ == "__main__":
    main()

8.2 SSE 方式连接

import asyncio
import os

from langchain_core.messages import HumanMessage
from langchain_openai import ChatOpenAI
from langchain_mcp_adapters.client import MultiServerMCPClient
from langgraph.prebuilt import create_react_agent

my_llm = ChatOpenAI(
    api_key=os.getenv("MODEL_API_KEY"),
    base_url=os.getenv("MODEL_BASE_URL"),
    model=os.getenv("MODEL_NAME"),
)


async def get_agent():
    """创建 Agent,通过 SSE 连接远程 MCP Server"""
    client = MultiServerMCPClient(
        {
            "demo": {
                "url": "http://127.0.0.1:8000/sse",
                "transport": "sse",
            }
        }
    )

    tools = await client.get_tools()
    print("可用工具:", [tool.name for tool in tools])

    agent = create_react_agent(my_llm, tools)
    return agent, client


async def chat(user_input: str) -> str:
    agent, client = await get_agent()
    try:
        state = await agent.ainvoke(
            {"messages": [HumanMessage(content=user_input)]}
        )
        messages = state.get("messages", [])
        return messages[-1].content if messages else "未获得结果"
    finally:
        await client.close()


def main():
    print("MCP Client (SSE) 已就绪,输入 exit 退出。")
    while True:
        user_input = input("\n用户: ").strip()
        if user_input.lower() == "exit":
            break
        if not user_input:
            continue
        print(f"助手: {asyncio.run(chat(user_input))}")


if __name__ == "__main__":
    main()

8.3 Streamable HTTP 方式连接

import asyncio
import os

from langchain_core.messages import HumanMessage
from langchain_openai import ChatOpenAI
from langchain_mcp_adapters.client import MultiServerMCPClient
from langgraph.prebuilt import create_react_agent

my_llm = ChatOpenAI(
    api_key=os.getenv("MODEL_API_KEY"),
    base_url=os.getenv("MODEL_BASE_URL"),
    model=os.getenv("MODEL_NAME"),
)


async def get_agent():
    """创建 Agent,通过 Streamable HTTP 连接远程 MCP Server"""
    client = MultiServerMCPClient(
        {
            "demo": {
                "url": "http://127.0.0.1:8000/mcp",
                "transport": "streamable_http",
            }
        }
    )

    tools = await client.get_tools()
    print("可用工具:", [tool.name for tool in tools])

    agent = create_react_agent(my_llm, tools)
    return agent, client


async def chat(user_input: str) -> str:
    agent, client = await get_agent()
    try:
        state = await agent.ainvoke(
            {"messages": [HumanMessage(content=user_input)]}
        )
        messages = state.get("messages", [])
        return messages[-1].content if messages else "未获得结果"
    finally:
        await client.close()


def main():
    print("MCP Client (Streamable HTTP) 已就绪,输入 exit 退出。")
    while True:
        user_input = input("\n用户: ").strip()
        if user_input.lower() == "exit":
            break
        if not user_input:
            continue
        print(f"助手: {asyncio.run(chat(user_input))}")


if __name__ == "__main__":
    main()

8.4 同时连接多个 MCP Server

MultiServerMCPClient 的强大之处在于可以同时连接多个不同类型的 MCP Server:

async def get_agent():
    """同时连接多个 MCP Server"""
    client = MultiServerMCPClient(
        {
            # 本地计算器服务(stdio)
            "calculator": {
                "command": "python",
                "args": ["mcp_server_stdio.py"],
                "transport": "stdio",
            },
            # 远程天气服务(SSE)
            "weather": {
                "url": "http://weather-server.example.com/sse",
                "transport": "sse",
            },
            # 远程数据库服务(Streamable HTTP)
            "database": {
                "url": "http://db-server.example.com/mcp",
                "transport": "streamable_http",
            },
        }
    )

    tools = await client.get_tools()
    print("可用工具:", [tool.name for tool in tools])

    agent = create_react_agent(my_llm, tools)
    return agent, client

九、总结与展望

核心要点回顾

要点 内容
MCP 是什么 AI 应用与外部系统之间的标准化通信协议("AI 的 USB-C")
三层架构 Host(宿主)→ Client(客户端)→ Server(服务端)
三大原语 Tools(工具)、Resources(资源)、Prompts(提示词模板)
协议基础 JSON-RPC 2.0
传输方式 stdio(本地)、SSE(远程,已 deprecated)、Streamable HTTP(远程,推荐)
与 Function Call 关系 Function Call 负责"决定调用",MCP 负责"规范执行",二者互补

适用场景

  • 个人开发:快速为本地 AI 助手接入文件操作、数据库查询、API 调用等能力
  • 企业应用:将内部系统(CRM、ERP、数据仓库)封装为 MCP Server,统一被 AI 应用调用
  • Agent 开发:构建具备复杂工具调用能力的 AI Agent,通过 MCP 协议实现工具的动态发现和编排

未来展望

MCP 生态仍在快速演进中。随着更多厂商和社区的参与,MCP 有望成为 AI 工具调用领域的 事实标准,就像 HTTP 之于 Web、gRPC 之于微服务一样,成为 AI 基础设施的关键一环。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐