Agent MCP

Tool 解决的是"把一个函数暴露给模型调用"。

MCP 解决的是更大一层的问题:把一组工具、资源和提示词,封装成一个标准服务,让不同 Agent 都能接入。

MCP 全称是 Model Context Protocol,可以理解成 Agent 使用外部能力的一套统一协议。

图里的关系可以这样理解:

txt 复制代码
Agent / MCP Client -> MCP 协议 -> MCP Server -> Tools / Resources / Prompts

所以 MCP 不是单个 Tool,而是 Tool 的集合,也可以包含资料和提示词模板。

这一篇主要看这些内容:

txt 复制代码
MCP 是什么
  -> MCP 和 Tool 的关系
  -> MCP Server 的结构
  -> 注册 Tool
  -> 注册 Resource
  -> 注册 Prompt
  -> stdio / HTTP 两种接入
  -> 在 Agent 中使用 MCP

先记住一句话:Tool 是一个能力,MCP Server 是一组能力的标准化服务。

MCP 解决什么问题

如果每个 Agent 都用自己的方式接入工具,会出现很多重复工作:

  • 工具参数格式不统一。
  • 本地工具和远程工具接入方式不同。
  • 不同语言写的工具难以复用。
  • IDE、Agent、脚本都要单独适配一遍。

MCP 的价值就是把这些能力标准化。

只要一个服务遵守 MCP 协议,客户端就可以发现它提供了哪些工具、资源和提示词,并按统一方式调用。

txt 复制代码
没有 MCP:每个 Agent 自己适配每个工具
有 MCP:工具封装成 MCP Server,Agent 按协议接入

这很像 AI 时代的"插件协议"。

MCP 和 Tool 的关系

普通 Tool 通常是在当前进程里定义,并直接绑定给模型。

MCP 则把工具放到一个独立服务里。

txt 复制代码
Tool:一个可调用函数
MCP Server:一组 Tool / Resource / Prompt
MCP Client:连接 MCP Server,并把能力交给 Agent 使用

MCP 最大的特点是跨进程调用。

  • 本地进程:通常用 stdio
  • 远程服务:通常用 HTTP / Streamable HTTP / SSE。

也就是说,Agent 不需要关心工具是用 TypeScript、Python 还是其他语言写的。

只要它是 MCP Server,就可以通过 MCP Client 接入。

MCP Server 的开发流程

开发一个 MCP Server,通常是这个顺序:

txt 复制代码
1. 创建 MCP Server
2. 注册 Tool
3. 注册 Resource
4. 注册 Prompt
5. 选择传输方式
6. 启动服务

其中 Tool 最常用,Resource 和 Prompt 是可选能力。

创建 MCP Server

Python SDK 里可以用 FastMCP 快速创建 MCP Server。

python 复制代码
from mcp.server.fastmcp import FastMCP


mcp = FastMCP("time-helper")

FastMCP 负责管理这个服务暴露出来的能力。

接下来要把工具、资源、提示词注册到这个 server 上。

注册 Tool

Tool 是 MCP 最核心的能力。

下面把"查询当前时间"这个普通工具,组装成 MCP Tool。

python 复制代码
from datetime import datetime
from typing import Annotated
from zoneinfo import ZoneInfo

from pydantic import Field
from mcp.server.fastmcp import FastMCP


mcp = FastMCP("time-helper")


@mcp.tool()
def get_current_time(
    time_zone: Annotated[
        str,
        Field(description="IANA 时区名称,例如 Asia/Shanghai"),
    ],
) -> str:
    """查询指定时区的当前日期和时间。"""

    # 真正执行的逻辑仍然是普通代码
    current_time = datetime.now(ZoneInfo(time_zone))

    return f"{time_zone} 当前时间:{current_time:%Y-%m-%d %H:%M:%S %Z}"

Tool 的关键点:

  • 函数名通常会成为工具名。
  • docstring 通常会成为工具描述,用来帮助模型判断什么时候调用这个工具。
  • 类型标注和 Field(description=...) 会帮助 MCP 生成参数 schema,用来约束模型怎么填写参数。
  • 工具描述和参数 schema 都会影响模型判断,区别是前者更偏"要不要用",后者更偏"怎么用"。
  • 函数体负责真正执行逻辑。
  • 返回值会作为工具结果交给客户端。

