Skip to main content
Glama
XiaoPuOuO
by XiaoPuOuO
README.md
# chatgpt-image-bridge

透過**本機 ChatGPT Desktop App**(macOS)自動生成圖片的 CLI 工具與 MCP server。

不是逆向 API、不用額外訂閱:工具用 Chrome DevTools Protocol(CDP)驅動你自己已登入的 ChatGPT.app——在「新對話」輸入框注入 prompt、按「傳送」、輪詢到生成完畢、把圖片取回落盤。用的就是你 App 本身的帳號與配額。

## 存在的意義

你訂閱 ChatGPT 就已經有聊天生圖額度,但它只能靠人在聊天窗口裡手動使用。這個工具把那份額度**變成一個可被程式呼叫的介面**:任何支援 MCP 的 Agent 環境(OpenCode、Claude Desktop 等)裝上它,Agent 就能直接「叫圖生圖」,產出 PNG 回傳繼續工作流——不用額外申請 OpenAI API key、不用按 API 計費付費、不動到帳號安全性(它只是自動化你本人的 UI 操作,官方看到的就是一個使用者在聊天)。

一句話:**把 ChatGPT 聊天的生圖額度搬進你自己的 Agent 工具鏈。**

## 原理

ChatGPT Desktop App 是 Electron 應用。以 `--remote-debugging-port` 參數啟動後,可用 loopback CDP 對其 renderer 執行 `Runtime.evaluate`:

1. 檢查 `127.0.0.1:9342/json/version`;若 App 未在 CDP 模式,先 `kill` 再以 `open -na /Applications/ChatGPT.app --args --remote-debugging-address=127.0.0.1 --remote-debugging-port=9342` 重啟(單實例鎖會忽略第二次啟動的參數,必須先結束舊進程;登入狀態保留)。選 9342 是為了避開 Codex Dream Skin injector 預設 watch 的 9341。
2. Attach 主視窗 target(`app://-/index.html`)。
3. 點「新對話」→ 清空 composer → `execCommand('insertText')` 注入 prompt → 點「傳送」。
4. 每 3 秒輪詢:無「停止」按鈕且 App 的生成圖片容器(`[data-testid="generated-image-preview"]`/`generated-image-gallery`)中出現比發送前更多的圖片即完成(不看尺寸,小圖也抓得到)。
5. 從 data URL 切出 base64 經 CDP 傳回,寫成 PNG。stdout 輸出 `路徑 bytes`。全程無網路下載、不需簽名 URL。

CDP 只綁 127.0.0.1,不外露。

## 需求

- macOS + `/Applications/ChatGPT.app`(已登入,方案需有圖片生成配額)
- Node.js >= 22(使用全域 `fetch` / `WebSocket`,零依賴)
- App 介面語言為中文或英文皆可(按鈕比對同時支援「新對話/傳送/停止」與 New chat/Send/Stop)

## 安裝

```bash
git clone https://github.com/XiaoPuOuO/chatgpt-image-bridge.git
cd chatgpt-image-bridge
chmod +x chatgpt-image-bridge.mjs chatgpt-image-mcp.mjs
```

## 用法

### CLI

```bash
node chatgpt-image-bridge.mjs "畫一張扁平插畫風的小圖:一隻戴耳機的柴犬在打鍵盤"
# stderr: [bridge] 新對話: clicked / 注入: ... / 發送: clicked
# stdout: /Users/you/.chatgpt-bridge/out/chatgpt-1700000000000.png 1271253
```

| 選項 | 預設 | 說明 |
|---|---|---|
| `--port` | `9342` | CDP port |
| `--timeout` | `300` | 等待生成逾時(秒) |
| `--queue-timeout` | `900` | 等待其他 bridge 任務完成的最長秒數,逾時退出碼 3 |
| `--out` | `~/.chatgpt-bridge/out/chatgpt-<ts>.png` | 輸出路徑 |
| `--no-restart` | off | App 不在 CDP 模式時直接報錯而不重啟 |

### 多 Agent 併發

多個 bridge 行程同時啟動時,會透過 `~/.chatgpt-bridge/lock` 檔案鎖**自動排隊(FIFO)**,同一時間只有一個操作 App,其餘等待前一個完成後依序執行。生圖在 OpenAI 端本就是串行,本地排隊不損失吞吐。持有鎖的行程崩潰時,鎖會因 pid 失效或超過 15 分鐘而被自動搶佔。N 個併發請求的總耗時約為單張時間 × N,請相應調高 MCP 用戶端的 `timeout`。

### MCP server(給 AI Agent 呼叫)

`chatgpt-image-mcp.mjs` 是零依賴的 stdio MCP server,暴露單一工具 `generate`;MCP 用戶端會以註冊名作前綴顯示,建議註冊名為 `image`,讓 Agent 端看到 `image_generate`。引數:`prompt` 必填、`timeout`、`queue_timeout`、`out`。回傳 JSON:

```json
{ "status": "success", "images": [ { "id": "img_...", "mime_type": "image/png", "width": 1254, "height": 1254, "path": "..." } ] }
```

失敗時為 `{ "status": "error", "message": "..." }`。多個 Agent 同時呼叫時自動排隊,不會互相干擾。

OpenCode(`~/.config/opencode/opencode.jsonc`):

```jsonc
"mcp": {
  "image": {
    "type": "local",
    "command": ["node", "/路徑/chatgpt-image-bridge/chatgpt-image-mcp.mjs"],
    "enabled": true,
    "timeout": 1800000
  }
}
```

Claude Desktop 等其它 MCP 用戶端 similarly 以 `node chatgpt-image-mcp.mjs` 註冊為 local/stdio server。

## 已知限制

- **會留下一般對話紀錄**:App 右上角的「暫存對話」模式目前不支援圖片生成,所以生成結果會留在歷史中,需手動刪除。
- 重啟 App 期間視覺上會閃一下;建議不在 App 裡手動操作時使用。
- 生成耗時取決於官方配額與排隊狀態,預設逾時 5 分鐘。
- 依賴 App 內的按鈕文字(新對話/傳送/停止)與 `generated-image-*` testid。OpenAI 改版或新增語言介面時需更新選擇器。
- 本質上是 UI 自動化:同一時間只有一個橋能操作 App,多橋併發時由檔案鎖自動排队(見「多 Agent 併發」)。

## License

MIT