MCP 入门到实战指南

目标读者:第一次接触 MCP、对 JSON-RPC 不熟、习惯 REST 思维的同学。

配套项目:react智能体调用mcp和cli区别的示例 || 一个客户端类调用多个mcpserver例子


一、先用一句话理解 MCP

MCP(Model Context Protocol)是一个让 AI 客户端与外部工具/数据源统一通信的协议标准。

它不是某个具体 API,而是一套"如何发现工具、如何调用工具、如何回传结果"的通用规则。

你可以把它类比成:

  • REST:面向资源(URL + HTTP 方法)
  • MCP:面向模型工具协作(JSON-RPC + 会话 + 能力协商)

二、JSON-RPC 是什么?(MCP 的消息语言)

MCP 常用 JSON-RPC 2.0 编码消息。核心字段只有几个:

  • jsonrpc:协议版本(固定 "2.0"
  • id:请求编号(用于请求-响应关联)
  • method:调用的方法名(例如 tools/listtools/call
  • params:方法参数

一个最小请求示例:

json 复制代码
{
  "jsonrpc": "2.0",
  "id": 101,
  "method": "tools/call",
  "params": {
    "name": "list_releases",
    "arguments": {
      "owner": "wisdomfriend",
      "repo": "github_watch_dual"
    }
  }
}

对应响应示例:

json 复制代码
{
  "jsonrpc": "2.0",
  "id": 101,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "..."
      }
    ]
  }
}

三、为什么 MCP 不是"两个 REST 接口就够了"?

很多同学会问:

"做两个 REST 不就行了吗?比如 GET /tools + POST /call。"

在单项目里可以这么做,但会遇到两个关键问题:

  1. 并发调用时,请求-响应关联要自己维护
  2. 流式返回、通知机制要自己再造一遍

这两个问题,我们在项目里都做了可运行演示。


四、项目实战演示 1:并发请求为什么必须靠 id

1)演示入口

启动项目:

bash 复制代码
cd github_watch_dual
uvicorn src.api:app --reload --port 8090

请求并发演示接口:

bash 复制代码
curl http://127.0.0.1:8090/demo/jsonrpc/concurrent

2)你会看到什么

接口会返回三组关键数据:

  • requests_sent:发出的请求(带 id
  • responses_in_arrival_order:按到达顺序的响应(可能乱序)
  • responses_mapped_by_id:按 id 重新关联后的映射

3)这说明了什么

并发场景下,响应不保证按请求顺序返回。

如果不用 id 做关联,客户端就可能"对错号"。

这就是为什么 MCP/JSON-RPC 把 id 设计为核心字段,而不是可选装饰。


五、项目实战演示 2:流式通知为什么不是普通 REST 一次响应

1)演示入口

访问流式接口:

bash 复制代码
curl -N http://127.0.0.1:8090/demo/jsonrpc/stream

2)你会看到什么

服务端会持续推送 text/event-stream

  • 先发多条 notifications/progress
  • 最后发一条带 id 的最终 result

这就是"通知"和"最终结果"并存的通信模式。

3)这说明了什么

如果只用最朴素 REST 一问一答:

  • 你很难优雅地表达中间进度通知
  • 或者需要额外造轮子(轮询、WebSocket、SSE 规范、自定义事件格式)

MCP 把这类模式标准化了,客户端和服务端都按同一协议处理。


六、结合真实 MCP 客户端代码理解四层职责

项目里真实调用代码(src/tool_backends.py)是:

  • streamablehttp_client(...):建立传输通道(transport)
  • ClientSession(read, write):协议会话封装(session)
  • session.initialize():握手/能力协商(初始化阶段)
  • session.call_tool(...):真正工具调用(业务阶段)

它看起来比 REST 多几步,但本质是在做协议分层,减少跨系统集成时的长期复杂度。


七、session.initialize() 到底在做什么?

初始化阶段常见职责:

  • 客户端与服务端确认协议版本
  • 交换能力声明(支持哪些功能)
  • 建立会话上下文(某些服务端会分配 Session ID)

如果跳过这步,常见后果是:

  • 客户端按 A 能力调用,服务端按 B 能力处理
  • 版本不匹配导致奇怪错误
  • 会话状态不完整导致后续调用失败

八、新手常见误区

  • 误区 1:MCP 就是"另一个 REST API"

    • 纠正:MCP 是协议标准,HTTP 只是其中一种传输层。
  • 误区 2:id 可有可无

    • 纠正:并发时 id 是请求-响应关联的关键。
  • 误区 3:一次响应就够,通知不重要

    • 纠正:工具调用常需要进度、事件、最终结果分阶段输出。

九、什么时候该用 MCP,什么时候不用?

建议用 MCP:

  • 你要把工具能力开放给多个 AI 客户端(IDE、Agent、服务)
  • 你希望复用一套标准调用协议,减少重复集成
  • 你需要并发、通知、流式等高级交互能力

不一定要用 MCP:

  • 单次脚本、一次性实验
  • 单客户端单后端、生命周期很短的小项目

十、结语

MCP 看起来"比 REST 麻烦",本质是把复杂度从"每个项目重复造轮子"变成"一次标准化"。

对新手来说,先记住这句话就够:

REST 适合快速做资源接口,MCP 适合做可复用的模型工具协议。


参考资料

相关推荐
Coffeeee4 分钟前
帮你快速理解AI Agent之我想招个Android实习生
android·人工智能·agent
新新技术迷11 分钟前
AI聊天自动跟随滚动,附回到底部按钮
人工智能
先锋部队11 分钟前
用Web Worker解析AI返回的大文本不卡UI
人工智能
把你拉进白名单15 分钟前
8.OpenClaw源码解析——三层洋葱重试
人工智能·llm·agent
用户6324150317817 分钟前
拖文档进AI对话框解析,前端要处理哪些脏活
人工智能
姗姗来迟了24 分钟前
AI回答里的引用来源卡片,前端怎么做
人工智能
用户71062077334025 分钟前
Codex-端口配置错误排查案例(stream disconnected before completion)
人工智能
IT_陈寒1 小时前
JavaScript的默认参数挖坑实录,我掉进去了
前端·人工智能·后端
米小虾2 小时前
多Agent系统编排详解:从架构设计到代码实现
人工智能·agent
米小虾2 小时前
多Agent系统的编排:架构、协议与企业级应用
人工智能·agent