注册 Resource

Resource 用来提供可读取的资料。

它不是让模型"执行动作",而是给模型一份内容。

python 复制代码
@mcp.resource("docs://time-zone-guide")
def time_zone_guide() -> str:
    """常见时区名称说明。"""

    # Resource 返回可读取内容
    return "常见 IANA 时区:Asia/Shanghai、UTC、America/New_York、Europe/London。"

Resource 适合放:

  • 使用指南。
  • 配置说明。
  • 项目规范。
  • 不需要执行、只需要读取的上下文资料。

注册 Prompt

Prompt 是预设对话模板。

它可以让 MCP Server 给客户端提供一套可复用提示词。

python 复制代码
@mcp.prompt()
def explain_current_time(time_zone: str) -> str:
    """生成当前时间查询提示词。"""

    # Prompt 返回一段可复用任务说明
    return f"请查询 {time_zone} 的当前时间,并用一句话说明这个时间属于哪个时区。"

Prompt 适合封装固定任务模板,例如:

  • 代码解释模板。
  • 文档生成模板。
  • 查询报告模板。
  • 业务问答模板。

Tool / Resource / Prompt 的区别

三者都能暴露给 MCP Client,但用途不同。

txt 复制代码
Tool:执行动作,返回执行结果
Resource:提供资料,返回可读取内容
Prompt:提供提示词模板,返回消息模板

简单判断:

  • 需要查数据库、调用接口、读文件:用 Tool。
  • 需要提供文档、配置、规范:用 Resource。
  • 需要复用一段任务说明:用 Prompt。

启动 stdio 服务

本地 MCP Server 通常使用 stdio。

stdio 的意思是:客户端启动这个进程,然后通过标准输入输出和它通信。

python 复制代码
if __name__ == "__main__":
    # stdio 适合本地 MCP Client 启动当前 Python 进程
    mcp.run(transport="stdio")

本地开发工具、IDE、桌面 Agent 经常用这种方式接入 MCP。

在 IDE 中使用 MCP

MCP Server 启动后,可以被 IDE 或 Agent 客户端加载。

这里以 Cursor 为例。

打开 Cursor 设置,进入 Tools & MCPs,点击 New MCP Server

然后在配置文件里加入自己的 MCP Server。

我们前面写的 time-helper 是一个本地 MCP Server,所以配置里不是写 URL,而是告诉 Cursor:用什么命令启动这个本地进程。

json 复制代码
{
  "mcpServers": {
    "time-helper": {
      "command": "uv",
      "args": [
        "--directory",
        "/Users/copyer/Documents/copyer_code/project/python/python-agent",
        "run",
        "python",
        "-m",
        "app.mcp_examples.time_server"
      ]
    }
  }
}

这段配置的意思是:

txt 复制代码
time-helper:MCP Server 的名字
command:用什么命令启动
args:启动命令的参数
--directory:进入项目目录
python -m app.mcp_examples.time_server:启动 MCP Server 模块

上面采用 uv 启动 Python 项目。也可以根据项目形态换成其他命令:

txt 复制代码
Python 文件:command 可以是 python
uv 项目:command 可以是 uv
Node.js 文件:command 可以是 node
npm 包:command 可以是 npx
远程服务:通常配置 url 和 headers

从图里可以看到,Cursor 不只是识别到了一个工具,还识别到了这个 MCP Server 暴露的 prompt 和 resource。

这也是 MCP 比单个 Tool 更像"能力包"的原因。

使用远程 MCP

除了本地 stdio,MCP 也可以连接远程服务。

先区分两个容易混淆的概念:

txt 复制代码
第三方 MCP:别人提供的 MCP Server
远程 MCP:通过 URL 连接的 MCP Server

第三方 MCP 不一定是远程 MCP。

比如截图里的 amap-maps,虽然它是高德提供的第三方 MCP,但配置方式是 npx,本质上还是 Cursor 启动了一个本地进程。

