MCP 通信

MCP(模型上下文协议)的底层交互是一个精巧的流程,核心是通过 JSON-RPC 2.0 格式在预定义的通道上交换标准化的消息。

下面的内容会为你完整拆解这个过程。同时,为了让整个流程更清晰,我会引入一个具体的场景:假设你的 Spring Boot 服务里有一个 get_weather 工具,而客户端程序(比如一个AI应用)需要调用它来获取天气信息。

🔌 核心架构概览

整个架构由几个关键部分组成:

  • MCP 客户端 (MCP Client):AI 应用(如 Claude Desktop)内部的组件,负责发起所有请求。

  • MCP 服务端 (MCP Server):你的 Spring Boot 服务,负责响应请求并执行业务逻辑。

  • 传输层 (Transport):客户端与服务端通信的方式,MCP 协议主要定义了两种标准传输机制。

    • 标准输入/输出 (stdio):用于本地通信,客户端将服务端作为子进程启动,通过标准输入(stdin)和标准输出(stdout)交换消息。消息之间通过换行符分隔。
    • HTTP with Server-Sent Events (SSE) :用于网络通信,客户端通过 HTTP 与服务端交互。服务端必须提供两个端点:一个用于客户端接收消息 的 SSE GET 端点,和一个用于客户端发送消息 的常规 HTTP POST 端点。
  • 消息协议 (JSON-RPC 2.0):所有传输的消息都遵循 JSON-RPC 2.0 规范,主要有以下三种类型。

    • 请求 (Request) :客户端发起的调用,包含唯一的 id,服务端必须对此做出响应(Response)。
    • 通知 (Notification) :客户端发起的消息,没有 id 字段,服务端不需要做出响应。
    • 响应 (Response) :服务端对"请求"的回复,包含与请求相同的 id 和执行结果或错误信息。

📡 核心生命周期与接口详解

MCP 的生命周期通常包含以下几个阶段,我会在每个阶段都给出清晰的接口定义和调用示例。

1. 连接与初始化 (Initialization)

这是会话建立的"握手"阶段,目的是让客户端和服务端互相认识,并就协议版本、能力等信息达成一致。

触发时点:当 MCP 客户端首次连接到 MCP 服务端时。

1.1 客户端发现服务端点 (SSE 模式独有)

如果是 SSE 模式 ,客户端首先会向服务端的 SSE 端点发起 GET 请求。服务端响应后,会通过一个名为 endpoint 的 SSE 事件,将用于后续通信的 POST 端点地址告诉客户端。

  • Client → Server (SSE GET)

    http 复制代码
    GET /sse HTTP/1.1
    Host: your-spring-boot-server.com
  • Server → Client (SSE endpoint event)

    json 复制代码
    event: endpoint
    data: /message?sessionId=abc123
1.2 客户端发送初始化请求

客户端向服务端发送 initialize 请求,告知自己的协议版本、客户端信息和支持的能力。

  • Client → Server (Request)

    json 复制代码
    {
        "jsonrpc": "2.0",
        "id": 1,
        "method": "initialize",
        "params": {
            "protocolVersion": "0.1.0",
            "capabilities": {
                "roots": {
                    "listChanged": true
                }
            },
            "clientInfo": {
                "name": "my-ai-client",
                "version": "1.0.0"
            }
        }
    }
1.3 服务端响应并返回自身能力

服务端收到后,会返回自己的协议信息、能力和服务端信息。

  • Server → Client (Response)

    json 复制代码
    {
        "jsonrpc": "2.0",
        "id": 1,
        "result": {
            "protocolVersion": "0.1.0",
            "capabilities": {
                "tools": {
                    "listChanged": true
                }
            },
            "serverInfo": {
                "name": "my-spring-mcp-server",
                "version": "1.0.0"
            }
        }
    }
