Claude Code MCP 重複啟動問題規劃報告

主題:多個 Claude session 反覆啟動 MCP 的根因、解法評估、專案比較與混合式部署方案

這份報告整理了目前對你環境的分析結果,目標是解決:Claude Code 多個 session 反覆啟動相同 MCP server,造成記憶體與程序數量膨脹。報告同時納入你關心的部署現實:是否一定要 Docker、是否會打架、如果隔離部署,MCP 服務應該如何整合

問題核心:stdio MCP per-session 重複啟動 重點:不是所有 MCP 都適合容器化 建議:先採 Host-first 混合式方案
Claude 主程序真實佔用
約 3.64 GiB PSS
Python / uv / MainThread 類
約 4.6 GiB RSS 熱點
Claude 相關 MCP 子程序
65 個相關程序
Codex session 樹狀佔用
約 0.81 GiB RSS
目標
shared backend + light proxy

一、問題定義

目前你的 Claude Code 工作模式會同時保留多個 session,而每個 session 都會依照 .claude.json 中的 mcpServers 設定,各自啟動一份 stdio MCP server。這不是單一 bug,而是目前 stdio transport 的自然結果。

問題本體不是「Docker 要不要用」,而是:如何把重型 MCP backend 從 per-session 啟動,改成 shared singleton daemon

二、目前觀察到的 MCP 類熱點

服務類型程序數約略 RSS解讀
grok-search MCP server22約 1347.9 MiB查詢型服務,最適合先做共享化。
DrissionPage MCP server22約 800.9 MiB狀態型服務,最容易打架,不適合先粗暴共享。
contextweaver mcp7約 684.8 MiB讀多寫少,適合 daemon 化共用。
gemini-image-generator MCP server7約 592.5 MiB可共享,但要有併發與輸出隔離。
github-pages MCP server7約 354.5 MiB不是最大 RAM 熱點,但有外部副作用。
Codex session trees2 個活躍 session約 809.1 MiB每個 Codex session 也會各自帶起自己的 MCP 子程序樹,與 Claude 的問題在結構上相同,但目前規模較小。

三、官方與架構層結論

  1. Claude Code 目前沒有內建跨 session singleton MCP 設定。
  2. stdio MCP 在當前設計下是 per-session 啟動。
  3. 若要避免重複啟動,必須在 Claude 與真正 MCP backend 之間引入一層輕量 proxy / fabric。
  4. 重型 backend 再由平台層常駐管理,而不是由每個 Claude session 自己負責啟動。
  5. Codex 目前也呈現相同結構:兩個活躍 Codex session 總共約 809.1 MiB RSS,並且每個 session 都會各自帶起 grok-searchDrissionPageMCP 子程序。因此這不是 Claude 專屬現象,而是多個 agent/CLI 對 stdio MCP 的共同模式。

四、方案總覽:不是「Docker or not」,而是「Host-first mixed architecture」

Claude Session ── stdio ──> light proxy ──> local MCP fabric/router ──> shared backend

這個 shared backend 可以:

因此正確的設計不是「所有 MCP 都放 Docker」,而是:

  1. 先定義哪些 MCP 適合共享。
  2. 再決定它們共享後要跑在 Host 還是 Docker。
  3. Claude 端一律維持 stdio + proxy,減少相容性成本。

五、完整混合式整合架構圖

Claude Sessions
    │
    ▼
lightweight MCP proxies (host)
    │
    ▼
Local MCP Fabric / Router (host-native daemon)
    │
    ├── Host-native services
    │     ├── contextweaver-daemon
    │     ├── github-pages-daemon
    │     └── drission-orchestrator
    │
    └── Optional containers
          ├── grok-search-daemon
          └── gemini-image-daemon
Host 與 Docker 在這裡不是互斥,而是依服務屬性分工

六、哪些先放 Host,哪些可考慮容器化