context7 这种配置里直接写 urlheaders 的,才是典型的远程 MCP。

远程 MCP 的配置通常长这样:

json 复制代码
{
  "mcpServers": {
    "context7": {
      "url": "https://mcp.context7.com/mcp",
      "headers": {
        "CONTEXT7_API_KEY": "你的 API Key"
      }
    }
  }
}

这类配置不需要 Cursor 在本地启动脚本,而是直接通过 HTTP 连接已经部署好的 MCP Server。

本地和远程的区别主要在传输层:

txt 复制代码
stdio:启动本地进程,适合本地文件、脚本、数据库
HTTP:连接远程服务,适合云端 API、托管服务、团队共享服务

Python SDK 的 FastMCP 也可以用 HTTP 方式启动:

python 复制代码
if __name__ == "__main__":
    # streamable-http 适合把 MCP Server 作为远程服务暴露
    mcp.run(transport="streamable-http")

实际项目里,如果 MCP Server 需要被多人或多个 IDE 共用,才更适合部署成远程服务。

如果只是本机开发、读取本地文件、调用本地脚本,stdio 会更简单。

用 Python Client 调用 MCP

也可以直接在 Python 代码里连接 MCP Server,列出工具、资源、提示词并调用。

python 复制代码
import asyncio

from mcp.client.session import ClientSession
from mcp.client.stdio import StdioServerParameters, stdio_client


async def main() -> None:
    server_params = StdioServerParameters(
        command="uv",
        args=[
            "--directory",
            "/Users/copyer/Documents/copyer_code/project/python/python-agent",
            "run",
            "python",
            "-m",
            "app.mcp_examples.time_server",
        ],
    )

    # 1. 通过 stdio 启动并连接 MCP Server
    async with stdio_client(server_params) as (read, write):
        async with ClientSession(read, write) as session:
            # 2. 初始化会话
            await session.initialize()

            # 3. 查看服务提供了哪些工具
            tools = await session.list_tools()
            print([tool.name for tool in tools.tools])

            # 4. 调用工具
            result = await session.call_tool(
                "get_current_time",
                arguments={"time": "Asia/Shanghai"},
            )

            print(result.content)


asyncio.run(main())

这段代码里,Python 程序扮演的是 MCP Client。

它通过 stdio 启动 MCP Server,然后按协议调用工具。

小结

这一篇要记住几个核心点:

  1. MCP 是 Agent 使用外部能力的统一协议。
  2. Tool 是单个能力,MCP Server 是一组能力的标准化服务。
  3. MCP Server 可以暴露 Tool、Resource、Prompt。
  4. Tool 用来执行动作,Resource 用来提供资料,Prompt 用来提供模板。
  5. 本地 MCP 常用 stdio,远程 MCP 常用 HTTP。
  6. Python 里可以用 FastMCP 快速创建 MCP Server。
  7. MCP 的价值是复用和标准化,让不同 Agent 都能接入同一组能力。
相关推荐
闵孚龙1 小时前
Autograd 自动求导:PyTorch 训练模型的发动机
人工智能·pytorch·python
FL16238631291 小时前
基于CNN深度学习算实现手写字母识别系统python源码+训练好的模型+说明文档
python·深度学习·cnn
极创信息1 小时前
信创产品适配测试认证,域名和SSL是必须的吗?
java·开发语言·网络·python·网络协议·ruby·ssl
喵叔哟1 小时前
第3周学习笔记
python·langchain
码云骑士1 小时前
11-GIL不是性能杀手(上)-CPU密集vsIO密集的实测对比
开发语言·python
johnny2331 小时前
Python生态模版引擎:Django、Jinja2、Liquid、Mustache、Mako、Chameleon
python
喵叔哟2 小时前
Week 3 --Day 5:性能优化与监控
人工智能·python·性能优化·langchain
Kingairy2 小时前
python3装饰器
开发语言·python
暗黑小白2 小时前
第八篇:人在回路与内容安全 —— 当 AI 说“让我请示一下“
python·安全·架构·ai agent