大多數 AI 平台透過 REST API 連接到外部服務。這對於結構化資料來說運作良好 — 讀取 CRM 聯絡人、建立 Jira 工單 — 但它遺漏了瀏覽器內發生的所有事情。Gmail 中的電子郵件草稿、你正在閱讀的 Slack 對話串、ServiceNow 中填寫到一半的表單。
我們使用 Model Context Protocol (MCP) 打造了一個瀏覽器擴充功能來彌補這個差距。這篇文章涵蓋了架構決策、我們遇到的問題,以及系統從頭到尾的運作方式。
問題:瀏覽器狀態對 API 來說是不可見的
API 給你資料庫記錄。它們不會給你螢幕上顯示的內容。一位業務代表在 Gmail 中撰寫後續追蹤電子郵件時,擁有任何 API 都無法捕捉的情境 — 語氣、寫到一半的段落、同時開啟的分頁。我們希望 AI workflow 能夠像坐在你旁邊的人類助理一樣,在這個即時的瀏覽器情境中運作。
架構概述
這個擴充功能基於 WXT 0.20 (Manifest V3) 以及 Svelte 5 和 TypeScript 打造。它實作了一個 MCP client,透過 WebSocket 連接到 JieGou 伺服器,公開 60 多個 AI workflow 可以呼叫的瀏覽器自動化工具。
訊息流程如下:
MCP Server → WebSocket → Background Service Worker → Content Script → Page
當 recipe 或 workflow 需要與瀏覽器互動時,它會透過 WebSocket 連線傳送 JSON-RPC 2.0 工具呼叫。擴充功能的 background worker 將其路由到適當的工具執行器,該執行器會將 content script 注入到活動分頁中並回傳結果。
WebSocket 橋接
WebSocket proxy 處理身份驗證、heartbeat、重新連線和 token 刷新。
身份驗證在連線時發生 — client 傳送帶有 JWT token 的 authenticate 訊息。伺服器驗證後開始接受工具呼叫。
Heartbeat 在應用層每 15 秒執行一次(不依賴 WebSocket 協定的 ping)。如果 pong 在 5 秒內未到達,連線會被視為中斷並開始重新連線。
自動重連在斷線時使用 3 秒延遲搭配指數退避。Token 刷新會在 JWT 過期前 5 分鐘透過 REST endpoint 主動進行,因此連線永遠不會因為憑證過期而中斷。
工具執行器管道
所有工具都繼承自 BaseBrowserToolExecutor 類別,該類別提供通用輔助方法:injectContentScript() 搭配 ping/pong 去重複、sendMessageToTab()、getActiveTabOrThrow() 和分頁焦點管理。
工具分為幾個類別:
頁面互動 — click_element、fill_form_field、select_dropdown、check_box、scroll_page 和 navigate。這些透過 CSS 選擇器或自動生成的參考 ID 來識別 DOM 元素進行操作。
內容讀取 — read_page 解析 DOM 並為互動元素分配穩定的參考 ID。這就是 AI「看到」頁面的方式 — 它獲得帶有可點擊參考的結構化文字,而不是原始 HTML。
平台專用提取器 — web_fetcher 具有針對 Gmail、Slack、Jira、Salesforce、ServiceNow 和 HubSpot 的專門解析器。這些解析器不是通用的 DOM 抓取,而是理解每個平台的標記結構並提取乾淨、具型別的資料。
瀏覽器內部功能 — javascript 透過 Chrome DevTools Protocol Runtime.evaluate 執行任意程式碼、network_capture 監控 HTTP 流量、screenshot 擷取視窗或特定元素,以及 gif_recorder 建立多步驟互動的動畫錄製。
注入腳本:在頁面世界中執行
架構中最棘手的部分是注入腳本。Content script 在隔離的世界中執行 — 它們可以讀取 DOM,但無法存取頁面的 JavaScript 情境、React 元件狀態或框架內部。
我們有 16 個 TypeScript 模組,透過自訂 esbuild plugin 打包為 IIFE,並注入到 MAIN 世界中。這讓它們能夠存取 React 內部、呼叫頁面層級的 API,並與單頁應用程式路由器互動。
注入使用 ping/pong 去重複來避免將相同腳本注入到分頁兩次,結果透過 window.postMessage 流回 content script,然後再傳到 background worker。
我們學到的經驗
Manifest V3 service worker 是短暫的。 它們可能隨時被瀏覽器終止。我們必須讓 WebSocket 連線能夠從 service worker 重啟中恢復 — 在不丟失待處理工具呼叫的情況下透明地重新連線。
平台專用解析勝過通用抓取。 我們的第一版對所有內容都使用通用 DOM 提取。Gmail 的 HTML 巢狀結構很深,並且在更新之間會變化。為每個平台(目前有 6 個)編寫針對性的解析器,大幅提升了可靠性和資料品質。
MCP 是個很適合這個用途的協定。 基於 JSON-RPC 2.0 的基礎,配合 tools/list 發現和具型別的 tools/call 呼叫,實作起來足夠簡單,但結構化程度足以保持可靠。我們發現它比建立自訂協定更容易擴充。
接下來的計畫
我們正在努力擴充平台專用處理器,改善跨單頁應用程式導航的元素定位可靠性,並探索與更廣泛的 MCP 生態系統共享工具定義的方法。
如果你正在打造 MCP 整合或瀏覽器自動化工具,我們很樂意聽聽你發現哪些模式有用。這個協定仍然年輕,社群正在一起摸索最佳實踐。