codex-control-chrome-mcp 1.2.0 → 1.2.1

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/CHANGELOG.md CHANGED
@@ -6,6 +6,12 @@ This project follows semantic versioning.
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [1.2.1] - 2026-07-03
10
+
11
+ ### Fixed
12
+
13
+ - Native host failed to start on 1.2.0. The install launcher runs the host with `--browser <name>` before the extension origin that Chrome appends, so the origin was no longer `args[0]`. The CLI dispatcher only recognized native-host mode when the origin was `args[0]`, so the launcher's argv fell through to `Unknown command: --browser` and the host exited on every connect. The visible symptoms were the Codex extension connection flapping between connected/disconnected and `status` never listing a bridge socket (`sockets: []`). The dispatcher now detects the origin by shape anywhere in the args, and a regression test covers the launcher argv.
14
+
9
15
  ## [1.2.0] - 2026-06-29
10
16
 
11
17
  ### Added
package/README.md CHANGED
@@ -15,17 +15,6 @@ This is an independent community project. It is not affiliated with OpenAI, Code
15
15
  - Chrome Extension: [Codex Chrome Extension](https://chromewebstore.google.com/detail/hehggadaopoacecdllhhajmbjkdcmajg)
16
16
  - Skill: [`skills/codex-control-chrome-mcp/SKILL.md`](./skills/codex-control-chrome-mcp/SKILL.md)
17
17
 
18
- ## Status
19
-
20
- The current implementation provides:
21
-
22
- - official `@modelcontextprotocol/sdk` stdio server
23
- - Chrome and Microsoft Edge Native Messaging host mode
24
- - install/uninstall commands with manifest backup
25
- - JSON-RPC bridge socket under `/tmp/codex-browser-use`
26
- - Chrome tab, navigation, screenshot, CDP, and event MCP tools
27
- - bundled skill documentation for Agent tool ordering
28
-
29
18
  ## Platform Support
30
19
 
31
20
  | Platform | Status | Notes |
@@ -161,16 +150,12 @@ node ./bin/codex-control-chrome-mcp.js --native-host
161
150
 
162
151
  ## Troubleshooting
163
152
 
164
- `status` reports, per browser (under `install.chrome` / `install.edge`), a `registered` flag and a `classification` of the live manifest. When `registered` is `false` and `classification.kind` is `official-openai`, a Codex update has reclaimed that browser's manifest (see below). `classification` identifies OpenAI's genuine host by stable signals — the `com.openai.codexextension` name, the official extension origin, the bundle path, the binary format, and (on macOS) the OpenAI code signature — not by filename.
165
-
166
153
  ### A Codex update stopped the bridge
167
154
 
168
155
  Codex App/extension updates re-register their own `com.openai.codexextension` native-messaging manifest, which overwrites this project's proxy registration (the bundled host binary has even been renamed across releases). The symptom is `status` showing `sockets: []`, `registered: false`, and a manifest `path` back inside the Codex bundle.
169
156
 
170
157
  The MCP stdio server now **self-heals**: on startup it re-asserts the manifest when it detects it was reverted, so you usually do not need to re-run `install-native-host`. Because Chrome only reads the manifest when the extension reconnects, **reload the Codex Chrome Extension (or restart Chrome) once** after a Codex update to bring the bridge back. Set `CODEX_CONTROL_CHROME_NO_AUTO_REGISTER=1` to disable the auto re-register.
171
158
 
172
- If `status` shows no bridge sockets, reload Chrome or the Codex Chrome Extension after installing the native host.
173
-
174
159
  If Codex App integration stops working, uninstall this native host to restore the backed-up manifest:
175
160
 
176
161
  ```bash
@@ -179,6 +164,8 @@ npx -y codex-control-chrome-mcp@latest uninstall-native-host
179
164
 
180
165
  If tab or CDP tools fail, use the bundled skill workflow: list tabs again, claim only current tab IDs, attach before raw CDP calls, and read CDP events after enabling the relevant domain.
181
166
 
167
+ See [Install And Uninstall](./docs/install.md#troubleshooting) for the full per-browser checklist (the `registered` flag and host `classification`).
168
+
182
169
  ## License
183
170
 
184
171
  MIT
@@ -203,20 +203,16 @@ Agent-side MCP config should use:
203
203
  }
204
204
  ```
205
205
 
206
- Chrome Native Messaging manifests cannot store command arguments. Therefore `install-native-host` creates a stable launcher script:
207
-
208
- ```sh
209
- npx -y codex-control-chrome-mcp@latest install-native-host
210
- ```
206
+ Chrome Native Messaging manifests cannot store command arguments. Therefore `install-native-host` writes a stable launcher script at:
211
207
 
212
208
  ```text
213
209
  ~/.codex-control-chrome-mcp/native-host-launcher
214
210
  ```
215
211
 
216
- That launcher runs:
212
+ That launcher runs (the `--browser` flag tells the host which browser's proxy config to read):
217
213
 
218
214
  ```sh
219
- npx -y codex-control-chrome-mcp@1.0.0 --native-host "$@"
215
+ npx -y codex-control-chrome-mcp@latest --native-host --browser chrome "$@"
220
216
  ```
221
217
 
222
218
  The native host manifest points to the launcher, not directly to `npx`.
package/docs/install.md CHANGED
@@ -8,13 +8,6 @@ Package:
8
8
 
9
9
  ## Development Status
10
10
 
11
- The current implementation provides:
12
-
13
- - MCP stdio mode: `npx -y codex-control-chrome-mcp@latest --stdio`
14
- - manifest install: `npx -y codex-control-chrome-mcp@latest install-native-host`
15
- - manifest uninstall: `npx -y codex-control-chrome-mcp@latest uninstall-native-host`
16
- - bridge/socket status: `npx -y codex-control-chrome-mcp@latest status`
17
-
18
11
  Do not run install on a machine where Codex Chrome integration is important unless you are ready to test proxy mode or restore from backup.
19
12
 
20
13
  This is an independent community project. It is not affiliated with OpenAI, Codex, Google, or Chrome.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codex-control-chrome-mcp",
3
- "version": "1.2.0",
3
+ "version": "1.2.1",
4
4
  "description": "MCP server and native host bridge for controlling Chrome through the Codex Chrome extension.",
5
5
  "license": "MIT",
6
6
  "type": "module",
package/src/cli.js CHANGED
@@ -13,21 +13,19 @@ import { probeLengthPrefixedSocket } from "./probe.js";
13
13
 
14
14
  export async function runCli(argv) {
15
15
  const args = argv.slice(2);
16
- const command = args[0];
16
+ const invocation = classifyInvocation(args);
17
17
 
18
- if (args.includes("--stdio") || command === "stdio") {
18
+ if (invocation.mode === "mcp") {
19
19
  await runMcpServer();
20
20
  return;
21
21
  }
22
22
 
23
- if (args.includes("--native-host") || looksLikeChromeOrigin(command)) {
24
- // Chrome/Edge append the extension origin as a positional arg, so find it
25
- // by shape rather than position (the `--browser` flag shifts the indices).
26
- const origin = args.find(looksLikeChromeOrigin) ?? argv[3];
27
- await runNativeHost({ origin, browser: normalizeBrowser(readOption(args, "--browser")) });
23
+ if (invocation.mode === "native-host") {
24
+ await runNativeHost({ origin: invocation.origin ?? argv[3], browser: invocation.browser });
28
25
  return;
29
26
  }
30
27
 
28
+ const command = invocation.command;
31
29
  switch (command) {
32
30
  case "install-native-host": {
33
31
  const binPath = readOption(args, "--bin");
@@ -78,6 +76,31 @@ export async function runCli(argv) {
78
76
  }
79
77
  }
80
78
 
79
+ /**
80
+ * Decide how an invocation should be handled, purely from the CLI args.
81
+ *
82
+ * Chrome/Edge launch the native host by appending the extension origin as a
83
+ * positional arg, and the install launcher prepends `--browser <name>`. That
84
+ * prefix shifts the origin out of `args[0]`, so both the mode check and the
85
+ * origin lookup must scan by shape rather than position. (A 1.2.0 regression
86
+ * only checked `args[0]` here, so the launcher's `--browser`-prefixed argv fell
87
+ * through to `Unknown command: --browser` and the native host exited on every
88
+ * connect.)
89
+ */
90
+ export function classifyInvocation(args) {
91
+ if (args.includes("--stdio") || args[0] === "stdio") {
92
+ return { mode: "mcp" };
93
+ }
94
+ if (args.includes("--native-host") || args.some(looksLikeChromeOrigin)) {
95
+ return {
96
+ mode: "native-host",
97
+ origin: args.find(looksLikeChromeOrigin),
98
+ browser: normalizeBrowser(readOption(args, "--browser")),
99
+ };
100
+ }
101
+ return { mode: "command", command: args[0] };
102
+ }
103
+
81
104
  function looksLikeChromeOrigin(value) {
82
105
  return typeof value === "string" && value.startsWith("chrome-extension://");
83
106
  }