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 适合做可复用的模型工具协议。


参考资料

相关推荐
a9511416422 小时前
解决 Bookmarklet 中 %0A 换行符导致的跨环境执行失败问题
jvm·数据库·python
解救女汉子2 小时前
MySQL存储过程运行出错怎么排查_使用DECLARE HANDLER捕获错误
jvm·数据库·python
EdmundXjs2 小时前
智能体系统架构深度解析
人工智能
迷藏4942 小时前
**发散创新:基于Python的情感计算实战——从文本到情绪的智能识别**在人工智能与人机交互日益融合的今天,**情感计算(A
java·人工智能·python·人机交互
Absurd5872 小时前
SQL嵌套查询在多租户系统应用_数据隔离逻辑
jvm·数据库·python
2301_782659182 小时前
怎样使用Navicat高级特权进行还原时解决字符集冲突_企业数据保护
jvm·数据库·python
love530love2 小时前
修复 ComfyUI 插件 ComfyUI-BiRefNet-ZHO 报错 - Windows
服务器·人工智能·windows·python·birefnet-zho
m0_640309302 小时前
mysql如何处理连接数过多导致响应慢_mysql连接数调优
jvm·数据库·python
weixin_458580122 小时前
PHP怎么实现Toran Proxy代理_PHP依赖包缓存加速【技巧】
jvm·数据库·python