1.4 客户端发送初始化完成通知(必须发送,否则工具发现请求会卡住!!!

客户端收到成功响应后,发送一个 initialized 通知,表示自己已完成初始化,通信通道正式建立。

  • Client → Server (Notification)

    json 复制代码
    {
        "jsonrpc": "2.0",
        "method": "notifications/initialized"
    }

2. 工具发现 (Tool Discovery)

让客户端能从服务端"拉取"一份可用工具的清单,包括工具的名称、描述和输入参数定义(JSON Schema)。这是 MCP 实现"即插即用"的关键。

触发时点:在初始化阶段完成之后,由客户端主动发起。这也是服务端向外"介绍"自己能力的方式。

  • Client → Server (Request)

    json 复制代码
    {
        "jsonrpc": "2.0",
        "id": 2,
        "method": "tools/list"
    }
  • Server → Client (Response)

    json 复制代码
    {
        "jsonrpc": "2.0",
        "id": 2,
        "result": {
            "tools": [
                {
                    "name": "get_weather",
                    "description": "获取指定城市的当前天气信息",
                    "inputSchema": {
                        "type": "object",
                        "properties": {
                            "city": {
                                "type": "string",
                                "description": "城市名称,例如:北京"
                            },
                            "unit": {
                                "type": "string",
                                "enum": ["celsius", "fahrenheit"],
                                "description": "温度单位"
                            }
                        },
                        "required": ["city"]
                    }
                }
            ]
        }
    }

3. 工具调用 (Tool Call)

这是最重要的业务交互阶段。客户端根据 tools/list 返回的元数据,构造并发送 tools/call 请求,服务端执行后返回结果。

触发时点:当 AI 模型决定使用某个工具时,由 MCP 客户端代理发起此请求。

  • Client → Server (Request)

    json 复制代码
    {
        "jsonrpc": "2.0",
        "id": 3,
        "method": "tools/call",
        "params": {
            "name": "get_weather",
            "arguments": {
                "city": "杭州",
                "unit": "celsius"
            }
        }
    }
  • Server → Client (Response)

    json 复制代码
    {
        "jsonrpc": "2.0",
        "id": 3,
        "result": {
            "content": [
                {
                    "type": "text",
                    "text": "杭州当前天气:晴,25°C"
                }
            ],
            "isError": false
        }
    }

补充说明:协议也支持服务端通过 SSE 流式返回结果,这种方式对于需要长时间处理的任务特别有用。例如,可以先返回一个进度通知,最后再返回最终结果。


4. 关闭会话 (Shutdown & Exit)

当 AI 应用与 MCP 服务端的交互结束时,需要优雅地关闭连接。

触发时点:由客户端发起,表示会话结束。

  • Client → Server (Request)

    json 复制代码
    {
        "jsonrpc": "2.0",
        "id": 4,
        "method": "shutdown"
    }
  • Server → Client (Response)

    json 复制代码
    {
        "jsonrpc": "2.0",
        "id": 4,
        "result": {}
    }
  • Client → Server (Notification)

    json 复制代码
    {
        "jsonrpc": "2.0",
        "method": "exit"
    }

总的来说,MCP 的整个工作流程可以看作是一个结构化的对话,由"握手"(初始化)开始,接着"展示菜单"(工具发现),然后"点菜"(工具调用),最后"结账离开"(关闭会话)。每一步都有明确的 JSON-RPC 消息来驱动。

相关推荐
牧艺13 分钟前
从 Tool Calling 到 MCP Server:把业务能力做成 Agent 可复用接口
agent·全栈·mcp
凡泰AI1 小时前
如何借助MCP打通企业APP内部服务:从统一调用到小程序承接
小程序·uni-app·app·mpaas·mcp·小程序容器
小四的小六1 天前
MCP Client实战翻车记:两个Server同时跑,AI调错了Tool
openai·ai编程·mcp
在水一缸1 天前
当 AI 拥有了“核按钮”:深入解析 MCP 服务器与命令执行护栏
运维·服务器·人工智能·命令执行·智能体·ai安全·mcp
wMoqi2 天前
trae cn 中ai开发配置skill mcp 规则参考(yudao-cloud项目-个人用)
ai·skill·yudao·mcp·trae
不能只会打代码2 天前
Day 006 — Multi-Agent + MCP/A2A + 安全 + 可观测性
agent·token·sse·multi-agent·mcp·a2a
冬奇Lab4 天前
MCP 系列(08):企业治理——Registry、路由与可观测性
人工智能·llm·mcp
weigangwin4 天前
agent-workspace-linux 不是远程桌面:Linux AI 工作区的隔离边界验收
linux·xvfb·mcp·桌面隔离·权限边界·bubblewrap·agent-workspace
码哥字节4 天前
Anthropic 官方的 7 种 Claude Code 自定义方式,你可能只用对了 1 种
ai编程·claude·mcp
MicrosoftReactor4 天前
技术速递|基于 OpenClaw、MCP 和 Azure Container Apps 构建自主 Microsoft Teams 智能体
microsoft·agent·azure·teams·mcp