Claude Auth Manager
Use several Claude subscriptions and several API keys from one Claude Code
installation. Every saved account or key gets its own exact route in Claude Code's
/model picker, so two keys that expose the same upstream model remain separate
choices.
Supported credentials:
- Claude.ai subscriptions, including multiple isolated OAuth logins
- OpenRouter API keys
- Google Gemini API keys (direct, through Google's OpenAI-compatible endpoint)
- Anthropic API keys
All configured credentials can be active at the same time. One request uses one route, but foreground sessions, subagents, and background agents can concurrently use different routes and keys.
Install
Requirements: Python 3.10+ or uv. Claude Code is required to use CAM; the
installer installs it from its official installer if Claude is missing.
curl -fsSL https://raw.githubusercontent.com/xhluca/claude-auth-manager/main/install.sh | sh
The installer uses uv tool install when available. Otherwise it creates a private
Python environment under ~/.local/share/claude-auth-manager/tool and links cam
and claude-auth-manager into ~/.local/bin. It never uses sudo or modifies the
system Python. PyPI is tried first; a checksum-pinned GitHub release wheel is the
fallback if PyPI is unavailable. No GitHub login is required.
The final setup step registers the currently logged-in Claude account. For agents, CI, or updating an existing setup without touching accounts or model choices:
curl -fsSL https://raw.githubusercontent.com/xhluca/claude-auth-manager/main/install.sh \
| sh -s -- --install-only
Add --skip-claude-install to fail instead of installing a missing Claude Code.
To inspect the script first, download it with curl -fsSLO and run
sh install.sh --install-only after reviewing it.
Prefer uv directly?
uv tool install claude-auth-manager
cam account add --current
For a pinned installation: uv tool install 'claude-auth-manager==0.0.6'.
Ensure ~/.local/bin is on your PATH (uv tool update-shell can help for uv installs).
Update, reset, and uninstall
cam update
cam reset
cam uninstall
cam update installs the latest stable PyPI version using the package manager
that owns the running CAM installation (uv, pipx, or its private Python environment).
It keeps accounts, keys, and selected models. Development checkouts are protected
against replacement by an older registry version.
cam reset stops the router, restores backed-up Claude settings, and deletes
CAM's saved accounts, keys, catalogs, and state; the CLI stays installed.
cam uninstall performs that reset and removes the owning uv/pipx/private-environment
installation. It does not uninstall Claude Code or guess at removing a development
or shared-system Python install. Export anything you need before reset/uninstall.
Installer overrides: CLAUDE_AUTH_MANAGER_PYPI_INDEX_URL selects a package index;
CLAUDE_AUTH_MANAGER_INSTALL_BASE_URL selects the fallback wheel directory
(the pinned checksum still applies); CLAUDE_AUTH_MANAGER_TOOL_DIR selects the
private environment; XDG_BIN_HOME selects its command-link directory. Standard
UV_TOOL_DIR / UV_TOOL_BIN_DIR and XDG data/config locations are respected.
Add accounts and keys
Register the Claude account currently used by claude:
cam account add --current
Sign in to another Claude account without replacing the native login:
cam account add
Claude subscription names default to the authenticated email; no separate nickname
is required. cam account add runs Claude Code's official login flow with an
isolated CLAUDE_CONFIG_DIR, where Claude asks which email to use. Add --current
to register the already-active native login instead, or --name NAME to assign an
optional nickname. OAuth refresh remains delegated to the installed Claude Code
CLI.
Signing in to an already-saved account updates that account, keeping its route
ID, nickname, and selected models. You do not need to invent a new name. If the
account was registered with --current, the new login becomes an isolated managed
profile; the native Claude login is left untouched. Login is staged privately, so
cancelling or signing into a different account cannot overwrite the saved login.
CAM opens Claude's hosted code login, not the automatic login link that
redirects the browser to localhost. Sign in and paste the complete code from
Claude's page into CAM. This is the default on every machine, including SSH,
containers, and WSL; it does not depend on detecting where your browser runs.
If the browser does not open, open the sign-in link printed in the terminal.
If no code is displayed, paste the entire hosted callback URL from the address
bar instead; CAM accepts that URL directly too.
Input is masked with one * per character and checked against the current login.
No port forwarding, second terminal, or extra command is needed. As a fallback,
the prompt also accepts the entire URL of a failed localhost callback from an
older login flow. Do not share callback URLs or login codes.
You can also add a long-lived token created with claude setup-token. Paste it
at the masked prompt; no nickname is required:
claude setup-token
cam account add --token
For secret pipes, use cam account add --token-stdin. The manager derives a stable,
non-secret identifier from unnamed tokens. --name NAME is available when a human
nickname would be useful. Token values are deliberately never accepted as command-line
arguments, where shell history and process listings could expose them.
Add as many keys as needed. Secret input is masked by default. --key-path PATH is
the preferred noninteractive form for agents and secret mounts; --key-stdin works
for pipes. Inline --key KEY is also supported when convenience outweighs the risk
of shell-history and process-list exposure.
cam key add personal --provider openrouter
cam key add personal --provider openrouter --key 'YOUR_OPENROUTER_KEY'
cam key add personal --provider openrouter --key-path /run/secrets/openrouter
cam key add lab --provider openrouter
cam key add google-work --provider google
cam key add google-personal --provider google
cam key add anthropic-team --provider anthropic-api
List credentials together, or select one metadata view. These commands print only metadata, never secret values:
cam list
cam list --account
cam list --key
cam list --model --account primary@example.com sonnet --json
cam list --model --key personal qwen --json
cam list --route
cam list --config
cam check
Select routes
cam select refreshes every OpenRouter key through OpenRouter's authenticated,
guardrail-filtered model endpoint before resolving or displaying routes. This
also updates models added or removed since the key was first indexed. A failed
refresh aborts selection instead of trusting stale access. Other providers keep
their explicit cam index refresh behavior. Then select any mixture of accounts
and keys:
cam index
cam search gemini --tools
cam search qwen --key personal
# Start on one subscription and omit other subscriptions from this edit:
cam select --account primary@example.com
# Account filtering also disambiguates short model IDs in scripted selection:
cam select --account primary@example.com claude-sonnet-5
cam select \
'anthropic/primary@example.com/claude-sonnet-5' \
'anthropic/secondary@example.com/claude-sonnet-5' \
openrouter/personal/qwen/qwen3-coder \
openrouter/lab/qwen/qwen3-coder \
google/google-work/gemini-3.8-flash
The interactive picker has one Source dropdown for everything: All, each Claude
subscription, and each OpenRouter, Google, or direct Anthropic API key. Press
Tab, type to search accounts or key nicknames, then press Enter to filter the
model list. Search and Source are shown on separate lines, and selections remain
selected while their source is hidden.
--account ACCOUNT is optional and always takes a value. It limits which Claude
subscriptions participate in the edit and starts on that subscription when only
one is supplied; API-key sources remain available in the same dropdown. Favorites
from other Claude subscriptions are preserved, while visible API-key favorites
remain editable. Account IDs and labels are both accepted, and --account can be
repeated. Routes no longer exposed by refreshed provider catalogs are removed.
Then run normal Claude Code and use /model:
claude
There is no single global active profile. Every selected route remains active.
A Claude process starts with its saved default (or --model), and /model
hot-switches the live conversation beginning with its next request while also
saving that choice as the default for new sessions. CAM routes every request from
its current model field; it does not pin a session to its launch model. Earlier
turns remain in the conversation and were still produced by their earlier models.
To choose before launch, pass the exact managed route to Claude directly:
claude --model cam/openrouter/personal/qwen/qwen3-coder
claude --model 'cam/anthropic/primary@example.com/claude-sonnet-5[1m]'
Starting a second Claude process with another route does not switch or stop the
first one. cam select changes which routes are allowed and restarts the local
router, so avoid changing the selection during an in-flight request: retained
routes reconnect and continue, while a removed route is rejected on its next
request instead of falling back to another credential. Existing Claude processes
are not killed. Reopen /model to refresh its picker; reopen /agents when you
want Claude Code to refresh generated subagent definitions.
Both cam select and Claude's /model picker keep labels compact: each row starts
with only the model name, such as Gemini 3.8 Flash, Sonnet 5, or Opus 4.8.
For Sonnet and Opus routes configured for 1M, the name includes (1M context)
to distinguish the extended window, matching Claude Code's picker. Fable keeps
its plain name because its 1M window is standard. Picker selections and generated
presets include Claude's [1m] annotation where needed; the router still receives
the same account/key route and upstream model ID. Fable also opts into 1M
internally for gateway sessions, without adding the suffix to its visible name. See
Claude Code's context configuration.
Every custom description uses one compact provenance convention:
Claude · Max 20x (account@example.com) via claude-auth-manager
Google · Gemini API (google-work) via claude-auth-manager
Z.AI · OpenRouter (personal) via claude-auth-manager · 0.075 in / 0.25 out / 0.015 cached ($/M) · z-ai/glm-5.3-flash
The first field is the model maker, followed by the credential type and its email
or nickname. The subscription multiplier comes from saved login metadata; when it
is unavailable, the description does not guess it. Other reported plans, such as
Plus, are shown as-is, and token-only accounts with no plan metadata show
Subscription. Pricing is included only when the catalog publishes input and
output rates; — marks an unpublished cached-input rate. The exact model slug is
appended only for OpenRouter. Prices are rounded to at most three decimals for
input/output and four for cached input, with redundant trailing zeroes removed.
Tools and context stay out of descriptions. Full
credential IDs and cam/... routes stay out of the interactive selector and its
save confirmation. The confirmation uses the same short model name and provenance
as the picker.
Picker IDs are fail-closed and credential-specific:
cam/anthropic/primary@example.com/claude-sonnet-5
cam/openrouter/personal/qwen/qwen3-coder
cam/openrouter/lab/qwen/qwen3-coder
cam/google/google-work/gemini-3.8-flash
If only one credential exposes a model, cam select qwen/qwen3-coder is accepted.
When several keys expose it, cam reports the ambiguity and asks for an exact
provider/key/model route.
Model-specific subagent definitions are generated alongside the picker entries.
This allows a parent on one credential to invoke a named subagent pinned to a
different credential. The pre-tool hook prevents Claude Code from silently
replacing that exact subagent model with sonnet.
Commands
Automatic fallback
Each selected model route can have a ranked list of fallbacks on any selected
account, key, or provider. In cam select, highlight a selected model and press
Ctrl-F. Type to search the model pool; Enter adds/removes the highlighted model.
Tab switches between the pool and the ranked list. Ctrl-U moves a selected
fallback up; Ctrl-D moves it down. Ctrl-S applies the list; Esc cancels the edit.
Save the main picker with s to commit; cancelling it discards all edits.
Models hidden by an account filter remain available as fallback destinations.
Circular links are allowed; a route is never attempted twice in one request.
Set a route's entire ranked list with one command; this does not change favorites:
cam select 'cam/anthropic/primary@example.com/claude-opus-5' --fallback \
'cam/anthropic/backup@example.com/claude-sonnet-5' \
'cam/openrouter/personal/z-ai/glm-5.3-flash'
cam list --fallback
cam list --fallback 'cam/anthropic/primary@example.com/claude-opus-5' --json
cam select --clear-fallback 'cam/anthropic/primary@example.com/claude-opus-5'
Use cam list --route --json to discover your exact selected routes. Link-only
edits take effect on the running router's next request; no service or Claude
restart is needed. Removing a favorite removes its incoming and outgoing links.
Fallback is opt-in: CAM never chooses another paid key or account by itself.
When a route returns insufficient credits (402), a usage limit (429), a temporary server error (500/502/503/504/529), a timeout (408), or a connection failure, CAM tries ranked alternatives with their own credentials. Direct alternatives take priority over their descendants: A → [B, C], B → [D] attempts A, B, C, D. Duplicate visits (including circular links) are skipped. Each request starts a fresh traversal, subject to cooldowns. It can walk through several unavailable accounts in one request. Authentication, permission/guardrail, and invalid-request errors are returned directly. No undeclared route is tried.
Provider Retry-After and rejected Anthropic limit-reset headers determine when
to try a route again. Without a reset hint, defaults are 60 seconds for outages,
5 minutes for usage limits, and 15 minutes for exhausted credits. Cooldowns are
saved across router restarts. Each request starts from its originally selected
route, skips routes still cooling down, and automatically returns to an earlier
route once it succeeds again. Other Claude sessions retain their own selection.
While fallback is in use, CAM inserts a visible CAM fallback active banner in
the response and updates the original /model entry's description with the actual
destination. The selected row remains the primary so recovery remains automatic;
the upstream response and routing notice identify the model that really answered.
Claude's settings watcher may take a few seconds to refresh the description.
cam list --config --json exposes configured links, current activations, failure
reasons, and retry deadlines for agents. The picker annotation is shared across
sessions using that primary route; the banner describes each actual response.
Early errors inside an HTTP-200 stream can also fall back. Once any content or
tool call has reached Claude, CAM does not replay it: it reports the interrupted
stream, marks that route unavailable, and uses the fallback on Claude's next retry
or request. This avoids duplicating tool work. A chain with no healthy destination
returns an explicit error after at most one attempt per route. Fallback does not
silently truncate a conversation to fit a smaller model's context or remove user
images; the destination must support the request. Built-in aliases such as opus
are not tied to a saved account link; choose the account-specific CAM picker row.
Every public command, argument, and option is listed below. Run bare cam,
cam account, or cam key to see the corresponding help without an error.
Native Sonnet / permission-classifier accounts
Claude's auto-mode permission classifier can request a native Sonnet model independently of the selected chat model. Switching chat accounts therefore does not necessarily switch the classifier's credentials. Opt in to a separate account order (saved Claude subscriptions only):
cam select --classifier primary@example.com backup@example.com
cam list --classifier
cam list --classifier --json
cam select --clear-classifier
After the updated router is running, account-order edits apply on its next request,
without changing /model, favorites, or permission mode. The first account is
tried first; availability errors such as quota limits and outages advance to the
next, with the usual cooldowns. The exact Sonnet model ID (including [1m]),
system prompt, thinking settings, and output schema are preserved. Responses
receive no routing banners that could corrupt a permission decision. A denial
is returned unchanged, not retried; authentication/permission errors and exhausted
chains fail closed. No automatic approval or alternative-model classification
is performed.
Scope: this handles all native Sonnet requests passing through CAM, including
classifiers, because no reliable classifier-only request marker is assumed
available. Managed cam/... model routes keep their independent fallback chains;
requests bypassing CAM are unaffected. Listing shows the configured order and
last recorded routing status; it does not send a classifier request. Clearing
restores the session's original credentials. Select the order explicitly—CAM
does not silently enroll accounts. Updating from an older release requires the
usual router restart once before these new controls can take effect.
General
cam [-h] [--version] COMMAND ...
-h,--help— show help for the current command and exit.--version— print the installed CAM version and exit.
cam list
cam list [QUERY...] [--model] [--account [ACCOUNT] | --key [KEY]]
[--provider PROVIDER]... [--tools] [--offline] [--json]
cam list [--route | --config] [--check-confirmation {ask,never}] [--json]
cam list --fallback [ROUTE] [--json]
cam list --classifier [--json]
- No view flag — list non-secret metadata for all saved accounts and provider keys.
--accountwithout--model— list only Claude subscription accounts.--keywithout--model— list only provider API keys.--model— statically list available credential-scoped model routes; refreshes each OpenRouter key's current guardrail-filtered catalog first.QUERY...— with--model, filter IDs, names, descriptions, providers, and source names using case-insensitive terms or glob patterns; any query may match.--model --account— list models across all Claude subscriptions; addACCOUNTto select one account by ID, email, or label.--model --key— list models across all API keys; addKEYto select one key by ID or label.--provider PROVIDER— with--model, keepanthropic,anthropic-api,google, oropenrouter; repeat to include several.--tools— with--model, keep only models advertising tool support.--offline— with--model, use saved catalogs without network refresh.--route— list only the currently selected/modelfavorites.--fallback [ROUTE]— show ranked fallbacks and effective attempt order for every selected model or one exact route; supports--jsonand makes no network requests.--classifier— show native Sonnet/classifier account order and last recorded routing status; combine only with--json.--config— show the default model, router port, check-confirmation mode, and routes.--check-confirmation ask|never— with--config, require or disable confirmation for billable route checks.--json— emit the selected view as JSON instead of a table.
Model JSON includes an exact route value that can be passed directly to
cam select; it also retains the upstream id, provider, credential, and model
metadata.
cam account
cam account use ACCOUNT switches the native/default full login used by Claude's
/usage, not the selected routed chat model. Close Claude sessions using that
native profile first, then reopen Claude after switching. CAM refuses to replace
credentials underneath a running native session. Saved model routes and classifier
chains remain unchanged; the outgoing native login becomes a managed account.
A private recovery snapshot is kept in CAM's state directory. This command
currently supports Linux file-backed OAuth logins, not setup tokens or macOS Keychain.
cam account add [--current | --token | --token-stdin] [--name NAME]
cam account remove NAME
cam account use NAME
cam account add— open Claude's hosted OAuth flow, or renew the matching saved account.--current— register the native login currently used by Claude without copying its refresh token.--token— securely prompt for a long-lived value generated byclaude setup-token.--token-stdin— read a setup token from standard input for a pipe or agent workflow.--name NAME— assign an optional nickname; hosted and native logins otherwise use their email.cam account remove NAME— remove an account by ID or nickname; selected accounts must first be removed withcam select.
The three add-mode flags are mutually exclusive. Setup tokens are intentionally not accepted as command-line values.
cam key
Hugging Face Inference Providers are supported with --provider huggingface:
cam key add hf --provider huggingface
cam index --key hf
cam list --model --key hf --offline
cam check --key hf
The token is stored privately (mode 0600) in
~/.config/claude-auth-manager/keys/huggingface/hf (or under XDG_CONFIG_HOME).
Other sessions can discover its nickname with cam list --key; agents should use
registry.read_key("hf", provider="huggingface") rather than printing or copying it.
Tokens need Hugging Face's Make calls to Inference Providers permission.
This integration currently offers only live, provider-pinned routes advertised
as free or with zero input/output prices. It rechecks the catalog before inference
and refuses unknown/paid routes. Free monthly credits are not treated as free
models. Availability, provider limits, and prices can change; cam select refreshes
the HF catalog. No payment settings are changed. Chat, tool calls, streaming, and
managed fallback routing use the existing CAM interface.
cam key add NAME --provider PROVIDER
[--label LABEL]
[--key KEY | --key-path PATH | --key-stdin]
[--no-validate]
cam key remove NAME
NAME— required unique key nickname used in credential-scoped model routes.--provider,-p— required provider:openrouter,google, oranthropic-api.--label LABEL— set a display label distinct from the route nickname.- No secret-input flag — read the key from a masked interactive prompt.
--key KEY— take the key inline; this can expose it in shell history and process listings.--key-path PATH— read the key from a file, the preferred form for agents and secret mounts.--key-stdin— read the key from standard input.--no-validate— store without validation or model indexing; usecam index --key NAMElater.cam key remove NAME— remove a named key; selected keys must first be removed withcam select.
The three secret-input flags are mutually exclusive. Without --no-validate, CAM
validates the credential and immediately indexes the models available through it.
cam index
cam index [--key NAME] [--json]
- No
--key— refresh every saved provider-key catalog and include subscription routes. --key NAME— refresh only the catalog belonging to that named provider key.--json— emit indexed model metadata as JSON instead of a table.
cam search
cam search QUERY... [--key NAME] [--tools] [--offline] [--json]
QUERY...— search case-insensitive terms or glob patterns across model IDs, names, providers, and credential labels; any query may match.--key NAME— search only models belonging to one named provider key.--tools— keep only models that advertise tool support.--offline— search saved catalogs without refreshing them over the network.--json— emit matching model metadata as JSON instead of a table.
Without --offline, cam search refreshes the applicable catalogs before searching.
cam select
cam select [ROUTE...] [--account ACCOUNT]... [--port PORT]
[--fallback TARGET [TARGET ...]] [--clear-fallback FROM]...
- No
ROUTE— open the interactive multi-select picker. ROUTE...— run non-interactively and select exactcam/...routes,provider/credential/modelspecs, or unambiguous model IDs.--account ACCOUNT— include only this Claude subscription in the edit and initially filter to it when singular; API keys remain in the Source menu, and other subscription favorites are preserved; repeatable.--port PORT— save and use a local router port from 1–65535; otherwise reuse the configured port or9427.ROUTE --fallback TARGET [TARGET ...]— replace one route's ordered fallbacks without changing favorites, opening the picker, or refreshing catalogs; destinations must be selected favorites.--classifier ACCOUNT [ACCOUNT ...]— set a separate ordered list of saved Claude subscriptions for native Sonnet/classifier requests; no model-selection flags can be combined with it.--clear-classifier— disable the native Sonnet account override and restore original session credentials.cam list --fallback [ROUTE] [--json]— show direct rankings and the effective attempt order for all selected routes or one route, without network requests.--clear-fallback FROM— remove a selected route's fallback link; repeatable; applies before--fallbackedits.
Interactive picker keys:
- Typing — filter model IDs, names, and descriptions within the active source.
Tab,Shift-Tab— open the searchable Source dropdown containing All, subscriptions, and API keys.- In the Source dropdown, type to filter account labels, emails, key nicknames, or providers; use
↑/↓andEnterto apply, orEscto return. ↑,↓ork,j— move through results; moving above the first result returns to search.Enter,Space— toggle the highlighted model;Enterfrom search enters result browsing.Ctrl-F— open the highlighted selected model's fallback editor: type to search, Enter toggle, Tab pool/ranking, Ctrl-U/D move up/down, Ctrl-S apply, Esc cancel; save the main picker to commit.Esc— return to search;/clears the search and returns to it from result browsing.sorS— save while browsing; in search, useCtrl-SorShift-Sbecause lowercasesis searchable text.qorCtrl-C— cancel without changing favorites.
The dependency-free fallback picker uses result numbers to toggle, f to search
accounts and keys, b NUMBER to edit that selected model's fallback, / to search
models again, s to save, and q to cancel.
cam check
cam check [ROUTE] [-y | --yes] [--json]
cam check --all [--json]
cam check --account [ACCOUNT] [--json]
cam check --key [KEY] [--json]
- No
ROUTE— perform a non-billable local check of configuration, credentials, and router health. ROUTE— send a real, potentially billable request and verify a completeGlobtool round-trip.--all— check every saved account and key, including those with no selected models, using non-billable provider endpoints.--account [ACCOUNT]— check all subscriptions, or one exact account ID/display label.--key [KEY]— check all API keys, or one exact key ID/display label.-y,--yes— send the live route probe without its confirmation prompt.--json— emit health or live-probe details as JSON.
Use cam list --config --check-confirmation ask|never to change the default
confirmation behavior for future live checks.
The credential checks do not send prompts or switch accounts/routes. Claude subscriptions show available 5-hour/7-day usage windows (and reset timestamps in JSON); expired OAuth tokens may refresh through Claude Code. OpenRouter shows the key's remaining spending budget, not the underlying account's credit balance. Google and Anthropic API keys are checked against their model-list endpoints; their remaining quota is reported as unknown. A valid metadata response does not guarantee that an inference request, model, or tool is available.
The Claude usage endpoint is the same endpoint used by Claude Code, but is not a stable public API and may deny setup tokens with insufficient scope. Failures are reported separately per credential, without raw provider messages or tokens. Exit status is 1 if any credential check fails or reports a reached limit, and 0 otherwise (including an empty list). These checks don't change fallback cooldowns.
Service and lifecycle
cam serve [--host HOST] [--port PORT]
cam reset
cam uninstall
cam update
cam serve— run the credential router in the foreground instead of through CAM's user service.--host HOST— bindcam serveto127.0.0.1,localhost, or::1; non-loopback hosts are rejected.--port PORT— makecam servelisten on a port from 1–65535; the default is9427.cam reset— stop the router, restore pre-CAM Claude settings, and delete CAM accounts, keys, catalogs, and state while preserving native Claude credentials.cam uninstall— runcam reset, then remove CAM when the current uv, pipx, or fallback installation can be identified safely.cam update— update CAM in place using the package manager that owns the current installation, then restart configured routing.
Security and behavior
- The router binds only to
127.0.0.1(default port9427) and requires a random local header token. - Provider credentials, managed OAuth profiles, the registry, and backups are stored with owner-only permissions under the XDG config/state directories.
- Registering the current Claude account records a reference to its native credential file; it does not copy its refresh token.
- Every managed model is checked against the selected route allowlist. Incoming
AuthorizationandX-Api-Keyvalues are stripped before the exact route's credential is injected. - Provider keys never appear in Claude settings, model labels, generated agents, or
diagnostics. They appear in command-line arguments only when you explicitly use
--key KEY; the masked prompt,--key-path, and--key-stdinavoid that exposure. cam resetstops the service, restores the pre-manager Claude settings, and removes manager-owned accounts, keys, catalogs, and state. A referenced native Claude credential is never deleted.
Claude Code connectors and account-scoped UI features still belong to its native login. Changing the inference route does not impersonate a second account for those features.
Development and testing
uv run --with pytest pytest -q
uv run --with ruff ruff check .
The local integration suite uses fake upstreams to verify credential isolation, streaming, tool translation, duplicate models across multiple keys, and concurrent routing. The optional Docker check uses real Claude, OpenRouter, and Gemini credentials from read-only secret mounts:
scripts/live-docker-check.sh \
/path/to/openrouter-key \
/path/to/gemini-key \
~/.claude
The live test copies the native Claude OAuth file into a temporary container home and removes that home when it exits.
Fallback tests use a separate fault-injecting HTTP upstream, never a hidden
production debug endpoint. tests/test_fallback.py exercises five synthetic
accounts/keys, credits and quota exhaustion, outages, recovery, streaming errors,
tool indexes, concurrent requests, persistent cooldowns, and cyclic/removed links.
scripts/test-fallback-tui.py tests the real Claude TUI in Docker with only
synthetic credentials. docker/Dockerfile.fallback extends the existing UI test
image with pytest, pexpect, and pyte; mount this checkout at /src and the Claude
binary at /usr/local/bin/claude, then run the script with network disabled.
Pass --late to test Claude's automatic retry after a partial streamed response.
scripts/test-ranked-picker.py checks actual curses search, selection, reordering,
and saving hotkeys in a PTY using synthetic models; run in the same test image.
uv run python scripts/test-fallback-live.py is billable: it uses each selected
credential as a real destination for a Claude Code Glob tool round-trip, with
synthetic exhausted predecessors in a separate loopback router. It prints only
redacted test results and leaves production routing choices unchanged. An expired
credential is reported as blocked rather than counted as a successful live test.
uv run python scripts/test-install-lifecycle.py checks the published curl
installer, direct PyPI installation, checksum-verified GitHub fallback, update,
and uninstall in disposable homes and tool stores. It uses no real Claude login
and does not modify the caller's installed CAM or settings.
Publishing a release
Update the version in pyproject.toml, __init__.py, uv.lock, and install.sh;
run the tests, then bash scripts/build-release.sh. Copy the wheel's SHA-256 into
install.sh and rebuild so the source archive includes the correct pin. Commit
and tag the release, upload the wheel, source archive, and SHA256SUMS to GitHub,
and publish the same package files with
uv run --with twine twine upload dist/*.whl dist/*.tar.gz.
Supply publishing credentials through your local PyPI configuration or a secure
credential store, never repository files. Re-run the public lifecycle smoke test
after publication. Published package versions must not be replaced.
License
MIT
Metadata
Release files for claude-auth-manager 0.0.6
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| claude_auth_manager-0.0.6.tar.gz | 164.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| claude_auth_manager-0.0.6-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 270.2 kB
Release files / claude_auth_manager-0.0.6.tar.gz
| Download URL | claude_auth_manager-0.0.6.tar.gz |
|---|---|
| Size | 164.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ab88ff85ef9f5b0135fd8157a4ad5a9e20000b30a2f4a1160dafa085c6e183a9
|
|
BLAKE2b-256 checksum How to use checksums |
764dcfa4b471e4038e47f2d9c34909705daee5d07d00578f5042f162a5ed82ef
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.11
|
Release files / claude_auth_manager-0.0.6-py3-none-any.whl
| Download URL | claude_auth_manager-0.0.6-py3-none-any.whl |
|---|---|
| Size | 105.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
fcbd32a20b7f9af9b6cc8011034bacdeab3d5c1c30e7d846d28fa1c3d3351111
|
|
BLAKE2b-256 checksum How to use checksums |
47677581fa60b4b62c07c743de86c6f8d58d3ade9278e6b9fcd06cd9bf935e33
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.11
|