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 證據。