@jrwoodcock/modelmux 2.0.0 → 2.0.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/README.md CHANGED
@@ -59,10 +59,20 @@ The installer will:
59
59
  1. Check for Node.js 18+
60
60
  2. Prompt you for API keys and save them to `~/.zshrc`
61
61
  3. Register modelmux with Claude Code and Codex automatically
62
- 4. Run a connectivity test against each API
62
+ 4. Add a Codex tool-routing rule (see [Codex: "ask Claude" opens an app](#codex-ask-claude-opens-an-app-instead-of-calling-modelmux))
63
+ 5. Run a connectivity test against each API
63
64
 
64
65
  Then restart Claude Code and/or Codex to pick up the new MCP server.
65
66
 
67
+ > **Using the Claude or Codex Desktop app?** Both work, with two caveats the
68
+ > installer handles automatically: there's no `claude`/`codex` command on your
69
+ > PATH (the installer finds each app's bundled binary instead), and the apps
70
+ > can't read API keys from `~/.zshrc` (so the keys are baked into the server's
71
+ > config at registration). After installing, **fully quit the app with Cmd+Q** —
72
+ > not just closing the window — then reopen it. In Claude, modelmux appears under
73
+ > **Settings → MCP** as a *user* server (available in every project). See
74
+ > [Troubleshooting](#troubleshooting) if it doesn't show up.
75
+
66
76
  ### Install from npm
67
77
 
68
78
  The server is also published to npm. This gives you the `modelmux` command
@@ -93,18 +103,55 @@ bash install.sh
93
103
 
94
104
  ### Manual registration (if the installer skipped a tool)
95
105
 
96
- If Claude Code or Codex wasn't found during install, register manually after installing them:
106
+ If Claude Code or Codex wasn't found during install, register manually after installing them.
107
+
108
+ **Claude Code (CLI):** register at user scope and pass your keys as `-e` values, so the server has them no matter how the host is launched. The server name (`modelmux`) must come **before** the `-e` flags — `-e` is variadic and would otherwise consume the name:
109
+ ```bash
110
+ claude mcp add -s user modelmux \
111
+ -e ANTHROPIC_API_KEY="sk-ant-..." \
112
+ -e OPENAI_API_KEY="sk-..." \
113
+ -e PERPLEXITY_API_KEY="pplx-..." \
114
+ -- node ~/.modelmux/src/server.js
115
+ ```
116
+
117
+ **Claude Desktop app (no `claude` on PATH):** the app bundles the CLI — call it directly with the same arguments:
118
+ ```bash
119
+ "$HOME/Library/Application Support/Claude/claude-code/"*/claude.app/Contents/MacOS/claude \
120
+ mcp add -s user modelmux -e ANTHROPIC_API_KEY="sk-ant-..." -e OPENAI_API_KEY="sk-..." \
121
+ -e PERPLEXITY_API_KEY="pplx-..." -- node ~/.modelmux/src/server.js
122
+ ```
123
+
124
+ > **Why embed the keys?** A Desktop app is launched from the Dock, so it does
125
+ > **not** load `~/.zshrc` — a server it spawns can't see API keys exported there.
126
+ > Passing the keys at registration (`-e` for Claude, `--env` for Codex) stores
127
+ > them in the MCP config so they're always found. Trade-off: if you later rotate
128
+ > a key in `~/.zshrc`, re-run the registration (or edit the entry) so the stored
129
+ > copy is updated too. The CLI tools inherit keys from your shell, but embedding
130
+ > them is harmless and keeps both paths identical.
97
131
 
98
- **Claude Code:**
132
+ **Codex (CLI):** Codex uses `--env` (not `-e`):
99
133
  ```bash
100
- claude mcp add modelmux -- node ~/.modelmux/src/server.js
134
+ codex mcp add \
135
+ --env ANTHROPIC_API_KEY="sk-ant-..." \
136
+ --env OPENAI_API_KEY="sk-..." \
137
+ --env PERPLEXITY_API_KEY="pplx-..." \
138
+ modelmux -- node ~/.modelmux/src/server.js
101
139
  ```
102
140
 
103
- **Codex:**
141
+ **Codex Desktop app (no `codex` on PATH):** the app bundles the CLI — call it directly:
104
142
  ```bash
105
- codex mcp add modelmux -- node ~/.modelmux/src/server.js
143
+ ~/.codex/plugins/.plugin-appserver/codex \
144
+ mcp add --env ANTHROPIC_API_KEY="sk-ant-..." --env OPENAI_API_KEY="sk-..." \
145
+ --env PERPLEXITY_API_KEY="pplx-..." modelmux -- node ~/.modelmux/src/server.js
106
146
  ```
107
147
 
148
+ > **Tip:** if a Desktop app can't launch the server (it shows as failed/not
149
+ > connected), use the **absolute path to node** instead of bare `node` — apps
150
+ > launched from the Dock may not have your `node` on PATH (common with nvm).
151
+ > Find it with `command -v node`, e.g. `/Users/you/.nvm/versions/node/vXX/bin/node`.
152
+
153
+ After registering, **fully quit and reopen** the app (Cmd+Q, not just closing the window) so it loads the new server.
154
+
108
155
  ---
109
156
 
110
157
  ## API keys
@@ -122,6 +169,18 @@ Then `source ~/.zshrc` and restart Claude Code / Codex.
122
169
 
123
170
  You only need keys for the tools you plan to use. The `broker` tool's synthesis step uses Claude, so `ANTHROPIC_API_KEY` is the most important one.
124
171
 
172
+ ### Updating keys (Desktop apps)
173
+
174
+ Because the Desktop apps embed your keys in their MCP config (they don't read `~/.zshrc`), changing a key in `~/.zshrc` is not enough — the embedded copy goes stale. After rotating a key, re-sync both apps in one command:
175
+
176
+ ```bash
177
+ bash ~/.modelmux/update-keys.sh # or ./update-keys.sh from the cloned repo
178
+ ```
179
+
180
+ It reloads the keys from `~/.zshrc` and re-registers modelmux with Claude and Codex (whichever it finds). Restart the apps (Cmd+Q, then reopen) afterward. Terminal CLIs don't need this — they read `~/.zshrc` directly.
181
+
182
+ The re-registration is safe: Codex is updated in place, and Claude (which must be removed before re-adding) is verified and retried, so a transient failure is reported loudly rather than silently leaving an app unregistered.
183
+
125
184
  ### Optional model overrides
126
185
 
127
186
  ```bash
@@ -291,6 +350,9 @@ You need a small amount of credit loaded on each API account — even $5 on each
291
350
  ```
292
351
  modelmux/
293
352
  ├── install.sh ← run this on each Mac
353
+ ├── update-keys.sh ← re-sync API keys into the Desktop apps after rotating
354
+ ├── lib/
355
+ │ └── common.sh ← shared shell helpers (host detection, key flags)
294
356
  ├── package.json
295
357
  ├── package-lock.json
296
358
  ├── README.md
@@ -310,10 +372,19 @@ modelmux/
310
372
  ## Troubleshooting
311
373
 
312
374
  **Tools don't appear in Claude Code or Codex**
313
- Restart the app after registration. MCP servers are loaded at startup.
375
+ Restart the app after registration. MCP servers are loaded at startup — and for the Desktop app you must fully quit it (Cmd+Q), not just close the window.
376
+
377
+ **Nothing shows up under MCP servers in the Claude or Codex Desktop app**
378
+ The installer's auto-registration only runs if it can find a `claude`/`codex` command. The Desktop apps have neither on your PATH, so on older installs the step was skipped. Re-run `bash install.sh` (it now detects each app's bundled binary), or register manually using the **Desktop app** commands under [Manual registration](#manual-registration-if-the-installer-skipped-a-tool). In Claude it registers at **user** scope, so it appears as a *user* server (available everywhere), not a *local* one.
314
379
 
315
380
  **"X_API_KEY not set" error**
316
- Run `source ~/.zshrc` in your terminal before launching the AI tool, or add the export to your shell profile and open a fresh terminal.
381
+ In a **terminal**-launched tool, run `source ~/.zshrc` first (or open a fresh terminal). In a **Desktop app** (Claude or Codex), exporting keys in `~/.zshrc` is not enough — the app doesn't read your shell profile. Register modelmux with the keys passed as env values (`-e` for Claude, `--env` for Codex; see [Manual registration](#manual-registration-if-the-installer-skipped-a-tool)); the installer does this for you.
382
+
383
+ **Server shows as failed / won't launch in a Desktop app**
384
+ The app may not have `node` on its PATH (common when node is managed by nvm). Re-register using the **absolute path to node** instead of bare `node` — find it with `command -v node`. The installer already does this automatically.
385
+
386
+ **Codex: "ask Claude" opens an app instead of calling modelmux**
387
+ Codex's Computer Use plugin can read "ask Claude" as "open the Claude app on screen" rather than calling modelmux's `ask_claude` tool. The installer adds a routing rule to `~/.codex/AGENTS.md` so "ask `<model>`" phrasing prefers the modelmux tools while leaving Computer Use untouched for everything else — **restart Codex** after install for it to take effect. The rule is fenced by a `<!-- modelmux:tool-routing -->` marker (added once, never overwrites your own notes); delete that marked block to undo. You can always force a tool explicitly: *"use the modelmux `ask_claude` tool to …"*.
317
388
 
318
389
  **Connectivity test fails**
319
390
  Check that the key is correct and that your API account has credit loaded. Perplexity requires a paid API plan (separate from Perplexity Pro).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jrwoodcock/modelmux",
3
- "version": "2.0.0",
3
+ "version": "2.0.1",
4
4
  "description": "MCP server that lets Claude Code, Codex, and Perplexity call each other as tools. Supports text, code, images, and PDFs passed by file path.",
5
5
  "author": "Jason R. Woodcock",
6
6
  "license": "Apache-2.0",
package/src/server.js CHANGED
@@ -25,7 +25,7 @@
25
25
  * Node.js 18 or higher is needed for fetch support.
26
26
  *
27
27
  * @author Jason R. Woodcock
28
- * @version 2.0.0
28
+ * @version 2.0.1
29
29
  * @license Apache-2.0 — see the LICENSE and NOTICE files.
30
30
  */
31
31
 
@@ -639,7 +639,7 @@ rl.on("line", async (line) => {
639
639
  id,
640
640
  result: {
641
641
  protocolVersion: "2024-11-05",
642
- serverInfo: { name: "modelmux", version: "2.0.0" },
642
+ serverInfo: { name: "modelmux", version: "2.0.1" },
643
643
  capabilities: { tools: {} },
644
644
  },
645
645
  });
package/src/test.js CHANGED
@@ -17,7 +17,7 @@
17
17
  * FAIL — the check ran but produced an unexpected result or error
18
18
  *
19
19
  * @author Jason R. Woodcock
20
- * @version 2.0.0
20
+ * @version 2.0.1
21
21
  * @license Apache-2.0 — see the LICENSE and NOTICE files.
22
22
  */
23
23