#!/bin/sh # kitesurf-mcp.sh — 把 Cloudflare Kitesurf 無頭瀏覽器掛成一個 MCP server(stdio)。 # # 【為什麼需要這支包裝,不能直接把 leo 給的那段 JSON 貼進設定】 # leo 給的那段是 **CDP(Chrome DevTools Protocol)** 端點,不是 MCP server: # 實測 `wss://api.cloudflare.com/.../browser-run/devtools/browser?browser=kitesurf` # 握手回 `101 Switching Protocols` 之後,第一個訊息就是 # `{"method":"Target.targetCreated",...}` ⇒ 它講的是 CDP,不是 MCP 的 JSON-RPC。 # Claude Code 的 MCP client 只會講 stdio / SSE / HTTP 的 MCP,接上去必定 initialize 失敗。 # ⇒ 正解是中間放一個「會講 CDP、也會講 MCP」的翻譯:@playwright/mcp # (它有 --cdp-endpoint 與 --cdp-header,剛好能帶 CF 要的 Authorization header)。 # # 【為什麼金鑰不寫在設定檔裡】D36 金鑰鐵律:AI 只碰得到名字,值在**執行當下**才解析。 # 所以 .claude.json 裡只有這支腳本的路徑,token 由本腳本在啟動瞬間從 .env 讀出來, # 不落在任何設定檔、不進版控。 # # 【為什麼帳號 id 寫死】agent-memory §2 紅線:那把 token 打 GET /accounts 會回兩個, # 第二個 `24f01c68…` 是 leo **接案代管的客戶帳號**,AI 一律不碰。 # 寫死 leo21c 的 id ⇒ 結構上不可能連到客戶帳號(不靠「記得選對」)。 set -eu INKSTONE_ROOT="$(cd "$(dirname "$0")/.." && pwd)" ENV_FILE="$INKSTONE_ROOT/polaris/mira/.env" # 憑證地圖:leo21c 的 CLOUDFLARE_API_TOKEN 住這裡 ACCOUNT_ID="51a01bfa2665bd7bc3fd080dc40cf3e1" # leo21c(唯一准用的帳號,見上方紅線) if [ ! -f "$ENV_FILE" ]; then echo "kitesurf-mcp: 找不到 $ENV_FILE(leo21c 的 CLOUDFLARE_API_TOKEN 在那裡)" >&2 exit 1 fi CF_TOKEN=$(grep -E '^CLOUDFLARE_API_TOKEN=' "$ENV_FILE" | head -1 | cut -d= -f2- | tr -d '"'"'"' \r') if [ -z "${CF_TOKEN:-}" ]; then echo "kitesurf-mcp: $ENV_FILE 裡沒有 CLOUDFLARE_API_TOKEN" >&2 exit 1 fi exec npx -y @playwright/mcp@latest \ --cdp-endpoint "wss://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/browser-run/devtools/browser?browser=kitesurf" \ --cdp-header "Authorization: Bearer $CF_TOKEN" \ "$@"