MCP建議位置原因是否先容器化
contextweaverHost要讀本機 repo,路徑與權限在主機上最自然。
github-pagesHost依賴本機 gh/git 認證環境。
DrissionPageMCPHost依賴本機瀏覽器、GUI、debug port、下載路徑。否,且不建議早期容器化
grok-searchHost 或 Docker查詢型、弱狀態、最容易做 singleton。可考慮
gemini-image-generatorHost 或 Docker可共享,但要控制輸出與併發。可考慮

七、為什麼不是全 Docker

你提出的顧慮是正確的:如果全 Docker 化,就會帶來每個服務都要額外部署、維護與整合的成本。雖然那不是每個 Claude session 都部署一次,但仍然是每個 backend 一份部署責任。

全 Docker 的問題

因此更合理的順序

  1. 先用 Host-native daemon 驗證共享架構是否有效。
  2. 只把真正有依賴治理需求的 backend(例如 grok-searchgemini-image-generator)選擇性容器化。

八、如果採隔離部署,MCP 服務如何整合?

這裡的關鍵不是讓 Claude 直接碰容器,而是讓 Claude 仍然只碰 stdio proxy。

Claude Code -> stdio proxy -> host router/fabric -> containerized backend

責任分工

這樣的好處

九、Codex 是否也有同類問題?

有,而且在結構上與 Claude 的現象一致,只是目前規模較小。

項目觀察結果
活躍 Codex session2 個
Codex session tree 總 RSS約 809.1 MiB
Session A tree約 318.8 MiB,包含 codex + grok-search + DrissionPageMCP
Session B tree約 490.3 MiB,包含 codex + grok-search + DrissionPageMCP
結論Codex 也存在 per-session 啟動 MCP 子程序的模式,因此未來若要平台化,不應只解 Claude,也應把 Codex 納入同一個 local MCP fabric 設計。
這代表本報告提出的 shared backend + light proxy 架構,不只是為 Claude 而設計,也可以成為 Claude + Codex 的共用本機 MCP 平台藍圖。

十、兩個參考專案比較:Wrap-MCP vs ragieai/mcp-gateway

面向safx/Wrap-MCPragieai/mcp-gateway
核心定位透明 MCP proxyRagie 專用多租戶 gateway
與你問題的貼合度
對 stdio MCP 的理解直接相關不是主要場景
對 singleton/shared backend 的啟發
Docker / service 化參考一般較完整
是否適合直接作為你的主方案較適合不適合
結論:用 Wrap-MCP 的思路做中介層;借 mcp-gateway 的 service / Docker 化方式做部署參考。

十一、針對打架風險的設計原則

查詢型 MCP(較安全共享)

這類通常可以共享 singleton backend,只要做好 request routing 與 rate limit。

有副作用的 MCP(需控併發)

這類要加:

強狀態型 MCP(高風險)

這類不要直接共享同一個 browser/tab。應改成:

drission-proxy -> drission-orchestrator -> worker pool -> per-session browser contexts

十二、分階段落地計畫

Phase 1:全 Host 驗證

Phase 2:擴大到副作用型服務

Phase 3:專門設計 Drission

Phase 4:再決定是否容器化

十三、建議優先順序

  1. 先改 grok-search:最適合共享,收益高,風險低。
  2. 再改 contextweaver:讀多寫少,適合 daemon 化。
  3. 之後考慮 gemini-image-generator:需做併發限制。
  4. 最後才碰 DrissionPageMCP:一定要做 orchestrator,而不是單例共用瀏覽器。

十四、最終結論

你要解的不是「要不要 Docker」,而是「如何把 per-session MCP 啟動改成 shared backend」。

最務實的路線不是全 Docker,也不是維持現狀,而是:

  1. Claude 端保留 stdio 介面
  2. 用 light proxy + local fabric/router 做橋接
  3. 先做 Host-native 共享 backend
  4. 只有真正需要隔離的服務再選擇性容器化
這樣的混合式方案能最小化改造成本,同時最大化實際收益,並保留後續演進空間。

參考專案