我最近同時在跑三個 AI coding agent:Claude Code 處理主線任務,Codex 負責救援型除錯,另外還有一套自建的 Hermes 閘道在背景跑。但三個都開在各自的終端機視窗裡,彼此看不到對方在做什麼。當其中一個 agent 需要另一個的輸出、或是我想讓 Codex 去確認 Claude Code 剛剛改的東西有沒有效,唯一的辦法就是我自己在中間複製貼上。
兩個 agent 的時候這樣搞還撐得住。但三個以上,人肉訊息匯流排這件事就開始失控:切視窗切到眼花,貼錯地方,漏看某個 agent 已經在等你回應半天。
這篇文章記錄我怎麼用 tmux-bridge-mcp 解決這個問題,包含把它裝進 Claude Code 和 Codex 之前做的安全審查(這步驟其實比裝起來還花時間),裝完之後順手把 Codex 接上本地跑的 oMLX 模型的過程,再來是後續實際跨三個不同 agent 做的端到端驗證(過程中還意外發現一件值得警惕的事),最後補上一段多 pane/多視窗環境調校的心得,這是任何想同時開多個 agent 的人幾乎必然會撞到的痛點。
實測環境:以下所有版本號、耗時、終端輸出都是 2026 年 7 月 7 日當天實際跑出來的紀錄,當時的環境是 grok CLI
0.2.87-mac、Codex CLI0.142.5(雲端帳號預設gpt-5.5)。這些工具版號更新得很快,你現在跑起來的數字八成跟我不一樣。我保留原始數字而不是回頭改成最新版,是因為這篇的價值在於「當時真的踩到了什麼」,不在於版號好不好看。
問題:agent 各自關在自己的終端裡
MCP(Model Context Protocol)本身已經解決了「agent 怎麼呼叫外部工具」這件事,Claude Code、Codex、Gemini CLI、Kimi CLI 都原生支援。但 MCP 沒有內建「讓 agent A 讀寫 agent B 所在的終端機」這種能力,因為兩個 agent 通常是兩個完全獨立的 process,各自的 session 互不相通。
如果 agent 都跑在 tmux 的不同 pane 裡,理論上是可以用 tmux 本身的指令(send-keys、capture-pane)去跨 pane 操作的。所以缺的只是一層「把這些指令包裝成 agent 能呼叫的標準工具」。這正是 tmux-bridge-mcp 在做的事。

tmux-bridge-mcp 是什麼
tmux-bridge-mcp(github.com/howardpen9/tmux-bridge-mcp,npm 套件同名,MIT license,作者 howardpen9,31 stars,2026 年 3 月建立)是一個 standalone 的 MCP server。它提供 9 個 tool:
tmux_list:列出目前有哪些 tmux session/window/panetmux_read:讀取某個 pane 目前顯示的內容tmux_type:把文字打進某個 pane(不含送出)tmux_message:跟tmux_type類似,但會自動加上寄件人資訊tmux_keys:送出按鍵(例如 Enter、Ctrl-C)tmux_name:幫 pane 命名,方便之後用名稱而非座標定位tmux_resolve:把名稱解析回實際的 pane 座標tmux_id:查詢目前呼叫者自己所在的 pane idtmux_doctor:檢查 tmux 環境是否正常
運作方式很直接:呼叫這些 tool 的那一端(例如 Claude Code)需要支援 MCP client,但被讀寫的目標 pane 完全不需要懂 MCP,只要是個活著的終端 process 就行。因為實際送鍵盤輸入的動作,是 tmux-bridge server 自己對著那個 pane 執行 tmux send-keys,跟你自己手動打字進那個視窗沒有本質差別。
也就是說,只要 Claude Code 這邊裝了 tmux-bridge-mcp,它就能讀寫隔壁 pane 裡跑的 Codex,即使 Codex 那邊完全沒裝任何 MCP server。這是理解這個工具風險模型的第一個關鍵:能力不對等,裝的那一端擁有的是「操控」對方 pane 的能力,而非雙方協商後的溝通。

