模型上下文协议(MCP)


一、核心概念:什么是 MCP?

一句话:MCP 是 LLM 与外部系统的"通用适配器",让任何 LLM 都能无缝连接任何外部工具、数据库或 API。

打个比方

  • 工具函数调用:像给 AI 配一套专用工具(特定扳手和螺丝刀),适合固定任务
  • MCP:像通用电源插座系统,允许任何合规工具接入,打造动态可扩展的工作坊

MCP 的本质:开放标准协议,规范 Gemini、GPT、Claude 等 LLM 与外部系统的通信方式。

⚠️ 重要提醒:MCP 效果高度依赖底层 API 的设计质量!

  • ❌ 只是简单包装传统 API → 智能体表现差
  • ✅ 底层 API 支持过滤、排序等确定性特性 → 智能体高效工作
  • ❌ API 返回 PDF 等不可解析格式 → 无意义
  • ✅ API 返回文本(Markdown)→ 智能体可直接处理

二、MCP vs 工具函数调用

特性 工具函数调用 MCP
标准化 专有、厂商定制 开放标准协议
范围 LLM 直接请求某个预定义函数 LLM 与外部工具的通用框架
架构 一对一交互 客户端-服务器架构
发现机制 需显式告知 LLM 可用工具 支持动态发现
复用性 与应用和 LLM 高度耦合 可复用、独立的 MCP 服务器

三、MCP 架构详解

3.1 四大组件

用户请求
    ↓
┌─────────┐     ┌─────────────┐     ┌─────────────┐     ┌─────────────┐
│   LLM   │ ←→  │ MCP 客户端   │ ←→  │ MCP 服务器   │ ←→  │ 第三方服务   │
│ (核心)   │     │ (应用包装层) │     │ (能力暴露层) │     │ (实际执行层) │
└─────────┘     └─────────────┘     └─────────────┘     └─────────────┘
组件 角色 说明
LLM 核心 Agent 处理请求、制定计划、决定何时访问外部
MCP 客户端 翻译官 将 LLM 意图转化为 MCP 标准请求
MCP 服务器 门卫 暴露工具/资源/Prompt,认证和校验请求
第三方服务 执行者 实际执行操作(数据库查询、发邮件等)

3.2 五步交互流程

1. 发现 → 客户端查询服务器能力,获取工具/资源/Prompt 清单
2. 请求构造 → LLM 决定使用某工具,构造请求参数
3. 客户端通信 → 客户端按标准格式发送请求到服务器
4. 服务器执行 → 认证 → 校验 → 调用底层软件
5. 响应与更新 → 标准化响应返回 → 更新 LLM 上下文 → 继续任务

3.3 三大能力类型

类型 说明 示例
资源(Resources) 静态数据 PDF、数据库记录、文件内容
工具(Tools) 可执行功能 发邮件、API 查询、文件操作
Prompt 交互模板 引导 LLM 与资源/工具的结构化交互

四、源码解构:ADK 连接 MCP 文件系统服务器

4.1 智能体配置

import os
from google.adk.agents import LlmAgent
from google.adk.tools.mcp_tool.mcp_toolset import MCPToolset, StdioServerParameters

# 文件操作根目录
TARGET_FOLDER_PATH = os.path.join(
    os.path.dirname(os.path.abspath(__file__)), "mcp_managed_files"
)
os.makedirs(TARGET_FOLDER_PATH, exist_ok=True)

root_agent = LlmAgent(
    model='gemini-2.0-flash',
    name='filesystem_assistant_agent',
    instruction=(
        '帮助用户管理文件。你可以列出、读取和写入文件。'
        f' 你的操作目录为:{TARGET_FOLDER_PATH}'
    ),
    tools=[
        MCPToolset(
            connection_params=StdioServerParameters(
                command='npx',                    # 使用 npx 运行 Node.js 包
                args=[
                    "-y",
                    "@modelcontextprotocol/server-filesystem",  # MCP 文件系统服务器
                    TARGET_FOLDER_PATH,          # 限制操作范围
                ],
            ),
            # 可选:限制暴露的工具
            # tool_filter=['list_directory', 'read_file']
        )
    ],
)

源码解读

  • StdioServerParameters:通过 STDIO(标准输入输出)启动 MCP 服务器进程
  • command='npx':使用 npm 自带的包执行工具,无需全局安装
  • @modelcontextprotocol/server-filesystem:社区提供的文件系统 MCP 服务器
  • TARGET_FOLDER_PATH:限制文件操作范围,安全措施
  • tool_filter:可选,限制智能体只能使用特定工具(最小权限原则)

4.2 连接其他类型的服务器

# 连接 Python MCP 服务器
connection_params = StdioConnectionParams(
    server_params={
        "command": "python3",
        "args": ["./agent/mcp_server.py"],
        "env": {                            # 环境变量传递
            "SERVICE_ACCOUNT_PATH": "...",
            "DRIVE_FOLDER_ID": "..."
        }
    }
)

