|
| 1 | +# Phoenix Builder MCP |
| 2 | + |
| 3 | +An MCP (Model Context Protocol) server that lets Claude Code launch, control, and inspect a running Phoenix Code instance. It also includes a Chrome extension that enables screenshot capture when Phoenix runs in a browser. |
| 4 | + |
| 5 | +## Prerequisites |
| 6 | + |
| 7 | +- Node.js |
| 8 | +- The [phoenix-desktop](https://github.com/nicedoc/phoenix-desktop) repo cloned alongside this repo (i.e. `../phoenix-desktop`) |
| 9 | + |
| 10 | +## Setup |
| 11 | + |
| 12 | +### 1. Install dependencies |
| 13 | + |
| 14 | +```bash |
| 15 | +cd phoenix-builder-mcp |
| 16 | +npm install |
| 17 | +``` |
| 18 | + |
| 19 | +### 2. Claude Code MCP configuration |
| 20 | + |
| 21 | +The project root already contains `.mcp.json` which registers the server automatically: |
| 22 | + |
| 23 | +```json |
| 24 | +{ |
| 25 | + "mcpServers": { |
| 26 | + "phoenix-builder": { |
| 27 | + "command": "node", |
| 28 | + "args": ["phoenix-builder-mcp/index.js"], |
| 29 | + "env": { |
| 30 | + "PHOENIX_DESKTOP_PATH": "../phoenix-desktop" |
| 31 | + } |
| 32 | + } |
| 33 | + } |
| 34 | +} |
| 35 | +``` |
| 36 | + |
| 37 | +Set `PHOENIX_DESKTOP_PATH` to the path of your phoenix-desktop checkout if it is not at `../phoenix-desktop`. |
| 38 | + |
| 39 | +You can also set `PHOENIX_MCP_WS_PORT` (default `38571`) to change the WebSocket port used for communication between the MCP server and the Phoenix browser runtime. |
| 40 | + |
| 41 | +### 3. Chrome extension (for browser screenshots) |
| 42 | + |
| 43 | +Screenshots work out of the box in the Electron/Tauri desktop app. If you are running Phoenix in a browser (e.g. `localhost` or `phcode.dev`), you need to install the Chrome extension: |
| 44 | + |
| 45 | +#### Loading as an unpacked extension (development) |
| 46 | + |
| 47 | +1. Open `chrome://extensions` in Chrome. |
| 48 | +2. Enable **Developer mode** (toggle in the top-right corner). |
| 49 | +3. Click **Load unpacked**. |
| 50 | +4. Select the `phoenix-builder-mcp/chrome_extension/` directory. |
| 51 | +5. The extension will appear as "Phoenix Code Screenshot". |
| 52 | + |
| 53 | +Once loaded, any Phoenix page on `localhost` or `phcode.dev` will have `window._phoenixScreenshotExtensionAvailable` set to `true`, and the `take_screenshot` MCP tool and `Phoenix.app.screenShotBinary()` API will work in the browser. |
| 54 | + |
| 55 | +#### Building a .zip for distribution |
| 56 | + |
| 57 | +```bash |
| 58 | +cd phoenix-builder-mcp/chrome_extension |
| 59 | +./build.sh |
| 60 | +``` |
| 61 | + |
| 62 | +This produces `chrome_extension/build/phoenix-screenshot-extension.zip`. |
| 63 | + |
| 64 | +To build a signed `.crx` you need the Chrome binary and a private key: |
| 65 | + |
| 66 | +```bash |
| 67 | +chrome --pack-extension=./phoenix-builder-mcp/chrome_extension --pack-extension-key=key.pem |
| 68 | +``` |
| 69 | + |
| 70 | +## MCP Tools |
| 71 | + |
| 72 | +Once the MCP server is running, the following tools are available in Claude Code: |
| 73 | + |
| 74 | +### `start_phoenix` |
| 75 | +Launches the Phoenix Code Electron app by running `npm run serve:electron` in the phoenix-desktop directory. Returns the process PID and WebSocket port. |
| 76 | + |
| 77 | +### `stop_phoenix` |
| 78 | +Stops the running Phoenix Code process (SIGTERM, then SIGKILL after 5s). |
| 79 | + |
| 80 | +### `get_phoenix_status` |
| 81 | +Returns process status, PID, WebSocket connection state, connected instance names, and the WS port. |
| 82 | + |
| 83 | +### `get_terminal_logs` |
| 84 | +Returns stdout/stderr from the Electron process. By default returns only new logs since the last call. Pass `clear: true` to get all logs and clear the buffer. |
| 85 | + |
| 86 | +### `get_browser_console_logs` |
| 87 | +Returns `console.log`/`warn`/`error` output forwarded from the Phoenix browser runtime over WebSocket. Supports the same `clear` flag. When multiple Phoenix instances are connected, pass `instance` to target a specific one (e.g. `"Phoenix-a3f2"`). |
| 88 | + |
| 89 | +### `take_screenshot` |
| 90 | +Captures a PNG screenshot of the Phoenix window. Optionally pass a `selector` (CSS selector string) to capture a specific element. Returns the image directly as `image/png`. |
| 91 | + |
| 92 | +In Electron/Tauri this uses the native capture API. In the browser it requires the Chrome extension (see above). |
| 93 | + |
| 94 | +### `reload_phoenix` |
| 95 | +Reloads the Phoenix app. Prompts to save unsaved files before reloading. |
| 96 | + |
| 97 | +### `force_reload_phoenix` |
| 98 | +Force-reloads the Phoenix app without saving unsaved changes. |
| 99 | + |
| 100 | +## Typical Claude Code workflow |
| 101 | + |
| 102 | +``` |
| 103 | +> start_phoenix # launches the app |
| 104 | +> take_screenshot # see what the UI looks like |
| 105 | +> get_browser_console_logs # check for errors |
| 106 | +> reload_phoenix # pick up code changes |
| 107 | +> take_screenshot # verify the fix |
| 108 | +> stop_phoenix # done |
| 109 | +``` |
| 110 | + |
| 111 | +## Architecture |
| 112 | + |
| 113 | +``` |
| 114 | +Claude Code <--stdio--> MCP Server (index.js) |
| 115 | + | |
| 116 | + +-- process-manager.js (spawns/kills Electron) |
| 117 | + +-- ws-control-server.js (WebSocket on port 38571) |
| 118 | + | |
| 119 | + Phoenix browser runtime |
| 120 | + (connects back over WS for logs, screenshots, reload) |
| 121 | +``` |
| 122 | + |
| 123 | +For browser-mode screenshots the flow is: |
| 124 | + |
| 125 | +``` |
| 126 | +MCP Server --WS--> Phoenix runtime --postMessage--> Content Script --chrome.runtime--> Background SW |
| 127 | + (captureVisibleTab) |
| 128 | +``` |
0 commit comments