核心心智模型:read-act-read
用起來的標準流程是這樣:
tmux_read(target):先讀一次目標 pane 現在顯示什麼tmux_message(target, text):把訊息打進去(還沒按 Enter)tmux_read(target):再讀一次,確認文字真的正確打進去了tmux_keys(target, keys=["Enter"]):按下 Enter 送出- 不主動去 poll 對方有沒有回,等對方自己把回覆打進發話者的 pane
步驟 1 不是可有可無的習慣,而是工具本身內建的「read guard」機制:tmux_type/tmux_message/tmux_keys 都會檢查呼叫者是不是已經先讀過該 pane,沒讀過會直接報錯拒絕執行。也正因如此,設計意圖是逼你先看清楚目標 pane 現在的狀態再動手,不能盲打。
但這裡有個很重要、也是我在做安全審查時花最多時間確認的細節:這個 read guard 只是操作順序上的防呆提醒,不是安全邊界。作者自己在文件裡也是這樣講的。呼叫端只要先隨便讀一次目標 pane(哪怕讀到的內容跟接下來要打的東西毫無關係),guard 就會放行。它擋不住「這段文字到底該不該送出去」這個問題,只確認了「你有沒有看過一眼」。
這個限制決定了這個工具能不能安全地用在哪些場景,下一節細說。
為什麼要先做安全審查
工作區的規範是新工具、新 MCP 安裝前必須先過安全審查,不能只憑自己讀一遍 source code 就覺得沒問題裝下去。這次因為工具本身牽涉「讓一個 agent 對另一個 agent 的終端送出等同人類鍵盤輸入的內容」,風險模型比一般的唯讀型 MCP 工具複雜,所以委派給專職的 agency-security-engineer agent 做正式審查,而不是自己隨便看看。
審查怎麼做的:
- 把 GitHub 上的原始碼 clone 到本機
- 用
npm pack把實際發布到 npm registry 的版本拆開,逐檔跟 GitHub 原始碼比對是否一致(這一步是防「原始碼乾淨,但實際發布的版本被動過手腳」這種供應鏈攻擊,GitHub 上看起來乾淨不代表你npx裝下來的東西一樣乾淨) - 掃
package.json有沒有postinstall/preinstallhook - 逐檔確認所有執行外部指令的地方是不是都用
execFile(bin, [陣列參數])這種形式,而不是把參數拼接成字串再丟給 shell(前者杜絕 shell injection,後者只要有一個地方沒把使用者輸入跳脫乾淨就容易被注入) - 掃有沒有偷偷藏的網路呼叫或遙測
結論是有條件核准。程式碼本身確實乾淨:依賴只有 @modelcontextprotocol/sdk 和 zod 這兩個知名套件、沒有 postinstall、沒有混淆過的程式碼、沒有遙測、所有 exec 呼叫都是陣列參數形式、npm 發布版跟原始碼逐檔一致。
但「有條件」的條件,來自這個工具「本質設計」帶來的結構性風險,跟程式碼寫得好不好無關:它讓任一 agent 能對另一個 agent 的 pane 送出等同人類鍵盤輸入的內容,包含按 Enter 送出。而前面講的 read guard 又只是順序提醒不是安全邊界,呼叫端只要先讀一次就能繞過。
具體風險場景是這樣的:如果某個 agent 從不可信來源(一個網頁、一封 email、某個第三方 API 回應)讀進一段文字,而這段文字裡藏著誘導性的指令,agent 被誘導把這段文字原封不動轉發給另一個 pane,就等於繞過了那個 pane 所屬 agent 自己的工具核准機制。換句話說,這是一種 prompt injection 鏈的攻擊面:注入不需要直接打進被攻擊的 agent,只要能借道另一個 agent 的手就行。
核准附帶的四項緩解措施
基於這個風險模型,審查核准附帶四項緩解措施,我照單全收:
第一,版本 pin 死。 兩邊設定檔都固定用 tmux-bridge-mcp@0.3.0,禁止用會自動抓最新版的 npx -y tmux-bridge-mcp(不帶版本號)。之後要升版,得先手動讀過新版跟舊版之間的原始碼 diff,確認沒有引入新的風險行為,才手動改版本號升級。
第二,獨立 tmux socket。 用 TMUX_BRIDGE_SOCKET 環境變數指定一個專屬的 socket 路徑(例如 /tmp/tmux-agents-<user>.sock),不要讓這個工具去碰機器預設或全域的 tmux server。這樣即使真的出了什麼狀況,影響範圍也只限於這個專屬 session 裡的 pane,不會波及我手動操作用的其他 tmux session。
第三,不用在敏感協作場景。 不用在處理第三方或客戶敏感資料的場景,例如有外部成員在場的公司群組協作場景。
第四,不可信來源的內容禁止未經人工過目直接轉送。 網頁抓取結果、email 內容、第三方 API 回應這類不可信外部來源的文字,不能未經人工看過就直接丟給 tmux_message/tmux_type 轉送到另一個 pane。tmux_keys 也不可以代替使用者對「刪除、force push、金鑰操作」這類不可逆動作按下 Enter 確認,這類確認永遠要回到操作者自己的核准流程,不能被鍵盤注入代勞。
這四條裡,第四條是我覺得最容易被忽略、卻最重要的一條。前三條都是「限縮攻擊面」,但第四條是直接點名「哪些動作絕對不能讓這個工具代勞」。

