MCP开发基础教程

MCP 开发基础教程

适用对象:想了解 MCP 是什么、怎么来的,以及如何从零上手开发自己的 MCP Server / Client 的开发者。
读完你将掌握:MCP 解决什么问题、整体结构、发展脉络,以及一套可直接落地的工程最佳实践(含可运行示例)。


一、MCP 的来源

1. 它解决什么问题

在 MCP 出现之前,让 LLM 连接外部系统是一件很痛苦的事:每个 AI 应用都要为每个外部系统单独写一套定制集成代码。

假设你有 N 个 AI 应用(IDE、聊天助手、Agent 框架……)和 M 个外部系统(数据库、文件系统、CRM、天气 API……),就需要维护 N × M 个定制连接。每新增一个模型或一个工具,集成数量就翻倍增长——这就是业界常说的 "N × M 问题"。

MCP(Model Context Protocol,模型上下文协议)就是 Anthropic 于 2024 年 11 月发布并开源的开放标准,用来解决这个痛点。它把上面的组合爆炸压缩成 N + M:

  • 每个 AI 应用实现一个 MCP Client
  • 每个外部系统实现一个 MCP Server

两者通过统一的标准协议通信,任意组合即可互联,不必为每种组合单独写代码。人们常把它比喻成 "AI 世界的 USB-C 接口"——一个通用标准,所有设备都能插。

2. 一句话定义

MCP 是一个开放式协议,为 AI 应用(LLM)连接外部数据源和工具提供标准化的接口。

在 MCP 之前,LLM 的知识只来自训练数据,无法访问实时信息、无法执行具体动作。MCP 让 LLM 变成能检索信息、更能执行动作的动态代理,而不是只会聊天的静态模型。

3. MCP 与相关概念的区别

概念 是什么 与 MCP 的关系
Function Calling / 工具调用 让模型生成结构化的工具调用 MCP 标准化了工具描述、调用协议,是工具调用的"通用化封装"
RAG 检索并注入信息来增强生成 RAG 侧重"取信息",MCP 侧重"取信息 + 执行动作"的更广交互
API 程序间的通用接口 每个系统一套自定义 API;MCP 是给 LLM 用的统一标准协议
MCP 里的 Tool 服务器暴露给模型执行的函数 是 MCP 的核心原语之一(详见第二节)

二、MCP 的结构

1. 三个参与方:Host / Client / Server

MCP 采用客户端-服务器架构,包含三个角色:

┌─────────────────────────────────────────┐
│            MCP Host                     │
│                                         │
│   ┌──────────┐   ┌──────────┐           │
│   │ Client 1 │   │ Client 2 │   ...     │
│   └─────┬────┘   └─────┬────┘           │
└─────────┼──────────────┼────────────────┘
          │ 1:1          │ 1:1
     ┌────┴────┐    ┌────┴────┐
     │Server A │    │ Server B│
     │ (local) │    │ (remote)│
     │  stdio  │    │   HTTP  │
     └─────────┘    └─────────┘
角色 是什么 职责
Host(宿主) AI 应用本身,如 Claude Desktop、VS Code (Copilot)、Cursor 创建和管理多个 Client;执行安全策略(如工具调用需用户确认);处理用户交互
Client(客户端) Host 内为每个 Server 连接创建的组件,与 Server 保持 1:1 连接 处理协议协商与能力交换;双向路由消息;维护安全边界(通常不用你写,Host 自动创建)
Server(服务器) 提供工具/数据/提示词的外部程序 通过 MCP 原语暴露能力;可以是本地进程或远程服务

大多数开发者需要构建的是 Server 部分——这也是本文第四节的核心。

2. 三个核心概念:Tools / Resources / Prompts

Server 通过下面三种原语(Primitive)向 Client 暴露能力:

原语 谁控制 发现方法 执行方法 用途
Tools(工具) 模型控制 tools/list tools/call 可执行函数:查数据库、调 API、发消息等
Resources(资源) 应用控制 resources/list resources/read 数据源:文件、记录、API 响应等
Prompts(提示词) 用户控制 prompts/list prompts/get 可复用的交互模板 / 工作流

对应地,Client 也可以向 Server 暴露能力:

原语 方法 用途
Sampling(采样) sampling/createMessage Server 反向请求 Host 的 LLM 帮忙推理
Roots(根路径) roots/list Server 查询 Client 的文件系统边界(哪些目录可访问)
Elicitation(引导) elicitation/request Server 请求 Client 向用户询问信息

3. 通信基础:JSON-RPC 2.0 与消息类型

MCP 基于 JSON-RPC 2.0 消息格式,建立有状态连接。只有三种核心消息类型:

消息类型 说明
请求(Request) 双向发送,带方法+参数,期待响应
响应(Response) 匹配特定请求 ID 的成功结果或错误
通知(Notification) 单向发送,不需要响应的消息

4. 能力协商(Capability Negotiation)

连接建立时,Client 和 Server 通过 initialize 阶段互相声明支持的能力:

  • Server 声明提供什么(tools、resources、prompts)
  • Client 声明支持什么(sampling、roots、elicitation)
  • 双方只使用对方声明支持的能力;协议版本必须一致,否则初始化失败

5. 连接生命周期

MCP 是有状态协议,一个连接分三个阶段:

  1. 初始化(Initialization):Client 发 initialize 请求 → 双方协商协议版本和能力 → Client 发 initialized 通知确认 → 连接就绪。
  2. 操作(Operation):正常消息交换,Client 可发现并调用 Server 的能力(如 tools/list、tools/call)。
  3. 关闭(Shutdown):任一方可关闭连接,未完成请求被取消、资源被清理。

三、MCP 的发展

时间线

时间 里程碑
2024-11 Anthropic 发布并开源 MCP,协议修订 2024-11-05;早期只支持 stdio 与 HTTP + SSE 传输
2025-03 协议修订 2025-03-26;HTTP + SSE 被标记为弃用,为 Streamable HTTP 让路
2025-11 协议修订 2025-11-25;Streamable HTTP 正式取代 SSE,成为远程部署的标准传输方式
2026-02 FastMCP 3.0 发布(PrefectHQ 维护的独立高层框架),加入 OAuth、OpenTelemetry 等能力
至今 官方 SDK 覆盖 Python / TypeScript / Java / Kotlin / C# 五种语言;公开 MCP Server 10,000+

发展主线

从"每个系统一套定制 API" → "统一、标准化的连接协议" → "更稳定、更可扩展、更安全的传输与认证体系"。
驱动逻辑始终是:降低 AI 应用接入外部系统的成本,同时提升集成的一致性和安全性。

关键演进点:

  • 传输层:stdio(本地进程)始终是本地首选;远程从 HTTP+SSE 演进为 Streamable HTTP——一个统一端点,既支持简单 JSON 响应,也支持 SSE 流式推送,部署更干净。
  • 认证:引入基于 OAuth 2.1(RFC 9728) 的授权框架,满足生产环境的访问控制需求。
  • 框架:从底层官方 SDK 衍生出更易用的高层框架(如 Python 的 FastMCP),用装饰器几行就能跑通一个 server。

四、上手开发(工程最佳实践)

1. 选型:语言与框架

语言 推荐框架 适用场景 备注
Python FastMCP 3.x / 官方 mcp SDK Python 生态工具集成 pip install fastmcp,装饰器即可;想要底层控制用官方 mcp.server.Server
TypeScript @modelcontextprotocol/sdk + Zod Node.js / 前端生态工具集成 McpServer + Zod 拿类型安全

快捷选择:Python + FastMCP 上手最快,本文示例以此为主。

2. 选择传输方式(Transport)

传输方式 推荐场景
stdio 本地首选:Claude Desktop / Cursor 等本地客户端。零配置、最快、不占端口、能访问本地文件
Streamable HTTP 生产/远程首选:多客户端共用、团队共享、需要认证与日志。走 HTTP POST + GET,可流式
HTTP + SSE 已弃用(2025-03 起),新项目不要再选

建议路径:先用 stdio 跑通本地 → 再切 Streamable HTTP 部署远程并加认证。

3. 最小可运行 Server(Python + FastMCP)

# server.py
from fastmcp import FastMCP

mcp = FastMCP("demo-server")

@mcp.tool()
def add(a: int, b: int) -> int:
    """Add two numbers"""
    return a + b

