MCP状态机

在2025年6月18日更新的 MCP 规约中,MCP 应用被划分四个生命周期阶段——初始化(Initialization)、操作(Operation)、关闭(Shutdown)、连接关闭(Connection closed)【此前的MCP版本中定义为初始化(Initialization)、消息交换(Message Exchange)和终止(Termination)三个阶段】——中,系统依次经历六种明确的状态,构成一个严谨的状态机模型。这些状态依次是:

  • 未初始化(Uninitialized):初始阶段,客户端尚未与服务器建立连接;
  • 初始化中(Initializing):客户端向服务器发出initialize请求,并等待服务器协商协议版本与能力;
  • 已初始化(Initialized):客户端接收到服务器的响应后,发送initialized通知,系统进入就绪状态;
  • 运行中(Operating):客户端与服务器依据协商的能力,通过JSON-RPC持续进行工具调用、资源访问及上下文管理;
  • 关闭中(ShuttingDown):当客户端或服务器任一方发出结束信号时,系统开始关闭通道并释放挂起的请求;
  • 已终止(Terminated):完成底层传输的关闭和资源释放,生命周期结束。

通过将生命周期的三个主要阶段映射到上述六个明确状态,MCP不仅精确界定了每一阶段的职责与交互边界,还为后续深入理解各状态职责、验证消息类型及异常处理流程提供了清晰的结构性基础。

在正常情况下,MCP的状态机如下图所示。

图 MCP状态机

1. 未初始化(Uninitialized)

在“未初始化”状态下,客户端尚未与服务器建立任何有效连接,整个系统处于协议生命周期的起点。此时,客户端所能发送的唯一合法请求是 initialize。任何其他类型的消息,例如工具调用、资源访问或上下文管理操作,均应被视为非法请求,必须被服务器忽略或明确拒绝。

该状态明确了一个严格的会话起点,以确保所有后续交互都建立在明确的协议协商之上。允许客户端发送 initialize 请求,并等待服务器回应其版本兼容性与能力定义,有助于构建清晰、可控的连接流程。同时,服务器在未接收到 initialize 请求前,也不应发送任何功能性响应或执行指令,从而确保初始化阶段的单向性和专一性。

通过这样的约束机制,MCP 协议有效防止了客户端和服务器在尚未协商完毕前出现功能操作,从根本上提升了协议执行的稳定性与可预测性,也为客户端与服务器建立可靠通信基础打下了坚实前提。

2. 初始化中(Initializing)

当客户端发起 initialize 请求时,系统随即进入“初始化中”阶段。

该请求过程将确定协议版本、能力声明(capabilities)、客户端信息等核心信息。服务器仅在这一阶段接受 initialize 请求,并通过返回自身的版本与能力信息,实现双方的双向协商。如果发现版本不兼容或能力无法匹配,双方应立即终止交互;反之,一旦协商成功,系统将进入下一状态。

此阶段非常重要,它为客户端与服务器之间的后续交互奠定了基础,确保了协议版本、能力以及实现细节的一致性。同时,它拒绝了除协商之外的所有消息,以保持状态的纯净性和协议的严格性。

3. 已初始化(Initialized)

当客户端接收到服务器协商响应并向客户端发送 initialized 通知后,系统就进入了“已初始化”状态。该状态标志着协商流程正式完成,客户端和服务器已明确彼此支持的协议版本和能力范围。系统进入“接近就绪”的阶段,此时虽然尚未启动任何实际功能交互,但所有运行前准备都已到位。

4. 运行中(Operating)

系统在初始化完成后,随即步入“运行中”状态,这是 MCP 生命周期的核心交互期,也是 MCP 的拥有最长时间的状态。在此状态下,客户端与服务器依据协商的能力集,通过 JSON‑RPC 进行双向通信,这包括工具调用、资源订阅与访问、上下文管理等多种操作。在些状态下的各项交互均需遵在“初始化中”状态协商的协议版本与可用能力,并应当实现合理的超时与取消机制,避免长时间挂起或资源阻塞。

5. 关闭中(ShuttingDown)

当客户端或服务器准备结束会话时,系统将进入“关闭中”状态。此时,尽管系统已经准备关闭,但可能仍有正在处理的请求未返回响应。这些正在处理的请求需要被妥善处理,以防止资源泄露和调用悬挂。

MCP 协议为此提供了一套标准的取消机制:通过发送 notifications/cancelled 通知,并携带一个代表请求的 requestId (以及可选的 reason ),以明确取消某个仍在处理的请求。如果在收到取消通知时,相应请求已经处理完成,则可以忽略该取消任务通知;否则,应立即停止对应请求任务并清理相关资源,以确保该请求优雅干净地中止。而一旦发送取消通知,则应忽略在此之后收到的对应请求任务的响应。

需要特别注意的是,MCP 协议明确指出 initialize 请求是不可取消的,如果在客户端发送 initialize 请求后需要立即进入“关闭中”状态,可待系统进入“运行中”状态后再中断连接即可。

为实现上述取消请求机制,一个典型的实现方式是:系统维护一个“挂起请求表”(例如 pendingRequests 映射),在发起请求时将代表请求的 requestId 加入该表,在收到请求的响应后则从该表中删除对应请求。如果系统准备关闭,则依序遍历该请求表,对于在表中的每条请求(即当前还未完成响应的请求)依次发送取消通知。请求响应方在接收到该通知后应主动中断请求处理流程,并释放相关资源。

为了避免在关闭期间引入新的业务请求,系统应在该阶段停止接收任何新的调用。客户端可以选择在获得所有响应或发出取消通知后关闭其流;服务器也应在所有关闭相关操作完成后主动断开与当前客户端的连接。这一策略能够确保所有挂起的交互都能得到妥善处理,释放所有内部资源,最终实现稳定、一致的会话关闭。

“关闭中”阶段的结构化设计为 MCP 会话提供了清晰、有序且可控的终止路径。通过结合显式取消机制,系统在终止前能够确保所有请求中止、资源彻底释放,有效防止调用悬挂和资源泄漏,增强整个协议交互的健壮性。

6. 已终止(Terminated)

在执行了程序关闭操作后,系统达到了“已终止”状态。在这个阶段,当前客户端和服务器的底层连接被彻底断开,与会话相关的所有状态和资源都已被释放和清空。会话完全结束,客户端与服务器之间不再有任何联系。若需重新开始交互,必须返回到“未初始化”状态,并重新经历整个生命周期流程。

掌握 MCP 状态机及其转换机制对于架构师和开发者来说非常重要,这将有助于在设计和开发基于 MCP 的AI应用程序时,尤其是在那些包含复杂 MCP 组件的应用程序时,能够恰当地设计和运用 MCP。这不仅能够提高AI应用程序架构设计和代码实现的合理性、正确性、可读性,还能增强其健壮性。