Ian Chou's Blog

OS 裡實際發生了什麼事? (Process Tree & Pipes)

OS 裡實際發生了什麼事? (Process Tree & Pipes)

沒錯,完全正確。在 OS(特別是您的 Ubuntu 環境)層級來看,這就是標準的 Process Tree(行程樹) 結構。

當您在 Cursor 或 Claude Desktop 裡掛載這個 MCP Server 時,OS 裡實際發生的事情如下:

1. 行程關係 (Process Relationship)

Cursor 應用程式(Parent Process)會呼叫系統指令(類似 fork() + exec() 或 Node.js 的 spawn)來啟動您的 Bun/Node 程式(Child Process)。

如果您在 Ubuntu 終端機下指令 pstree -p,您會看到類似這樣的階層:

systemd(1)───...───Cursor(1234)───bun(5678)───server.ts

2. 資料流向 (The "Pipes")

這裡最關鍵的是 Parent 如何把它的「嘴巴」接到 Child 的「耳朵」上。OS 會建立 匿名管線 (Anonymous Pipes) 來對接 File Descriptors (FD):

OS 層級 File Descriptor 誰擁有 對接方向 用途
FD 0 (stdin) Child (Server) Parent 寫入 ➡️ Child 讀取 Parent 發送 CallTool("add") 指令進來
FD 1 (stdout) Child (Server) Child 寫入 ➡️ Parent 讀取 Server 回傳 { result: 300 } 出去
FD 2 (stderr) Child (Server) Child 寫入 ➡️ Parent 監聽 Server 印出 console.error (Log),Parent 顯示在 Debug 面板

3. 為何這對開發者很重要?

既然您熟悉 Node.js 架構,這解釋了兩個常見的 MCP 開發地雷:

  1. Zombie Processes (殭屍行程):
    如果 Parent 當機(Crash)但沒有正確釋放 Child,您的 bun 程式可能會變成孤兒行程留在背景佔用記憶體,直到您手動 kill -9 殺掉它。

  2. Dirty Stdout (污染標準輸出):
    這就是為什麼我在上一段強調 絕對不能用 console.log

    • 因為 stdout (FD 1) 是 "Data Channel" (純 JSON)。
    • console.error (FD 2) 是 "Side Channel" (純文字日誌)。
    • 如果您在 stdout 裡混入了 console.log("Debug info"),Parent 那一端在做 JSON.parse() 時就會炸開,導致連線中斷。

下一步建議

既然您瞭解這是 Process 層級的管線通訊,開發時最痛苦的就是「看不到管線裡傳了什麼 JSON」。

您是否需要我介紹 MCP Inspector?這是一個官方提供的網頁介面工具,它會充當「中間人 (Proxy)」,讓您在瀏覽器上直接看到 Parent 和 Child 之間來回傳送的每一條 JSON 訊息,非常適合 Debug。