@mcp.tool()
def get_weather(city: str) -> str:
    """Get weather for a city (demo)"""
    return f"Weather in {city}: 22°C, sunny"

if __name__ == "__main__":
    mcp.run()          # 默认 stdio
    # 远程部署改一行:
    # mcp.run(transport="http", host="0.0.0.0", port=8080)

@mcp.tool() 会自动读取类型注解和 docstring 生成 JSON Schema。所以写函数签名要认真:类型注解 + 一句话 docstring,缺一不可——Client 端拿到的工具描述就来自这里。

4. 最小可运行 Client

# client.py
import asyncio
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client

async def main():
    server_params = StdioServerParameters(command="python", args=["server.py"])
    async with stdio_client(server_params) as (read, write):
        async with ClientSession(read, write) as session:
            await session.initialize()
            tools = await session.list_tools()
            print("Available tools:", [t.name for t in tools.tools])
            result = await session.call_tool("add", {"a": 1, "b": 2})
            print("add(1,2) =", result.content[0].text)

asyncio.run(main())

远程调用只需把 stdio_client 换成 streamablehttp_client(url="https://.../mcp"),客户端会按 URL 自动选择传输方式。

5. 工程最佳实践清单

Server 侧

  • 单一职责:一个 Server 专注一个领域,别把所有工具塞进一个 Server。
  • 输入校验:对参数做类型、长度、格式校验——尤其是 SQL 和文件路径,这是注入重灾区。
  • 异步优先:I/O 操作全部异步化;数据库用连接池。
  • 错误可观测:统一异常处理、结构化日志、可追踪的 request ID。

Client 侧

  • 严格生命周期:统一用 async with 管理连接和会话。
  • 重试与退避:网络错误用指数退避重试,并设最大次数。
  • 超时治理:连接超时、请求超时都显式配置。
  • 降级策略:远程失败时可降级为本地缓存结果或提示人工介入。

安全与权限

  • 密钥不硬编码:走环境变量或密钥管理服务。
  • 高危工具二次确认:写库、删文件、发消息等工具,务必让用户确认。
  • 最小权限:Server 不要拥有过大的系统权限;远程部署加 Authorization 认证(推荐 OAuth 2.1 / JWT)。

测试与验收

  • 工具级单测:每个 tool 至少覆盖成功、失败、边界三类用例。
  • 传输层联调:stdio、Streamable HTTP 各跑一条回归链路。
  • 观测指标:把错误率、延迟、超时率、重试率纳入监控。

6. 常见问题排查

报错 / 现象 通常原因 处理
initialize() 失败 Server 没启动 / 传输方式不一致 / 协议版本不匹配 先确认 Server 监听端点、传输方式与 Client 一致;看 Server 日志首个异常栈,别只看 Client 报错
Tool not found 工具名拼错 / Server 加载失败 用 Inspector 看实际工具列表
Validation error 参数 schema 不匹配 Python 检查 type hint,TS 检查 Zod schema
Connection closed(HTTP) Server 进程崩了 / 网络断 看 Server log,确认 Streamable HTTP 端点实际在监听
客户端看不到 Server 配置 JSON 写错 用 python -m json.tool < config.json 校验语法

7. 调试工具

官方提供 MCP Inspector,一条命令启动可视化调试:

# TypeScript
npx @modelcontextprotocol/inspector

# Python
mcp dev server.py   # 开发模式,支持热重载
mcp install server.py   # 安装到 Claude Desktop
mcp run server.py       # 直接运行

附:一页速查

  1. 是什么 → 让 LLM 连接外部系统的统一开放协议,AI 界的"USB-C"。
  2. 解决什么 → 把 N×M 个定制集成,压缩成 N+M 的标准连接。
  3. 谁在用 → Host(AI 应用)/ Client(连接器)/ Server(能力提供方)三方协作。
  4. 核心原语 → Tools / Resources / Prompts(Server 端)+ Sampling / Roots / Elicitation(Client 端)。
  5. 传输怎么选 → 本地 stdio;远程 Streamable HTTP(别再用已弃用的 SSE)。
  6. 怎么上手 → Python + FastMCP,@mcp.tool() + mcp.run() 约 30 行跑通;再补校验、认证、测试、监控。
posted @ 2026-08-30 23:33  LemHou  阅读(35)  评论(0)    收藏  举报