codex-chrome-bridge 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +281 -0
- package/package.json +49 -0
- package/src/bridge.js +2931 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 usedhonda
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
# codex-chrome-bridge
|
|
2
|
+
|
|
3
|
+
[](https://npmjs.org/package/codex-chrome-bridge)
|
|
4
|
+
[](LICENSE)
|
|
5
|
+
[](https://nodejs.org)
|
|
6
|
+
|
|
7
|
+
> MCP server that lets Codex control Chrome through the same bridge Claude Code already uses.
|
|
8
|
+
|
|
9
|
+
**The idea**: Claude Code + Claude in Chrome already have a working browser connection on your machine.
|
|
10
|
+
This wrapper discovers that connection and exposes it to Codex via MCP — no Puppeteer, no Playwright,
|
|
11
|
+
no separate browser instance. Just reuse what's already running.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## How it works
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
Codex ──stdio──▶ codex-chrome-bridge (MCP) ──socket──▶ Claude native host ──▶ Chrome (CiC extension)
|
|
19
|
+
│ │
|
|
20
|
+
22 MCP tools Existing bridge
|
|
21
|
+
(browser_*) (already running)
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
1. **Claude Code + Claude in Chrome** establish a native-messaging bridge to Chrome
|
|
25
|
+
2. **This wrapper** discovers that bridge's Unix socket and connects to it
|
|
26
|
+
3. **Codex** sees 22 browser tools through a standard MCP interface
|
|
27
|
+
4. No new browser instance, no new extension, no new permissions — just reuse
|
|
28
|
+
|
|
29
|
+
**Why this matters**: Instead of building yet another browser automation stack, this project proves that Codex can piggyback on Claude Code's existing browser integration with zero additional infrastructure.
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## What makes this different
|
|
34
|
+
|
|
35
|
+
| | Typical browser MCP | codex-chrome-bridge |
|
|
36
|
+
|--------------------------|--------------------------------|-----------------------------------|
|
|
37
|
+
| **Browser instance** | Spawns its own | Reuses your existing Chrome |
|
|
38
|
+
| **Extension required** | Usually its own | Claude in Chrome (already there) |
|
|
39
|
+
| **Login sessions** | Separate (must re-login) | Shares your existing sessions |
|
|
40
|
+
| **Tab management** | Independent | Uses CiC's managed tab groups |
|
|
41
|
+
| **Permission model** | Varies | CiC's permission choreography |
|
|
42
|
+
| **Dependencies** | Playwright / Puppeteer / etc. | Zero (Node.js built-ins only) |
|
|
43
|
+
| **Setup** | Install + configure + launch | Discover + connect |
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Prerequisites
|
|
48
|
+
|
|
49
|
+
- **macOS** (native-messaging path is macOS-specific for now)
|
|
50
|
+
- **Node.js 24+**
|
|
51
|
+
- **Claude Code** installed and working
|
|
52
|
+
- **Claude in Chrome** extension active in Chrome
|
|
53
|
+
- Chrome running with at least one tab
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Quick Start
|
|
58
|
+
|
|
59
|
+
### 1. Install
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
npm install -g codex-chrome-bridge
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Or run directly with npx:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
npx codex-chrome-bridge probe
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### 2. Check the bridge is reachable
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
codex-chrome-bridge probe
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
You should see `connect_ok: true` and `status_ok: true`.
|
|
78
|
+
|
|
79
|
+
### 3. Start the MCP server
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
codex-chrome-bridge mcp
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
The server listens on stdin/stdout using JSON-RPC 2.0 (MCP protocol).
|
|
86
|
+
|
|
87
|
+
### 4. Validate (optional)
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
npx codex-chrome-bridge validate # prompt-safe, no popups
|
|
91
|
+
npx codex-chrome-bridge validate --live-browser # full browser sweep
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## MCP Tools (22)
|
|
97
|
+
|
|
98
|
+
<!-- TOOLS_START -->
|
|
99
|
+
| Tool | Required args | Description |
|
|
100
|
+
|------|---------------|-------------|
|
|
101
|
+
| `browser_health` | — | Check bridge connectivity and health |
|
|
102
|
+
| `browser_snapshot` | — | Return the current browser/tab context |
|
|
103
|
+
| `browser_tabs_context` | — | Return MCP tab-group context (optionally auto-create) |
|
|
104
|
+
| `browser_create_tab` | — | Create a new empty tab in the MCP tab group |
|
|
105
|
+
| `browser_navigate_tab` | `tabId`, `url` | Navigate a tab to a URL |
|
|
106
|
+
| `browser_open_or_focus` | — | Open a new tab for a URL |
|
|
107
|
+
| `browser_reuse_tab` | — | Confirm that an existing visible tab can be reused |
|
|
108
|
+
| `browser_close_tab` | `tabId` | Close a specific tab |
|
|
109
|
+
| `browser_javascript_exec` | `tabId`, `script` | Execute JavaScript |
|
|
110
|
+
| `browser_get_page_text` | `tabId` | Extract plain text |
|
|
111
|
+
| `browser_read_page` | `tabId` | Read an accessibility-tree style view of a tab or subtree |
|
|
112
|
+
| `browser_find` | `tabId`, `query` | Find an element using natural language |
|
|
113
|
+
| `browser_form_input` | `tabId`, `ref`, `value` | Set a form control value by ref |
|
|
114
|
+
| `browser_console_messages` | `tabId` | Read tracked browser console messages |
|
|
115
|
+
| `browser_network_requests` | `tabId` | Read tracked network requests |
|
|
116
|
+
| `browser_computer` | `tabId`, `action` | Unified action dispatch: hover, key, scroll, drag, right-click, double-click, wait, zoom, and scroll_to |
|
|
117
|
+
| `browser_click` | `tabId` | Click at viewport coordinates |
|
|
118
|
+
| `browser_type` | `tabId`, `text` | Type text into the focused element (optional click-first coordinates) |
|
|
119
|
+
| `browser_screenshot` | `tabId` | Capture a screenshot and cache the resulting image |
|
|
120
|
+
| `browser_upload_file` | `tabId`, `paths` | Upload local files to a file input |
|
|
121
|
+
| `browser_upload_image` | `tabId` | Upload an image from cache or local path to a target element |
|
|
122
|
+
| `browser_resize_window` | `tabId`, `width`, `height` | Resize the browser window |
|
|
123
|
+
<!-- TOOLS_END -->
|
|
124
|
+
|
|
125
|
+
### Categories
|
|
126
|
+
|
|
127
|
+
| Category | Tools |
|
|
128
|
+
|-----------------|-------|
|
|
129
|
+
| **Discovery** | `browser_health`, `browser_snapshot` |
|
|
130
|
+
| **Tabs** | `browser_tabs_context`, `browser_create_tab`, `browser_navigate_tab`, `browser_open_or_focus`, `browser_reuse_tab`, `browser_close_tab` |
|
|
131
|
+
| **Interaction** | `browser_click`, `browser_type`, `browser_computer` |
|
|
132
|
+
| **Reading** | `browser_read_page`, `browser_get_page_text`, `browser_find`, `browser_console_messages`, `browser_network_requests` |
|
|
133
|
+
| **Scripting** | `browser_javascript_exec`, `browser_form_input` |
|
|
134
|
+
| **Media** | `browser_screenshot`, `browser_upload_file`, `browser_upload_image`, `browser_resize_window` |
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## Codex Integration
|
|
139
|
+
|
|
140
|
+
### Option A: Global install (recommended)
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
npm install -g codex-chrome-bridge
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Add to `~/.codex/config.toml`:
|
|
147
|
+
|
|
148
|
+
```toml
|
|
149
|
+
[mcp_servers.codex_chrome_bridge]
|
|
150
|
+
command = "codex-chrome-bridge"
|
|
151
|
+
args = ["mcp"]
|
|
152
|
+
startup_timeout_sec = 20
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Option B: Project-local (npx)
|
|
156
|
+
|
|
157
|
+
```toml
|
|
158
|
+
# .codex/config.toml
|
|
159
|
+
[mcp_servers.codex_chrome_bridge]
|
|
160
|
+
command = "npx"
|
|
161
|
+
args = ["codex-chrome-bridge", "mcp"]
|
|
162
|
+
startup_timeout_sec = 20
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Option C: From source
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
git clone https://github.com/usedhonda/codex-chrome-bridge.git
|
|
169
|
+
cd codex-chrome-bridge
|
|
170
|
+
npm run codex:bridge
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
## Configuration
|
|
176
|
+
|
|
177
|
+
### Environment Variables
|
|
178
|
+
|
|
179
|
+
| Variable | Default | Description |
|
|
180
|
+
|----------|---------|-------------|
|
|
181
|
+
| `CLAUDE_BRIDGE_SOCKET_ROOT` | `/tmp/claude-mcp-browser-bridge-<user>` | Socket search directory |
|
|
182
|
+
| `CLAUDE_BRIDGE_MANIFEST_PATH` | (macOS default) | Native messaging manifest path |
|
|
183
|
+
| `CLAUDE_BRIDGE_LAUNCHER_PATH` | (auto-detected) | Claude Code binary path |
|
|
184
|
+
| `CLAUDE_BRIDGE_DISCOVERY_TIMEOUT_MS` | `5000` | Socket discovery timeout |
|
|
185
|
+
| `CLAUDE_BRIDGE_TOOL_TIMEOUT_MS` | `15000` | Per-tool execution timeout |
|
|
186
|
+
| `CLAUDE_BRIDGE_MCP_TRACE_PATH` | (disabled) | MCP JSON-RPC trace log path |
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## Architecture
|
|
191
|
+
|
|
192
|
+
```
|
|
193
|
+
┌─────────────┐ stdio / JSON-RPC ┌────────────────────────┐
|
|
194
|
+
│ │ ◀─────────────────────▶ │ codex-chrome-bridge │
|
|
195
|
+
│ Codex │ │ (MCP server) │
|
|
196
|
+
│ │ │ src/bridge.js │
|
|
197
|
+
└─────────────┘ └───────────┬────────────┘
|
|
198
|
+
│ Unix socket
|
|
199
|
+
▼
|
|
200
|
+
┌────────────────────────┐
|
|
201
|
+
│ Claude native host │
|
|
202
|
+
│ (already running via │
|
|
203
|
+
│ Claude Code) │
|
|
204
|
+
└───────────┬────────────┘
|
|
205
|
+
│ Chrome native
|
|
206
|
+
│ messaging
|
|
207
|
+
▼
|
|
208
|
+
┌────────────────────────┐
|
|
209
|
+
│ Chrome browser │
|
|
210
|
+
│ + Claude in Chrome │
|
|
211
|
+
│ extension │
|
|
212
|
+
└────────────────────────┘
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### Key design decisions
|
|
216
|
+
|
|
217
|
+
- **Zero dependencies** — only Node.js built-ins (`child_process`, `fs`, `net`, `os`, `path`, `crypto`)
|
|
218
|
+
- **Single file** — `src/bridge.js` (~2900 lines), no build step, no transpilation
|
|
219
|
+
- **Socket discovery** — finds the live native-host socket via `ps` process inspection
|
|
220
|
+
- **Session scoping** — each MCP session gets its own `sessionId` and `displayName`
|
|
221
|
+
- **Image caching** — screenshot LRU cache (max 24) for `browser_upload_image` reuse
|
|
222
|
+
- **Protocol negotiation** — supports MCP protocol versions `2025-06-18`, `2025-03-26`, `2024-11-05`
|
|
223
|
+
|
|
224
|
+
---
|
|
225
|
+
|
|
226
|
+
## Validation & Testing
|
|
227
|
+
|
|
228
|
+
```bash
|
|
229
|
+
npm test # Hermetic unit tests (contract + fixtures + compat matrix)
|
|
230
|
+
npm run validate # Prompt-safe live MCP validation (no popups)
|
|
231
|
+
npm run validate:live # Full browser approval testing
|
|
232
|
+
npm run compat # Drift detection against local environment
|
|
233
|
+
npm run release:gate # Maintainer release checklist
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
## Known Limitations
|
|
239
|
+
|
|
240
|
+
### YELLOW verdict — usable but lifecycle-sensitive
|
|
241
|
+
|
|
242
|
+
This wrapper works well in practice, but the downstream contract is private:
|
|
243
|
+
|
|
244
|
+
- **Protocol drift** — Anthropic can change the CiC extension/native-host protocol at any time without notice
|
|
245
|
+
- **Permission popups** — CiC's permission choreography still applies (`ALWAYS`/`ONCE` grants, domain transitions)
|
|
246
|
+
- **Session coupling** — the bridge requires a running Claude native-host process
|
|
247
|
+
- **macOS only** — the native-messaging manifest path is macOS-specific for now
|
|
248
|
+
|
|
249
|
+
See [Known Limitations](./docs/known-limitations.md) and [Compatibility](./docs/compatibility.md) for details.
|
|
250
|
+
|
|
251
|
+
---
|
|
252
|
+
|
|
253
|
+
## Troubleshooting
|
|
254
|
+
|
|
255
|
+
| Problem | Likely cause | Fix |
|
|
256
|
+
|---------|-------------|-----|
|
|
257
|
+
| `probe` shows `connect_ok: false` | No Claude native host running | Start Claude Code or open a Claude in Chrome session |
|
|
258
|
+
| `probe` shows `socket not found` | Socket discovery failed | Check `CLAUDE_BRIDGE_SOCKET_ROOT` env var |
|
|
259
|
+
| Tools return timeout errors | CiC extension not responding | Refresh Chrome tab, check extension is enabled |
|
|
260
|
+
| Permission popup on every action | Grants are `ONCE`, not `ALWAYS` | Grant `ALWAYS` permissions per domain |
|
|
261
|
+
| `EPERM` or socket errors | Stale socket from previous session | Restart Claude Code to get a fresh socket |
|
|
262
|
+
|
|
263
|
+
See [Troubleshooting](./docs/troubleshooting.md) for more.
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
## Documentation
|
|
268
|
+
|
|
269
|
+
| Guide | Description |
|
|
270
|
+
|-------|-------------|
|
|
271
|
+
| [Quickstart](./docs/quickstart.md) | First-run setup and commands |
|
|
272
|
+
| [Compatibility](./docs/compatibility.md) | Version tracking and drift detection policy |
|
|
273
|
+
| [Known Limitations](./docs/known-limitations.md) | Power-user caveats |
|
|
274
|
+
| [Troubleshooting](./docs/troubleshooting.md) | Problem solving |
|
|
275
|
+
| [Version Matrix](./compat/version-matrix.json) | Validated extension/launcher baselines |
|
|
276
|
+
|
|
277
|
+
---
|
|
278
|
+
|
|
279
|
+
## License
|
|
280
|
+
|
|
281
|
+
[MIT](./LICENSE)
|
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "codex-chrome-bridge",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "MCP server that lets Codex control Chrome through Claude Code's existing browser bridge",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "src/bridge.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"codex-chrome-bridge": "src/bridge.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"src/bridge.js",
|
|
12
|
+
"README.md",
|
|
13
|
+
"LICENSE"
|
|
14
|
+
],
|
|
15
|
+
"engines": {
|
|
16
|
+
"node": ">=24"
|
|
17
|
+
},
|
|
18
|
+
"keywords": [
|
|
19
|
+
"mcp",
|
|
20
|
+
"codex",
|
|
21
|
+
"claude",
|
|
22
|
+
"chrome",
|
|
23
|
+
"browser-automation",
|
|
24
|
+
"claude-in-chrome",
|
|
25
|
+
"model-context-protocol"
|
|
26
|
+
],
|
|
27
|
+
"repository": {
|
|
28
|
+
"type": "git",
|
|
29
|
+
"url": "https://github.com/usedhonda/codex-chrome-bridge.git"
|
|
30
|
+
},
|
|
31
|
+
"homepage": "https://github.com/usedhonda/codex-chrome-bridge",
|
|
32
|
+
"bugs": "https://github.com/usedhonda/codex-chrome-bridge/issues",
|
|
33
|
+
"license": "MIT",
|
|
34
|
+
"scripts": {
|
|
35
|
+
"probe": "node ./src/bridge.js probe",
|
|
36
|
+
"mcp": "node ./src/bridge.js mcp",
|
|
37
|
+
"compat": "node ./scripts/check-compatibility.mjs",
|
|
38
|
+
"test": "node --test ./test/*.test.mjs",
|
|
39
|
+
"validate": "node ./scripts/validate-bridge.mjs",
|
|
40
|
+
"validate:live": "node ./scripts/validate-bridge.mjs --live-browser",
|
|
41
|
+
"demo:workflow": "node ./scripts/demo-read-computer-js.mjs",
|
|
42
|
+
"release:gate": "node ./scripts/release-gate.mjs",
|
|
43
|
+
"release:gate:live": "node ./scripts/release-gate.mjs --include-live",
|
|
44
|
+
"codex:bridge": "node ./scripts/run-codex-with-bridge.mjs",
|
|
45
|
+
"codex:bridge:exec": "node ./scripts/run-codex-with-bridge.mjs exec",
|
|
46
|
+
"docs": "node ./scripts/generate-docs.mjs",
|
|
47
|
+
"prepublishOnly": "npm test"
|
|
48
|
+
}
|
|
49
|
+
}
|