Files
Arcrun/system-dev/docs/3-specs/arcrun/sdk-and-website/mcp-account-source.md
uncle6me-web 5d00e71275 chore: D22 落地——docs/SDD/wiki/CLAUDE.md 進 repo(Gitea private 預設全 push)
頂層 D22 決策(leo 2026-07-03 拍板):推什麼由開發環境歸屬決定,
Gitea private=除機敏值/build 產物/.github 外全 push。
解 T1.5 卡點:雲端工人 clone 拿得到 credential-store-migration.md,可就地改寫 SDD。
機敏掃描兩輪通過(新增 189 檔約 2.1MB,node_modules/dist/wasm 照舊排除)。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 07:13:33 +08:00

9.1 KiB
Raw Permalink Blame History

DesignMCP 統一帳號來源 — 單一 remote MCP + .env 切 MCP URL

2026-06-06 richblack 拍板(推翻本檔初版的「①工具帶參數 / ②自架 worker / ③平台 routing」三方案)。 sdk-and-website/design.md 的單檔補充(規則 02 §4.3 允許)。 來源:壓測報告 §5.1/§5.2/§5.4(薄殼原則)+ richblack 對話釐清。 對應鐵律:.claude/rules/07-thin-shell.md §4(統一帳號來源)。


1. 問題(壓測 §5.2

CLI 已能讀三層 configenv > 專案 .arcrun.yaml > 全域)切帳號;MCP 不能——MCP 用 Cloudflare service binding 焊死平台 arcrun-cypher-executorself-hosted 用戶用 MCP 連不到自己的 cypher。

這違反薄殼鐵律:「切換帳號」這能力做在了 CLI(介面層),MCP 沒跟上 → 證明它不在 API/共用層。

2. 關鍵洞見(richblack):不需要兩套 transport

「self-hosted 用戶也有 CF,把 MCP 放上網對他也沒困難。接案時進客戶專案讀 .env 連的是 客戶專案的雲端 MCP — 這比保留 stdio + 雲端兩套更單純。」

推論:所有人都用 remote Worker MCP,差別只在「連哪台 MCP」

  • 我自己:全域 config 的 mcp_url 指向我自己的 MCP Worker。
  • 接案幫客戶:客戶資料夾 .arcrun.yaml / .env 放客戶的 mcp_url(那台 MCP 綁客戶 cypher)。 進客戶資料夾 → 自動連客戶那套。
  • SaaS 用戶:不設 mcp_url → fallback 平台預設 MCPAI 幫他帶 api_key。

不需要 stdio 本機 MCP、不需要 transport 抽象層、不需要把 Worker 改成讀本機檔。 現有 remote HTTP Worker MCP 形態完全保留。

3. 薄殼原則怎麼落地

「身份解析(讀哪個帳號/哪台 MCP)」本質在 client(帳號設定是本機檔,cypher/MCP Worker 讀不到)。 正解不是「API 去讀 .env」(做不到),而是:

MCP URL 與 cypher URL 一樣,由同一份 config 解析模組(env > 專案 > 全域)決定。 CLI 讀 cypher_urlClaude Code 的 MCP 連線讀 mcp_url同一份 .arcrun.yaml / env、同一個解析邏輯。 「切換帳號」這能力只實作一次(config 解析),不再綁死在 CLI。

接線:mcp_url → Claude Code 的 MCP 設定

Claude Code 看 .mcp.json(專案層)決定連哪台 MCP。所以需要一個東西把 「arcrun config 解析出的 mcp_url」寫進專案 .mcp.json

  • acr mcp-setup(新指令):依三層 config 解析出 mcp_url,在 cwd 寫 / 更新 .mcp.json
  • acr init 順帶呼叫(裝好就有)。
  • 「切帳號」= 在客戶資料夾跑 acr mcp-setup(讀該資料夾的 .arcrun.yaml)→ 產對的 .mcp.json

4. 動到的檔案

檔案 動作 狀態
cli/src/lib/config.ts ArcrunConfigmcp_urlENV_MAPARCRUN_MCP_URLresolveConfigSources 含 mcp_url;新增 DEFAULT_MCP_URL + getMcpUrl() 完成
cli/src/commands/mcp-setup.ts(新增) acr mcp-setup:依 getMcpUrl() 寫專案 .mcp.json 進行中
cli/src/index.ts 註冊 acr mcp-setup 進行中
cli/src/commands/init.ts init 尾端順帶 acr mcp-setup(裝好即有) 進行中
arcrun/mcp/(新目錄) MCP 從 sibling repo matrix/arcrun-mcp 搬進主庫(與 cli/ 並列)。形態不變(remote Worker),只是進主庫 → 同 repo、同 deploy 掃描、與 cypher API 對齊 進行中
mcp/wrangler.toml name/route 對齊 arcrun 部署慣例(workers_dev=truedeploy.yml/local-deploy.sh 自動掃到) 進行中

