claude-multiacc 2.0.57 → 2.0.59
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 +111 -3
- package/bin/claude +323 -84
- package/bin/claude-accounts +273 -42
- package/bin/codex +15 -0
- package/bin/codex-accounts +31 -4
- package/docs/ACCOUNT_OPERATIONS.md +62 -2
- package/docs/AUTORESUME-HANDOFF.md +30 -3
- package/docs/AUTORESUME.md +275 -18
- package/docs/CODEX.md +1 -0
- package/docs/INSTALLATION.md +7 -1
- package/docs/VERIFICATION.md +4 -0
- package/lib/__pycache__/audit.cpython-312.pyc +0 -0
- package/lib/__pycache__/autoresume.cpython-312.pyc +0 -0
- package/lib/__pycache__/autoresume_cross.cpython-312.pyc +0 -0
- package/lib/__pycache__/autoresume_cross_dispatch.cpython-312.pyc +0 -0
- package/lib/__pycache__/autoresume_cross_receipt.cpython-312.pyc +0 -0
- package/lib/__pycache__/autoresume_handoff.cpython-312.pyc +0 -0
- package/lib/__pycache__/autoresume_probe.cpython-312.pyc +0 -0
- package/lib/__pycache__/autoresume_receipt.cpython-312.pyc +0 -0
- package/lib/__pycache__/claude_client_error.cpython-312.pyc +0 -0
- package/lib/__pycache__/claude_reset.cpython-312.pyc +0 -0
- package/lib/__pycache__/claude_token_identity.cpython-312.pyc +0 -0
- package/lib/__pycache__/codex_autoresume_mode.cpython-312.pyc +0 -0
- package/lib/__pycache__/codex_config_edit.cpython-312.pyc +0 -0
- package/lib/__pycache__/codex_credit_controls.cpython-312.pyc +0 -0
- package/lib/__pycache__/codex_credit_local_scope.cpython-312.pyc +0 -0
- package/lib/__pycache__/codex_credit_selection.cpython-312.pyc +0 -0
- package/lib/__pycache__/codex_credits.cpython-312.pyc +0 -0
- package/lib/__pycache__/codex_limits_lock.cpython-312.pyc +0 -0
- package/lib/__pycache__/codex_python.cpython-312.pyc +0 -0
- package/lib/__pycache__/codex_trust.cpython-312.pyc +0 -0
- package/lib/__pycache__/codex_usage_fetch.cpython-312.pyc +0 -0
- package/lib/__pycache__/keychain.cpython-312.pyc +0 -0
- package/lib/__pycache__/mcp_oauth.cpython-312.pyc +0 -0
- package/lib/__pycache__/mcp_registry.cpython-312.pyc +0 -0
- package/lib/__pycache__/model_catalog.cpython-312.pyc +0 -0
- package/lib/__pycache__/model_match.cpython-312.pyc +0 -0
- package/lib/__pycache__/report.cpython-312.pyc +0 -0
- package/lib/__pycache__/selector_credit_scope.cpython-312.pyc +0 -0
- package/lib/__pycache__/selector_credits.cpython-312.pyc +0 -0
- package/lib/__pycache__/selector_funding.cpython-312.pyc +0 -0
- package/lib/__pycache__/selector_policy.cpython-312.pyc +0 -0
- package/lib/__pycache__/selector_primitives.cpython-312.pyc +0 -0
- package/lib/__pycache__/session_settings.cpython-312.pyc +0 -0
- package/lib/__pycache__/shim_path.cpython-312.pyc +0 -0
- package/lib/audit.py +88 -22
- package/lib/autoresume.py +1197 -82
- package/lib/autoresume_cross.py +3 -1
- package/lib/autoresume_handoff.py +82 -10
- package/lib/autoresume_probe.py +2 -2
- package/lib/claude_client_error.py +9 -4
- package/lib/codex_trust.py +263 -0
- package/lib/common.sh +131 -3
- package/lib/credential.py +5 -2
- package/lib/install_actions.sh +19 -0
- package/lib/keychain.py +180 -36
- package/lib/mcp_oauth.py +1748 -0
- package/lib/model_catalog.json +404 -0
- package/lib/model_catalog.py +201 -0
- package/lib/model_match.py +104 -0
- package/lib/report.py +8 -5
- package/lib/session_settings.py +123 -0
- package/package.json +2 -2
- package/tests/__pycache__/autoresume_cross_receipt_support.cpython-312.pyc +0 -0
- package/tests/__pycache__/autoresume_cross_tmux_environment.cpython-312.pyc +0 -0
- package/tests/__pycache__/autoresume_cross_tmux_support.cpython-312.pyc +0 -0
- package/tests/__pycache__/autoresume_cross_unit_support.cpython-312.pyc +0 -0
- package/tests/__pycache__/autoresume_tmux_support.cpython-312.pyc +0 -0
- package/tests/__pycache__/packaged_command_support.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_autoresume.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_autoresume_catalog.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_autoresume_catalog_cli.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_autoresume_codex_records.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_autoresume_codex_trust.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_autoresume_cross_claude_holders.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_autoresume_cross_guards.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_autoresume_cross_holders.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_autoresume_cross_origin.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_autoresume_cross_policy.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_autoresume_cross_receipt.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_autoresume_cross_tmux.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_autoresume_cross_tmux_races.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_autoresume_cross_tokens.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_autoresume_cursor.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_autoresume_fallback.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_autoresume_handoff_argv.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_autoresume_handoff_history.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_autoresume_handoff_origins.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_autoresume_memory.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_autoresume_memory_tmux.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_autoresume_mode.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_autoresume_probe.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_autoresume_receipt.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_autoresume_relaunch_settings.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_autoresume_settings.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_autoresume_sidechain.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_autoresume_sidechain_tmux.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_autoresume_tmux.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_autoresume_tmux_modes.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_autoresume_trust_tmux.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_claude_reset.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_claude_token_identity.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_codex_reset.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_codex_reset_credits.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_codex_reset_credits_polling.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_codex_reset_credits_report.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_codex_reset_fetch.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_codex_reset_polling.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_codex_reset_reporting.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_codex_reset_windows.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_selector.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_selector_cached_credits.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_selector_credit_scope.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_selector_credit_shim.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_selector_credits.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_selector_spread.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_token_identity_ceremony.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_token_identity_integration.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_token_identity_retry.cpython-312.pyc +0 -0
- package/tests/__pycache__/test_token_identity_sync.cpython-312.pyc +0 -0
- package/tests/fake_codex_tui.py +25 -0
- package/tests/fake_security.sh +24 -2
- package/tests/fixtures/cross_provider_cli.py +111 -1
- package/tests/run-tests.sh +1028 -23
- package/tests/test_autoresume.py +215 -8
- package/tests/test_autoresume_catalog.py +226 -0
- package/tests/test_autoresume_catalog_cli.py +185 -0
- package/tests/test_autoresume_codex_records.py +16 -0
- package/tests/test_autoresume_codex_trust.py +247 -0
- package/tests/test_autoresume_cross_guards.py +28 -0
- package/tests/test_autoresume_cross_origin.py +70 -0
- package/tests/test_autoresume_cross_tmux.py +27 -2
- package/tests/test_autoresume_cross_tokens.py +32 -2
- package/tests/test_autoresume_handoff_argv.py +120 -16
- package/tests/test_autoresume_handoff_origins.py +67 -0
- package/tests/test_autoresume_memory.py +1141 -0
- package/tests/test_autoresume_memory_tmux.py +94 -0
- package/tests/test_autoresume_probe.py +2 -1
- package/tests/test_autoresume_relaunch_settings.py +317 -0
- package/tests/test_autoresume_settings.py +135 -0
- package/tests/test_autoresume_sidechain.py +1518 -0
- package/tests/test_autoresume_sidechain_tmux.py +79 -0
- package/tests/test_autoresume_trust_tmux.py +63 -0
- package/tests/test_claude_client_error.py +10 -7
- package/tests/test_claude_org_block.py +1 -0
- package/tests/test_claude_pool_prepare.py +4 -1
- package/tests/test_claude_reset.py +3 -0
- package/tests/test_keychain_nologin.py +340 -0
- package/tests/test_mcp_oauth.py +1414 -0
- package/tests/test_packaged_commands.py +41 -0
package/README.md
CHANGED
|
@@ -59,6 +59,7 @@ MAC (source of truth) SERVER (mirror)
|
|
|
59
59
|
server.token / .credentials.json
|
|
60
60
|
(or the login lives in the macOS Keychain — see below)
|
|
61
61
|
selection.log sync.log health.log /usr/local/bin/claude -> repo shim
|
|
62
|
+
mcp-oauth.json (MCP OAuth, never synced)
|
|
62
63
|
repo bin/ first on PATH (rc block + hook) /root/claude-multiacc/ (addon repo)
|
|
63
64
|
```
|
|
64
65
|
|
|
@@ -297,6 +298,18 @@ account's `.credentials.json` (0600), or its macOS Keychain item.
|
|
|
297
298
|
> identity checked out prunes every sibling; `remove` deletes every item.
|
|
298
299
|
> `python3 lib/keychain.py prune <acct dir>` prunes by hand (only when the canonical item
|
|
299
300
|
> is a live login; it never writes).
|
|
301
|
+
> **A login, not any credentials document.** The same document (file or Keychain item) also
|
|
302
|
+
> holds the client's MCP servers' OAuth state (`mcpOAuth`), and from ssh/tmux Claude Code
|
|
303
|
+
> writes a `.credentials.json` holding only that once an OAuth MCP server is discovered. The
|
|
304
|
+
> pool counts a document as a login only when it carries `claudeAiOauth`: one with MCP
|
|
305
|
+
> state alone leaves the account to its Keychain login or `server.token` (`list` shows
|
|
306
|
+
> `auth=token`, or `NO-LOGIN`), expiry is read from the login object alone, such a rewrite
|
|
307
|
+
> never heals an `.expired` park, and every login multiacc writes (refresh, migration,
|
|
308
|
+
> `import --creds`) lands INTO the document with its MCP state kept. The limits pass's
|
|
309
|
+
> refresh and migration write under the client's own `<acct>/.storage-write.lock`, never
|
|
310
|
+
> across the token request: a refresh that finds the lock held skips (the next pass
|
|
311
|
+
> retries), and the rotated login waits for a client write in flight instead of being
|
|
312
|
+
> rolled back by it.
|
|
300
313
|
> Override: `CLAUDE_MULTIACC_KEYCHAIN=0` disables the lookup. This is what keeps idle accounts' telemetry fresh so they win
|
|
301
314
|
selection over busy accounts; without it, stale telemetry ranks neutral and a truly-idle
|
|
302
315
|
account would lose to a busy-but-fresh one. Refresh failures fail open and back off via
|
|
@@ -324,7 +337,10 @@ the session → account mapping comes from `<acct>/sessions/<pid>.json`, which t
|
|
|
324
337
|
maintains only while a run is alive. The shim spawns a short detached poll before `exec`
|
|
325
338
|
(the pid survives `exec`, so it knows the filename) that records the session id — with the
|
|
326
339
|
session's own start time — in `<acct>/.sessions-index`; selection then tail-scans those
|
|
327
|
-
transcripts.
|
|
340
|
+
transcripts. The poll also records which credential the run carries, the portable token
|
|
341
|
+
or the login, by PROCESS (`<acct>/.sessions-via/<pid>`, valid only while the registry's
|
|
342
|
+
`startedAt` matches), so a session the client switches the run to (`/clear`, `/resume`
|
|
343
|
+
inside the TUI) is charged to the same credential when it fails to authenticate.
|
|
328
344
|
|
|
329
345
|
Fresh account seeding creates `~/.claude/projects` before linking each account, even
|
|
330
346
|
if stock Claude has never run on that machine. For an existing pool with private
|
|
@@ -360,6 +376,12 @@ next selection. It has no automatic expiry; full `claude-accounts verify` must p
|
|
|
360
376
|
access after the organization enables it. `.client-org-cleared` suppresses transcript
|
|
361
377
|
errors recorded before that verification.
|
|
362
378
|
|
|
379
|
+
An interactive `authentication_failed` parks the credential that run carried. The poll
|
|
380
|
+
tags a session's index line `token` when the shim launched the run on the account's
|
|
381
|
+
portable token, and only such a failure retires the token (`setup-token-invalid`); any
|
|
382
|
+
other is the login's (`auth-error`) — a run that carried no token says nothing about it.
|
|
383
|
+
The verification watermark above supersedes these records too, so a PASS sticks.
|
|
384
|
+
|
|
363
385
|
The resulting usage marker is tagged `reason=client-rate-limit` and outlives a clean telemetry
|
|
364
386
|
pass while its window is still open — first-hand evidence beats a usage payload that
|
|
365
387
|
disagrees. A **weekly** rejection is absolute: nothing — neither a shim invocation nor the
|
|
@@ -441,7 +463,8 @@ Interactive sessions are not retried this way. They get auto-resume, described n
|
|
|
441
463
|
## Auto-resume
|
|
442
464
|
|
|
443
465
|
An interactive `claude` or `codex` session in **tmux** can stop on a usage limit, a failed
|
|
444
|
-
login, an API error or (claude) a crash
|
|
466
|
+
login, an API error or (claude) a crash, or show Claude Code's "Critical memory usage"
|
|
467
|
+
warning. It is then **resumed automatically, same session
|
|
445
468
|
id**, on another pooled account with headroom. If a usage limit exhausts that provider's
|
|
446
469
|
usable accounts, it can continue in the other provider with instructions to read the
|
|
447
470
|
original conversation's history. There is no `/exit`, no `--resume` and no
|
|
@@ -479,9 +502,26 @@ touch ~/.codex-accounts/autoresume.off # codex pool off
|
|
|
479
502
|
CLAUDE_MULTIACC_AUTORESUME=0 claude # one launch (CODEX_MULTIACC_AUTORESUME=0 codex)
|
|
480
503
|
```
|
|
481
504
|
|
|
505
|
+
**Model and effort.** A relaunch keeps the session on the model and effort it last ran
|
|
506
|
+
with, read from the session's own history, so a `/model` or `/effort` switch made after the
|
|
507
|
+
launch counts. A continuation in the other provider starts on the model and effort of the
|
|
508
|
+
same level. Both read the **model catalog**: the copy this release ships, merged with the
|
|
509
|
+
model caches Claude Code and Codex keep in their account dirs, written to
|
|
510
|
+
`<pool>/model-catalog.json`. It sends no request and reads no credential. Every install and
|
|
511
|
+
`self-update` refreshes it in both pools, and each limits pass refreshes its own pool's copy
|
|
512
|
+
once it is an hour old, so the matching follows new models between releases.
|
|
513
|
+
|
|
514
|
+
```bash
|
|
515
|
+
claude-accounts model-catalog show # the merged catalog a relaunch matches with
|
|
516
|
+
claude-accounts model-catalog refresh # rewrite both pools' copies now
|
|
517
|
+
```
|
|
518
|
+
|
|
519
|
+
`CLAUDE_MULTIACC_MODEL_CATALOG=0` or `CODEX_MULTIACC_MODEL_CATALOG=0` stops the refresh of
|
|
520
|
+
that pool's copy, and `MULTIACC_MODEL_CATALOG=0` stops both.
|
|
521
|
+
|
|
482
522
|
See [auto-resume: error classes, gates, budgets, logs and limitations](docs/AUTORESUME.md).
|
|
483
523
|
See [continuing between Codex and Claude](docs/AUTORESUME-HANDOFF.md) for history,
|
|
484
|
-
permission handling and the cross-provider opt-out.
|
|
524
|
+
permission handling, model matching and the cross-provider opt-out.
|
|
485
525
|
|
|
486
526
|
## MCP servers for every account
|
|
487
527
|
|
|
@@ -562,6 +602,74 @@ claude-accounts mcp apply # re-apply now (repair drift)
|
|
|
562
602
|
seed and launch and the shim's mirror; `claude-accounts mcp …`, sync and the fan-out still
|
|
563
603
|
work.
|
|
564
604
|
|
|
605
|
+
### MCP OAuth logins: sign in once, every account has it
|
|
606
|
+
|
|
607
|
+
A server that signs in with OAuth (higgsfield, say) keeps its login in the account's
|
|
608
|
+
**credential store** — `mcpOAuth` in `<acct>/.credentials.json`, or in the account's
|
|
609
|
+
Keychain item — not in `.claude.json`, so the registry cannot carry it. Under the pool a
|
|
610
|
+
server authenticated in one account said *needs authentication* under every other account
|
|
611
|
+
the shim picked (2026-10-19: five separate higgsfield grants in five accounts,
|
|
612
|
+
discovery-only stubs in the rest). The claude pool now shares those logins **on this
|
|
613
|
+
machine**:
|
|
614
|
+
|
|
615
|
+
```bash
|
|
616
|
+
claude-accounts mcp auth-status # per server: the pool's login; per account: fresh, stale, own, stub, missing or absent
|
|
617
|
+
claude-accounts mcp auth-status --json
|
|
618
|
+
claude-accounts mcp auth-sync # harvest, refresh what is due, share into every account, now
|
|
619
|
+
claude-accounts mcp auth-forget higgsfield # log it out of EVERY account on this machine
|
|
620
|
+
```
|
|
621
|
+
|
|
622
|
+
- **Harvest**: every account's MCP logins — its file, and its Keychain item when this
|
|
623
|
+
session can open it — are folded into `<pool>/mcp-oauth.json` (0600). Per server the
|
|
624
|
+
latest save wins (the largest `expiresAt`: the client stamps it on every save; a login
|
|
625
|
+
saved without one counts as expiring an hour after it was found, never as the oldest); a
|
|
626
|
+
discovery-only stub (`accessToken: ""`) never overwrites anything.
|
|
627
|
+
- **Share**: the shim merges the newest login into the picked account right before exec —
|
|
628
|
+
no network, and python only when an account's credential file or the store changed since
|
|
629
|
+
that account last looked — and every claude `limits` pass shares into all accounts. A
|
|
630
|
+
merge goes into a store that exists; a `.credentials.json` is **created** — holding the
|
|
631
|
+
MCP logins alone, 0600 — only for an account that runs on its setup token (no `.expired`
|
|
632
|
+
park, not an adopted dir), whose client has nowhere else to read them from in an ssh/tmux
|
|
633
|
+
session. That file costs the token nothing: a document without `claudeAiOauth` is no
|
|
634
|
+
Claude login to the shim, the limits pass, the audit or verify (`list` shows `auth=token`),
|
|
635
|
+
and it is the file the client writes itself once it meets an OAuth server. An account
|
|
636
|
+
with a Keychain login gets its item updated instead and never a file. A merge takes the
|
|
637
|
+
client's own lock (`<acct>/.storage-write.lock`), re-reads, changes that one `mcpOAuth` key
|
|
638
|
+
and nothing else (the Claude login beside it is never rewritten), and keeps the file's
|
|
639
|
+
mtime. A Keychain item is updated only when it already exists and this session can open
|
|
640
|
+
it, then read back; one is never created. An account parked with `.expired` gets no
|
|
641
|
+
Keychain write and no new file until it is back in the pool. A login the account holds of
|
|
642
|
+
another grant is replaced only when it is provably older.
|
|
643
|
+
- **Refresh**: the limits pass is the only refresher — one login in many accounts must have
|
|
644
|
+
ONE, because each client refreshes under its own config dir's lock and refresh tokens
|
|
645
|
+
rotate. A login is refreshed at its authorization server (RFC 8414 metadata, the refresh
|
|
646
|
+
grant with `resource` = the server URL) two hours before it expires, or at half its
|
|
647
|
+
lifetime when that is shorter (never twice per half-lifetime), long before a client's own
|
|
648
|
+
5-minute window, then shared everywhere. A failure backs off 15 min, doubling to 6 h (`mcp
|
|
649
|
+
auth-sync --force` retries now); a refused refresh token (`invalid_grant`) shows as **NEEDS
|
|
650
|
+
RE-AUTH**: sign in once in any account (`/mcp`) and that new login replaces it everywhere.
|
|
651
|
+
A login with a copy in a Keychain item this session cannot open is left to a pass that
|
|
652
|
+
can (a Terminal on the Mac, the scheduled agent) until 20 minutes before it expires.
|
|
653
|
+
- **Nothing is shared without that refresher**: not with
|
|
654
|
+
`CLAUDE_MULTIACC_MCP_OAUTH_REFRESH=0`, not by a launch when no refreshing limits pass ran in
|
|
655
|
+
the last hour, and not a login within the clients' own 5-minute window, refused by its
|
|
656
|
+
server, or whose failing refresh would next try too late. Each account keeps what it holds;
|
|
657
|
+
`auth-status` says why (`NOT shared: …`, `sharing paused: …`).
|
|
658
|
+
- **Machine-local**: `mcp-oauth.json` is never synced or fanned out — a grant belongs to the
|
|
659
|
+
machine it was issued on, so each Mac signs in once.
|
|
660
|
+
- **Logging out**: a `/mcp` "Clear authentication", `claude mcp login <server>` or a
|
|
661
|
+
re-authentication in ANY one account revokes the stored login at the server (when it
|
|
662
|
+
supports revocation — higgsfield does) — and under the pool that login is every account's.
|
|
663
|
+
So the pool retires it everywhere the moment it sees the key gone or blanked in an account
|
|
664
|
+
that held it; sign in once in any account and the new login is shared again. `mcp
|
|
665
|
+
auth-forget NAME` is the same logout from the operator's side: it drops the login from the
|
|
666
|
+
pool and every account store, and a copy it could not reach (a Keychain item this session
|
|
667
|
+
cannot open) stays ignored and is cleared by a later pass.
|
|
668
|
+
- **Kill switches**: `CLAUDE_MULTIACC_MCP_OAUTH=0` stops sharing (the shim's merge and the
|
|
669
|
+
limits pass's sync); `CLAUDE_MULTIACC_MCP_OAUTH_REFRESH=0` never refreshes — and so shares
|
|
670
|
+
nothing. `auth-status` and `auth-forget` always run. Claude pool only: Codex keeps MCP
|
|
671
|
+
OAuth in its own store, and `codex-accounts mcp auth-…` says so.
|
|
672
|
+
|
|
565
673
|
app-robot tasks are different: the panel launches Claude with `--strict-mcp-config` and a
|
|
566
674
|
merged MCP document (`agent_mcp.servers_for`) and Codex with the same document as `-c`
|
|
567
675
|
overrides, so a server every task must see is added there — never with `claude mcp add` on a
|