Grok Build Source Course · 12 / 20

MCP:连接只是起点

真正的客户端还要完成配置合并、OAuth、能力发现、命名隔离、模型可见性控制、状态推送和断线恢复。源码将这些责任拆在 MCP crate 与 Session Actor 周边。

Client Rolestdio / Streamable HTTPOAuthserver__tool50 ms 状态合并
01 / OBJECTIVES

课程目标

核对协议角色

从调用方向判断客户端与服务端,避免把内部 Hub Server 等同于 MCP Server。

追踪可见性

解释工具如何从 tools/list 进入快照、搜索索引与模型注册表。

设计恢复状态机

把 OAuth、状态合并、客户端身份和重启退避放进同一连接生命周期。

02 / CORE VISUAL

从外部 Server 到模型工具

03 / ROLE CHECK

客户端与服务端:按源码措辞落位

SOURCE CONFIRMEDGrok Build 是 MCP 客户端

McpClient 启动 stdio 或 Streamable HTTP 连接,执行初始化、list_toolscall_tool。Computer Hub MCP Adapter 也描述为把 MCP Server 的工具桥接进 Hub 路由。

NOT ESTABLISHED通用 MCP 服务端没有源码证据

xai-grok-workspace 的 Hub Server 属于 xAI Computer Hub 协议。当前快照未找到将 Grok Build 自身通过 MCP 传输暴露给任意 MCP Client 的入口,因此本课只确认客户端角色。

04 / OAUTH

OAuth 与真实凭据落点

1 · 复用或刷新先读磁盘凭据并尝试 token refresh
2 · 浏览器授权需要交互时启动用户同意流程
3 · 回调换令牌授权码交换访问与刷新令牌
4 · 锁定写入文件锁配合原子保存,支持多进程
CONFIG TYPES

配置字段

oauth_client_id
oauth_client_secret_env_var
oauth_scopes
crates/codegen/xai-grok-config-types/src/mcp.rs
CREDENTIAL STORE

本地 JSON 文件

let path = grok_home
    .join("mcp_credentials.json");
// lock + load + insert + atomic save

源码采用该文件存储,并通过文件锁与原子保存处理并发写入。

crates/codegen/xai-grok-mcp/src/credentials.rs · oauth.rs
05 / VISIBILITY

工具如何获得模型可见性

NAMESPACE

server__tool

注册名由服务端名、保留分隔符 __ 和原始工具名组成。源码要求完整名称中恰好出现一次分隔符,避免解析歧义,也让两个 Server 的同名工具拥有不同 ToolId

crates/codegen/xai-grok-mcp/src/servers.rs: into_registration
TWO AUDIENCES

模型工具与 App 工具分流

禁用工具会存入 disabled_tool_registrationsmodel_visible 为真才进入模型侧 Tool Bridge;带 ui.resourceUri 的工具可单独进入 UI 通知。

crates/codegen/xai-grok-shell/src/session/acp_session_impl/mcp.rs
SEARCH SNAPSHOT

大量 MCP 工具不必全部常驻提示词

ToolMetadataSnapshot 保存工具与服务端元数据,BM25 索引支持按 qualified name 或裸工具名精确命中,再提供搜索结果。mcp_initialized 告诉搜索层能力发现是否完成。

pub struct ToolMetadataSnapshot {
    pub tools: Vec<ToolMetadata>,
    pub servers: Vec<ServerMetadata>,
    pub mcp_initialized: bool,
}
crates/codegen/xai-grok-shell/src/session/tool_index.rs
06 / RECOVERY

状态合并与重启保护

Initializing开始握手
Ready能力可用
NeedsAuth等待授权
Unavailable连接中断
Disabled配置关闭
50 MS COALESCE

同键保留最新事件

mcp_dispatcher(server_name, event_kind) 为键,在 50 ms tumbling window 内 last-write-wins。高频 tools/list_changed 最终只推一次 ACP 状态。

IDENTITY GUARD

旧断线不能误删新连接

移除 dead client 前比较 client_id。如果断线事件属于已被替换的旧客户端,保持当前客户端,并丢弃过期状态。

RESTART POLICY

不同传输采用不同恢复动作

stdio 自动重启使用固定退避 1s → 4s → 16s,并检查关闭中、已禁用、配置移除等护栏。HTTP 先尝试客户端内恢复,并使用独立退避。成功重连后重新发现与注册工具,随后刷新快照。

crates/codegen/xai-grok-shell/src/session/mcp_dispatcher.rs · mcp_restart.rs · acp_session_impl/mcp_snapshot.rs
07 / LAB

课堂练习:画出可恢复客户端

30 MIN

提交物
状态图与 6 条测试

  1. 画出配置载入、连接、OAuth、能力发现、注册、搜索和调用的状态图。
  2. 加入 disabled、app-only 与 model-visible 三种工具路径。
  3. 设计两个同名工具,验证 qualified name 可消除冲突。
  4. 模拟 100 条 tools/list_changed,写出 50 ms 合并后的预期通知数。
  5. 模拟旧客户端断线事件晚到,说明 client_id 护栏如何保护新连接。
  6. 分别为 stdio 与 HTTP 写一条可恢复测试和一条停止重试条件。
Takeaway

MCP 集成的工程量集中在协议外围。命名、可见性、身份、状态合并和恢复策略共同决定一条连接能否长期稳定工作。

源码快照说明:本页依据本地 grok-build-main 的 MCP、config-types、shell session 与 computer-hub adapter 源码整理。代码片段为教学截取。关于 MCP 服务端角色的结论采用保守口径,内部 Hub Server 不作为通用 MCP Server 证据。