5. MCP 搬進 arcrun/mcp/(不改形態,只進主庫)

  • 搬 verbatimsrc/tools/*src/lib/*src/types.tssrc/mcp-handler.tssrc/index.tstests/
  • 形態不變:仍是 Hono + WebStandardStreamableHTTPServerTransport 的 remote Worker(不加 stdio)。
  • 進主庫的理由(a) 與 cypher-executor 同 repo → 改 API 時 MCP 薄殼同步可見、一起 review (b) 被 deploy 掃描(wrangler.toml)自動部署,納入 release.feature「推送=全部到位」; (c) self-host 用戶 codeload 主庫即得 MCP,能部署自己的 MCP Worker。
  • sibling repo matrix/arcrun-mcp 去留:搬進來後,原 sibling 為歷史/過渡;新開發在 arcrun/mcp/

5.5 self-hosted MCP 認證對齊(2026-06-14HANDOFF §3b

症狀(mira CC 實測 arcrun-mcp.leo21c.workers.dev):self-hosted 用 namespace 明碼連 MCP 一律 401 CLL 全通。根因:MCP middleware/partner-auth.ts 把 Bearer 拿去 KBDB /partners/:token/info 驗證namespace 明碼非註冊 partner → 401。而 cypher-executor 的 X-Arcrun-API-Key 不驗證、直接當分區 keywebhooks-named.ts triggerNamed)→ 這就是「CLI 通、MCP 401」的分歧。

決策:① MCP self-hosted 繞 partner 驗證 + ② mcp-setup 寫 headers(兩者缺一不可)。

修法 為何必須
partner-auth.tsMULTI_TENANT === 'false' 時 Bearer = namespace 明碼直接當 org_namespace,不打 KBDB partner 驗證(對齊 cypher 的 opaque-key 模型)。官方 SaaS(不設/"true")行為不變 → 官方與 self-host 共用同一份程式碼 只做②也沒用:partner 驗證仍擋明碼
mcp-setup.ts:把 config.api_keyself-hosted 存 namespace 明碼)寫進 .mcp.jsonheaders.Authorization: Bearer …(與 CLI 同一份身份,rule 07 §4 只做①也沒用:裸 .mcp.json 不送任何 header

判定旗標:worker [vars] MULTI_TENANT(與 cypher 同名)。

5.5.1 部署注入修補(2026-06-15HANDOFF §3b-2

症狀:①②code 正確、官方帳號測綠,但 mira 推 leo21c 端到端仍 401根因(非 code bug,是部署注入缺口)partner-auth.ts if (c.env.MULTI_TENANT === 'false') 邏輯對,但 worker env 裡 MULTI_TENANT === undefined——因為:

  • mcp/wrangler.toml 的 MULTI_TENANT 原本是註解掉的
  • cli/src/lib/deploy.tsinjectWranglerConfig 部署時注入了 KV id / WORKER_SUBDOMAIN / D1 id 但沒注入 MULTI_TENANT → 部署後 c.env.MULTI_TENANT===undefined ≠ 'false' → 走 partner-key → 401。
  • config 源頭早有(init.ts multi_tenant:false + mode:'self-hosted'),只是沒被注進 worker。

只取消註解 mcp/wrangler.toml 不夠——那只修「手動 fork」,沒修「acr update 自動部署」(mira 走後者)。 根因要修在 deploy.ts 注入邏輯。

修法(方案①:注 vars 非 secret,符合 self-hosted 零填寫契約)

檔案 動作 狀態
cli/src/lib/deploy.ts DeployContextselfHosted?;新增 export injectMultiTenant(toml)(處理 active/註解/無行三態,加進 [vars]);injectWranglerConfigselfHosted 時呼叫——與 WORKER_SUBDOMAIN/KV 注入同層級 完成
cli/src/commands/init.ts deployCtx 帶 selfHosted: trueinit 本就是 --self-hosted 分支) 完成
cli/src/commands/update.ts ctx 帶 selfHosted: config.mode==='self-hosted' || config.multi_tenant===falsemira 走這條) 完成
mcp/wrangler.toml # [vars]/# MULTI_TENANT 改 active [vars](官方不含 MULTI_TENANT=多租戶;注入走 case-3 加行,結構正確在 [vars] 下) 完成

本地驗注入(dry-run,真實 export 函式)mcp / cypher-executor 注入後各恰 1 行 active MULTI_TENANT = "false" 且在 active [vars] 之下 → ✓ PASS。cli tsc exit 0。 端到端(交棒回 miramira 在 leo21c 重跑 acr update 重部 MCP worker(這次帶 MULTI_TENANT=false)→ curl -H "Authorization: Bearer leo" https://<mcp>.leo21c.workers.dev/mcp200 非 401。官方帳號測不到(不設 MULTI_TENANT)。

5.5.0 原始 code 修法(2026-06-14,①②)

檔案 動作 狀態
mcp/src/types.ts EnvMULTI_TENANT? 完成
mcp/src/middleware/partner-auth.ts self-hosted 分支:Bearer 明碼直接當 org_namespace 完成
cli/src/commands/mcp-setup.ts .mcp.jsonheaders.Authorization 完成

驗收:mira 用 namespace 明碼連 self-hosted MCP(待 leo21c 部署後實測,HANDOFF §3);官方 SaaS MCP partner-key 路徑回歸不變。

6. 不在範圍(明確排除)

  • 不加 stdio transportrichblack §2:不需要)。
  • 不把 init / config 搬進 MCPinit 是本機 CF 部署動作,MCP Worker 做不到)。
  • 不在 MCP 重實作 credential 加密 / workflow 執行(server 職責,rule 02 §3.4)。

7. 驗收(客觀證據,mindset §7)

  1. cli/ + mcp/ 各自 tsc --noEmit exit 0。
  2. acr mcp-setup 在含 .arcrun.yaml(mcp_url=X)的資料夾 → 產出 .mcp.json 指向 X;無 mcp_url → 指向 DEFAULT_MCP_URL。
  3. acr config --where 顯示 mcp_url 來源層。
  4. mcp/ 被 deploy 掃描掃到(find wrangler.toml 命中)。
  5. self-hosted 用戶在客戶資料夾 acr mcp-setup → Claude Code 連客戶 MCP(端到端待 richblack 實測)。