# 使用 UVX 运行 Python MCP 包
connection_params = StdioConnectionParams(
    server_params={
        "command": "uvx",                   # Python 的 npx 等价物
        "args": ["mcp-google-sheets@latest"],
        "env": {
            "SERVICE_ACCOUNT_PATH": "...",
            "DRIVE_FOLDER_ID": "..."
        }
    }
)

源码解读

  • StdioConnectionParams:STDIO 方式连接(本地进程间通信)
  • env:环境变量传递,用于认证等敏感信息
  • npx vs uvx:npx 运行 Node.js 包,uvx 运行 Python 包

五、源码解构:FastMCP 创建自定义 MCP 服务器

5.1 服务端

# fastmcp_server.py
from fastmcp import FastMCP

mcp_server = FastMCP()

@mcp_server.tool
def greet(name: str) -> str:
    """
    生成个性化问候语。

    Args:
        name: 要问候的人名。

    Returns:
        问候语字符串。
    """
    return f"你好,{name}!很高兴认识你。"

if __name__ == "__main__":
    mcp_server.run(
        transport="http",
        host="127.0.0.1",
        port=8000
    )

源码解读

  • @mcp_server.tool:装饰器将 Python 函数注册为 MCP 工具
  • 文档字符串和类型提示会被 FastMCP 自动用于工具描述和接口规范
  • transport="http":使用 HTTP 传输(远程连接),而非 STDIO(本地连接)
  • 服务启动后监听 8000 端口,任何 MCP 客户端都可连接

5.2 客户端(ADK Agent 消费 FastMCP)

# ./adk_agent_samples/fastmcp_client_agent/agent.py
from google.adk.agents import LlmAgent
from google.adk.tools.mcp_tool.mcp_toolset import MCPToolset, HttpServerParameters

FASTMCP_SERVER_URL = "http://localhost:8000"

root_agent = LlmAgent(
    model='gemini-2.0-flash',
    name='fastmcp_greeter_agent',
    instruction='你是一个友好的助手,可以通过 "greet" 工具向人问好。',
    tools=[
        MCPToolset(
            connection_params=HttpServerParameters(
                url=FASTMCP_SERVER_URL,     # HTTP 方式连接远程 MCP 服务器
            ),
            tool_filter=['greet']           # 只允许使用 greet 工具
        )
    ],
)

源码解读

  • HttpServerParameters:通过 HTTP 连接远程 MCP 服务器(vs StdioServerParameters 本地连接)
  • tool_filter=['greet']:最小权限原则,只暴露需要的工具
  • Agent 的 LLM 会自动识别 MCP 提供的工具描述,决定何时调用

5.3 两种传输机制对比

机制 参数类 适用场景 通信方式
STDIO StdioServerParameters 本地、敏感数据、高性能 JSON-RPC over STDIO
HTTP HttpServerParameters 远程、组织共享、可扩展 Streamable HTTP + SSE

六、九大应用场景

场景 说明
数据库集成 自然语言查询 BigQuery,实时获取信息
生成式媒体 调用 Imagen(图片)、Veo(视频)、Lyria(音乐)
外部 API 交互 天气、股票、邮件、CRM 标准化接入
推理型信息抽取 LLM 推理 + MCP 数据,精准提取关键信息
自定义工具开发 FastMCP 快速开发,无需修改 LLM
标准化通信 不同厂商 LLM 与工具互操作
复杂流程编排 组合多种 MCP 工具实现多步骤自动化
IoT 设备控制 自然语言控制智能家居、工业传感器
金融服务自动化 市场分析、自动交易、合规报告

七、关键要点

  1. MCP 是开放标准:不是某个厂商的专有技术,任何合规 LLM 和工具都可接入
  2. 客户端-服务器架构:标准化信息流,LLM 通过客户端发现和调用服务器暴露的能力
  3. 三大能力:资源(静态数据)、工具(可执行功能)、Prompt(交互模板)
  4. 动态发现:智能体无需重启即可适应新功能
  5. 底层 API 质量是关键:MCP 只是接口,真正的效果取决于底层 API 的设计
  6. 两种传输机制:STDIO(本地高性能)vs HTTP(远程可扩展)
  7. FastMCP 简化开发:装饰器 + 类型提示 + 文档字符串 → 自动生成 MCP 工具
  8. 安全考虑:认证授权、tool_filter 最小权限、环境变量传递敏感信息

八、与前几章的联系

模式 与 MCP 的关系
工具使用(Ch5) MCP 是工具调用的标准化升级版
多智能体(Ch7) MCP 让多智能体共享工具生态
记忆管理(Ch8) MCP 可连接外部知识库作为长期记忆
A2A(Ch15) MCP 连接工具,A2A 连接智能体,互补关系
Logo

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

更多推荐