安裝步驟
環境若還沒裝 tmux,先裝上:
brew install tmux
接著在兩邊各自掛上版本 pin 死的 MCP server,並共用同一組專屬 socket。
Claude Code 端在專案 .mcp.json 加一個 server 條目,重點是 args 一定要帶版本號,以及 TMUX_BRIDGE_SOCKET 指向專屬 socket:
{
"mcpServers": {
"tmux-bridge": {
"command": "npx",
"args": ["-y", "tmux-bridge-mcp@0.3.0"],
"env": {
"TMUX_BRIDGE_SOCKET": "/tmp/tmux-agents-<user>.sock"
}
}
}
}
Codex 端可用內建指令自動寫入設定:
codex mcp add tmux-bridge -- npx -y tmux-bridge-mcp
這會把條目寫進 ~/.codex/config.toml,但指令本身不支援直接帶版本號,寫完後要手動補上版本 pin 與同一組 TMUX_BRIDGE_SOCKET,確保兩邊指向同一個 socket。
建立專屬 session時,對那個 socket 起一個 agents session、左右分割,再幫 pane 掛上 @name(也可用 MCP 的 tmux_name,初次搭建用原生指令通常更直觀):
tmux -S /tmp/tmux-agents-<user>.sock new-session -d -s agents -n main
tmux -S /tmp/tmux-agents-<user>.sock split-window -h -t agents:main
tmux -S /tmp/tmux-agents-<user>.sock set-option -p -t agents:main.0 @name claude
# 其餘 pane 同理掛 @name codex 等
Claude Code 需要重新啟動才會讀到新的 .mcp.json,從專案根目錄重新執行 claude 即可,不是單純 reload。
順手處理的另一件事:Codex 接本地模型
裝 tmux-bridge 的同時,我還想讓 Codex 能用 codex --profile omlx 切到本地 oMLX 模型伺服器,跑在 127.0.0.1:8090,模型是 unsloth 的 Qwen3.6-35B-A3B 4bit 量化版。這跟 tmux-bridge 沒有直接關聯,但同一次環境整理一起搞定,順帶記踩到的坑。
用舊式寫法在 config.toml 加 [profiles.omlx] 區塊,結果 Codex CLI 0.142.5 直接報錯,說不能同時存在 legacy profile table,要求把 profile 移到獨立檔案。新版做法是每個 profile 各自一個檔,命名規則 ~/.codex/<profile名>.config.toml。
折騰一陣子才發現,獨立檔案(omlx.config.toml)其實早就存在而且設定完全正確,只是之前 ls 輸出被截斷,根本沒看到它。核心欄位大概長這樣:
model_provider = "omlx"
model = "unsloth--Qwen3.6-35B-A3B-UD-MLX-4bit"
model_reasoning_effort = "high"
用 codex exec --profile omlx --skip-git-repo-check "reply with exactly the word: pong" 測串接,本地模型正確回了 pong。教訓跟工具本身無關:先確認檔案是不是真的不存在,再開始改設定,免得白繞一圈。
端到端驗證:管線通不通,以及一個意外發現
沒辦法真的同時開兩個活的 Claude Code/Codex session 一邊操作一邊拍給你看整條 MCP 鏈路,所以改用等價手法,直接驗證管線本身(tmux 讀寫層 + 目標 agent 層)是不是通的。
第一輪先測 codex 接本地 oMLX:在 codex pane 跑 codex --profile omlx,再用跟 MCP tool 相同的底層序列操作:tmux send-keys -l 打字但不按 Enter,capture-pane 確認文字有進去,再 send-keys Enter。測試訊息是 reply with exactly the word pong,本地 35B-A3B 正確回了 pong。互動模式下這次花了超過一分鐘才回,比 codex exec 非互動模式的秒級回應慢很多;若你也要用 tmux-bridge 串本地模型,延遲落差要有心理準備,不要以為卡住就是管線壞掉。
後來把驗證往前推:跨三個掛在不同 pane 的本地/本地化 agent 各送一次真實訊息,看「打字→送出→讀回覆」在不同 CLI 上有沒有各自的坑。
動手前先用 claude mcp list 查這次 session 有沒有真的接上 tmux-bridge-mcp。結果 process 雖在背景跑(npm exec tmux-bridge-mcp@0.3.0),卻沒出現在這次 session 的 MCP 連線清單;process 存在不等於被接上、能被 tool 呼叫。驗證 MCP 整合不能只看相關 process 是否在跑,一定要用 client 自己的清單指令確認連線狀態。
因為這次沒真的掛上,我改用底層邏輯一致的原始手法繼續:直接 tmux send-keys 打字、tmux capture-pane 讀回。驗證的是同一套 read-act-read 管線,只是繞過 MCP 封裝;對「管線通不通」結論站得住,對「MCP 封裝有沒有被接上」答案是誠實的否定。
依序測了三個 pane:
(a) codex(--profile omlx,本地 oMLX)。 送出中文測試訊息後,第一次 tmux send-keys ... C-m 沒真的送出,文字進了輸入框卻停著。原因是 codex 的 TUI 把整段貼上的中文當成 bracketed paste(終端機協定裡用特殊 escape 包住「這是一次貼上,不是逐字打」)處理,需要再補送一次 Enter 才會提交:不是第一次 Enter 沒生效,而是被吃掉去結束貼上狀態。補送後 codex 正確回覆確認收到。
(b) agy(Antigravity CLI,模型 Gemini 3.5 Flash)。 一樣先卡在「文字進框但沒送出」,補送 Enter 後才觸發;拿到的卻是個人額度用完、約 25.5 小時後重置的提示。這反而證明 bridge 本身沒問題:訊息有送達、agy 也執行到處理請求,失敗點在帳號額度而非 tmux 橋接層。之後順手按 0 跳過意見回饋提示,讓 pane 恢復待命。
(c) grok(grok-0.2.87-mac CLI,Composer 2.5)。 這次沒卡在補 Enter,一次送出就進入處理(「Waiting… 4.9s」),9.4 秒後 Turn completed,回覆確認收到。小插曲是 grok 那個 pane 只有 39 字元寬,capture-pane 抓回的畫面把回覆截斷了;改用 cat -A 看原始輸出(含跳脫序列)才還原完整內容。窄 pane 被截斷時,不必真的去 resize,capture-pane 原始輸出仍含完整字元,只是顯示時被換行/截斷。
三次測試小結:
| Pane | 工具 | 結果 |
|---|---|---|
| codex(oMLX 本地模型) | 需補一次 Enter 才送出(bracketed paste),之後正常回覆 | |
| agy(Antigravity/Gemini 3.5 Flash) | 需補一次 Enter,額度用完(非橋接問題) | |
| grok(grok-0.2.87-mac) | 一次送出即正常處理並回覆 |
這次驗證證明了 tmux 層讀寫時序、read guard 行為邏輯,以及三個完全不同的目標 pane(本地模型 Codex、雲端 Gemini 的 Antigravity、grok CLI)串起來是通的。MCP tool 做的事,就是把這整套動作包成 agent 能呼叫的標準介面,底層沒有魔法。但也正因順手查了連線清單才發現 MCP server 沒真的掛上,提醒我:「工具裝好了、process 也在跑」離「真的能用」中間還有一步查核不能省。
附錄:讓多 pane/多視窗好用的環境調校
裝完 tmux-bridge、測完三個 agent 之後,又花了點時間把多 agent 終端環境本身調順手。這些跟 tmux-bridge-mcp 沒有直接關係,但只要同時開多個 agent、多個 pane 或視窗,幾乎必然會撞上同一批問題。
Shift+Enter 在 tmux 裡沒辦法換行
我的終端機是 Ghostty,搭 tmux 3.7b。原本在 tmux 裡用 Claude Code,按 Shift+Enter 沒辦法換行,只會直接送出。
診斷下來,問題出在 tmux 的 extended-keys。預設是 on,意思是 tmux 會靠偵測 terminfo(終端機能力描述資料庫)裡的能力宣告,決定要不要把終端機送出的擴充按鍵回報(像 Shift+Enter 這類修飾鍵組合,用一般 escape 表達不了,需要 CSI-u 這類擴充協定)轉發給裡面的程式。Ghostty 這種較新的終端常常沒被 tmux 正確偵測到具備此能力,導致 tmux 乾脆不轉發,Shift+Enter 訊號就被吃掉。
修法是在 ~/.tmux.conf 開頭強制開啟轉發,並針對終端名稱明確宣告 extkeys,不要只靠 xterm* 萬用字元碰運氣:
set -s extended-keys always
set -as terminal-features 'xterm*:extkeys'
set -as terminal-features 'ghostty*:extkeys'
關鍵眉角:光 tmux source-file reload 不保證生效,因為 extended-keys 的協商跟 client 連線狀態有關,detach 後重新 attach(或關掉終端重開)最保險。detach 重連後測試,Shift+Enter 已確認換行正常。
但後來這功能又無聲無息壞過一次,而且 detach/reattach 完全沒用,真正兇手不是協商沒重跑,而是 ~/.tmux.conf 裡多了兩行看似合理、實則互相拆台的綁定:
bind-key -T root C-Enter send-keys Enter
bind-key -T root S-Enter send-keys Enter
意圖是「把 Ctrl+Enter/Shift+Enter 映射成換行」,但 send-keys Enter 實際上只會送出普通 Enter,等於在 tmux 這層就把修飾鍵資訊吃掉、轉成跟純 Enter 一樣的訊號給裡面的 Claude Code,結果永遠只會送出、不會換行。用 tmux list-keys -T root | grep -i enter 查最準;只要這兩行還在,怎麼 detach/reattach、重開 Ghostty 都沒用,因為問題在 tmux 主動攔截,不在 terminal 協商。
而且 bind-key 一旦生效過,不會因為你把該行從 .tmux.conf 刪掉就自動消失,活著的 tmux server 得手動解除:
tmux list-keys -T root | grep -i enter
tmux unbind-key -T root C-Enter
tmux unbind-key -T root S-Enter
解除後不用 detach,當場立刻生效。換句話說:extended-keys 的協商問題用 detach/reattach 排查,綁定攔截用 list-keys/unbind-key 排查,兩種故障模式長得很像(都是「Shift+Enter 送出而不是換行」),但根因完全不同。這條規則也回過頭來提醒:不要為了「多加保險」而手動綁 S-Enter/C-Enter 去 send-keys Enter;什麼都不綁,讓上面的 extended-keys/terminal-features passthrough 原始序列給 App 自己判斷,才是正解。
新視窗/分割窗固定綁定在 workspace 目錄
開新的 tmux 視窗或分割窗時,預設會沿用目前 pane 的路徑,人在深層子目錄裡開新視窗,新視窗也常卡在那個深層路徑。我想要的是不管在哪裡開,都直接落在 workspace 根目錄(~/workspace)。
較新版 tmux 已拿掉全域 default-path,做法改成覆寫建立視窗/分割窗的按鍵綁定,用 -c 帶目標路徑。限制只對「透過這些綁定建立的視窗」生效;若直接下 tmux new-window/tmux split-window,不會套用。
一個視窗塞四個 pane 太擠,改成四個獨立視窗
測完前面三個 agent 之後,同一個視窗裡塞了 4 個 pane(main/codex/agy/grok 全用 split-window 擠在一起),畫面被切得很碎。解法是改用 tmux 的視窗(window)而非分割窗(pane):同一時間只顯示一個,背景持續在跑,適合「只專注看其中一個,其他先待命」。用 tmux break-pane 把 codex/agy/grok 各自拆成獨立視窗並 rename,Claude Code 留在 window 1(main)當主畫面;session 沒斷,切過去就能看到最新狀態。底部 status bar 會列出各視窗名,滑鼠或 prefix+數字 都能切。
免按 prefix 的視窗切換快捷鍵
prefix+數字 能切視窗,但每次都要先按 prefix(預設 Ctrl-b)再按數字,切換頻繁時有點煩。做法是在 ~/.tmux.conf 加不需 prefix 的根層綁定(M-1~`M-n` 對應 Meta/Alt+數字),並在 Ghostty 端把實際想按的實體組合轉成 tmux 認得的序列。
我的 Ghostty 本來就有 macos-option-as-alt = left(左 Option 送 Alt/Meta,右 Option 保留特殊字元),照理左 Option+14 應能切視窗,但實測沒反應,於是改成 Option+Command+15。卡關原因是:macOS 的 Cmd(Super)本質上不屬於終端機協定的標準修飾鍵,到達 Ghostty 前往往已被 App 內建快捷鍵吃掉(例如預設 super+15 可正常切換。super+9 切分頁),不會被編碼成 escape 送進 shell/tmux。要讓 Option+Command+數字 真的送出 tmux 認得的訊號,必須在 Ghostty 設定裡明確定義這個組合要送出什麼;可用內建 esc: action(格式 esc:text)把 Option+Command+N 轉成「ESC + N」,正好等同 tmux 的 M-N,因此 tmux 端不必改綁定語意。改完後用 Ghostty 的 reload-config 快捷鍵重載,實測 Option+Command+1
路徑固定、視窗切換、Ghostty 轉譯可以收成一組示意(依你的 workspace 路徑與視窗數自行擴充):
# ~/.tmux.conf 示意:新窗固定路徑 + 免 prefix 切窗
bind-key c new-window -c "~/workspace"
bind-key '"' split-window -c "~/workspace"
bind-key % split-window -h -c "~/workspace"
bind-key -n M-1 select-window -t 1
bind-key -n M-2 select-window -t 2
# M-3~M-5 同理;Ghostty 端 Cmd 不進終端協定,改送 ESC+數字
keybind = alt+super+1=esc:1
keybind = alt+super+2=esc:2
# alt+super+3~5 同理
追加第 5 個視窗:雲端版 codex 跟本地版並存
四個視窗跑順後,又追加第 5 個視窗跑「雲端版」codex(預設 model,不帶 --profile omlx),跟 window 2 的本地 oMLX codex 是兩個獨立 process,刻意並存方便比較。建立時用 tmux new-window 指定名稱與 ~/workspace 當工作目錄,再送 codex 啟動;畫面上確認是 Codex v0.142.5,directory 落在 ~/workspace,模型列隨後顯示 gpt-5.5 default。
有個細節值得記:這個雲端帳號一啟動就顯示週額度只剩不到 10%,跟前面 agy 額度打滿是同一類提醒。本地模型跟雲端並存的實際好處是:雲端額度見底時,本地那邊還能撐著,整條工作流不至於一起卡住。tmux 與 Ghostty 兩邊各補上第 5 組切換鍵即可,做法跟 1~4 完全一致。
目前完整的視窗配置:
| 視窗 | 內容 | 切換鍵 |
|---|---|---|
| 1: main | Claude Code | Option+Cmd+1 |
| 2: codex | codex --profile omlx(本地 oMLX) | Option+Cmd+2 |
| 3: agy | Antigravity CLI | Option+Cmd+3 |
| 4: grok | grok-0.2.87-mac | Option+Cmd+4 |
| 5: codex-cloud | codex(雲端 gpt-5.5 default) | Option+Cmd+5 |
小結
tmux-bridge-mcp 解決的問題很實際:多個 AI agent 各自關在自己的終端裡,靠人工複製貼上當訊息匯流排,這件事在 agent 數量一多就會垮掉。它的做法也很單純,就是把 tmux 原生的讀寫能力包成標準 MCP tool。
但這種「讓 agent 直接操控另一個 agent 終端」的能力,天生就帶著結構性風險,而且風險不會因為程式碼寫得乾淨就消失。真正能守住這條線的,是使用清單上那四條緩解措施,尤其是最後一條:不可信來源的內容不能未經人工過目就轉送,不可逆動作的確認永遠留給操作者自己。工具能幫你省掉重複的複製貼上,但不能替你做這些判斷。
實際跑過三個不同 agent 的端到端測試之後,還多學到一件事:MCP server process「有在跑」不等於「有被接上」,這是查核 MCP 整合時最容易漏掉的一步,所以值得養成習慣每次都用 client 自己的清單指令確認一次。而多 agent 環境本身的終端調校,換行、路徑、視窗佈局、快捷鍵,雖然瑣碎,卻是讓這整套多 agent 工作流真正好用起來不可或缺的最後一哩路。
常見問題
tmux-bridge-mcp 跟直接用 tmux 原生指令有什麼差別?
差別在於「介面標準化」。你原本就可以用 `tmux send-keys`、`tmux capture-pane` 這些指令手動或寫腳本去跨 pane 操作,tmux-bridge-mcp 沒有新增任何 tmux 本身做不到的能力。它做的事情是把這些操作包裝成 MCP tool,讓支援 MCP 的 agent(Claude Code、Codex、Gemini CLI、Kimi CLI 等)可以直接呼叫,不用你自己再寫一層轉接程式碼。方便性換來的代價,是這個能力被打包成一個「agent 可以自己決定要不要用」的工具,而不是只有人類手動觸發。
read guard 機制既然可以被繞過,那裝這個工具的意義是什麼?
read guard 擋不住惡意或被誤導的呼叫,但它確實能防住「agent 沒看清楚現況就手滑打錯地方」這種操作失誤,這在日常使用裡其實是最常發生的情況。真正的安全底線不是靠這個機制,而是靠審查核准的四項緩解措施,尤其是「不可信來源的內容不能未經人工過目直接轉送」跟「不可逆動作不能被鍵盤注入代按確認」這兩條。工具負責省掉重複的手工轉發,人負責守住哪些內容跟哪些動作絕對不能自動化。
一定要用獨立的 tmux socket 嗎?可以直接用預設的 tmux server 嗎?
技術上可以,但審查核准時明確要求要用獨立 socket(`TMUX_BRIDGE_SOCKET` 環境變數指定路徑,例如 `/tmp/tmux-agents-<user>.sock`)。理由是縮小影響範圍:如果哪天真的發生前面講的 prompt injection 鏈這種狀況,問題會被限制在這個專屬 session 裡的 pane,不會波及你手動操作、放著日常工作的其他 tmux session。多一道 socket 隔離,成本幾乎是零,但能避免一次意外殃及整個工作環境。
tmux-bridge-mcp 支援哪些 agent?
任何原生支援 MCP client 的 agent 都能用,包含 Claude Code、Codex、Gemini CLI、Kimi CLI。但注意前面提過的能力不對等:只有裝了 tmux-bridge-mcp 這一端才具備「讀寫其他 pane」的能力,被讀寫的目標 pane 完全不需要支援 MCP,只要是個活著的終端 process 就行,可以是另一個沒裝任何 MCP server 的 CLI 工具,甚至是一般的互動式 shell。
文章裡提到 Codex 接 oMLX 本地模型那段,跟 tmux-bridge-mcp 有關嗎?
沒有直接關聯,是同一次環境整理時順手一起處理的需求。放進同一篇的原因是兩件事都牽涉到「多個 agent/後端協作」這個大主題,而且後面驗證 tmux-bridge 管線通不通的時候,剛好就是拿這個接好本地模型的 Codex pane 當測試對象。如果你只關心 tmux-bridge-mcp 本身,跳過本地模型那段完全不影響安裝跟使用。