Overview #
mcc runs several Claude Code accounts side by side. Each account gets its own login, its own command, and the same setup as your main one.
Claude Code reads its configuration from the directory in CLAUDE_CONFIG_DIR, which defaults to ~/.claude. mcc gives each extra account its own directory under ~/.mcc/profiles/ and a command that sets the variable before starting claude. It then keeps those profiles in sync with your default setup.
mcc supports macOS and Linux with zsh, bash or fish.
Install #
You need Claude Code.
Homebrew (macOS and Linux)
$ brew install luongnv89/tap/mccHomebrew builds mcc from source with its own Rust, so you don't need Rust installed. It also installs bash, zsh and fish completions. Update with brew upgrade mcc.
To build from source yourself you need Rust (cargo, Rust 1.88 or newer). If you don't have Rust, install it from rustup.rs.
One-liner
$ curl -fsSL https://raw.githubusercontent.com/luongnv89/mcc/main/install.sh | shFrom a clone
$ git clone https://github.com/luongnv89/mcc && cd mcc && ./install.shDirectly with Cargo
$ cargo install --git https://github.com/luongnv89/mcc --lockedThe one-liner downloads the prebuilt binary for your platform (macOS or Linux, x86_64 or arm64) from the latest GitHub release, checks its SHA-256 checksum, and installs it into ~/.local/bin (override with MCC_INSTALL_DIR); you don't need Rust. If ~/.local/bin is not on your PATH (it isn't by default on macOS), the script tells you; add it with export PATH="$HOME/.local/bin:$PATH" in your shell profile. A checksum mismatch stops the install. MCC_VERSION=v0.5.0 picks a release. When a release has no binary for your platform (releases up to v0.3.0 have none), or with MCC_FROM_SOURCE=1, or when run from a clone, the script builds with cargo and installs into ~/.cargo/bin (override with CARGO_INSTALL_ROOT). Check it worked:
$ mcc --versionQuick start #
$ mcc init # detect your environment (also runs automatically the first time) $ mcc statusline install # opt-in: lets mcc show each account's usage $ mcc add work --clone # new profile with your default setup, then log in $ work # start Claude Code as the "work" account $ mcc list # see all profiles $ mcc usage # how much of each account's limits is used $ mcc sync work # later: pull the default's new skills and settings, keeping your edits $ mcc rename work job # rename the profile: its command becomes `job` $ mcc delete job # remove it completely
After mcc add finishes, the new command works in any shell straight away, because the launcher is written to ~/.local/bin. The shell alias takes effect in new terminals.
Concepts #
Default profile
Your existing Claude Code setup: ~/.claude plus ~/.claude.json, started with claude. mcc never writes into it during sync. If ~/.claude doesn't exist yet, mcc add creates it as the default profile first.
mcc profiles
Each additional account. A profile is a directory at ~/.mcc/profiles/<alias>/ used as CLAUDE_CONFIG_DIR, a launcher at ~/.local/bin/<alias>, a managed alias block in your shell rc file, and an entry in ~/.mcc/config.toml.
Clone or fresh
When you add a profile you choose how it starts:
- Clone (
--clone) copies the default profile's setup: settings,CLAUDE.md, skills, agents, commands, hooks and MCP servers, and shares its plugins instead of copying them (--copy-pluginscopies them). It never copies credentials. See Clone & sync rules. - Fresh (
--fresh) starts with an empty profile.
Sync
A one-way copy from the default profile into a profile. Most tools assume the default config path, so the default stays the source of truth and profiles follow it.
Commands #
| Command | What it does | Key options |
|---|---|---|
mcc | With no command, once mcc is set up: the profile that applies in this directory and why, every profile's account, usage and drift, and warnings; read-only (before setup, the help) | |
mcc init | Detect OS, terminal, shell, rc file and the claude binary | --force, --shell |
mcc add [ALIAS] | Create the default profile, or a new profile with its own command | --clone, --fresh, --link ITEMS, --copy-plugins, --no-login, --email, --sso, --label, --color, -y |
mcc list (ls) | Show every profile with metrics and usage | --json, --json-v2, -l, --no-usage |
mcc usage [PROFILE] | Show 5-hour and weekly usage in a table; --all looks every account up live for one run, with a risk notice | --all, --json, --json-v2, --show-email, --hide-email |
mcc sync [ALIAS] | Copy the default's setup into a profile | --all, --dry-run, --prune, --force, --only, -y |
mcc diff ALIAS | Show how a profile differs from the default's setup | --only |
mcc rename ALIAS NEW (mv) | Rename a profile and its command | |
mcc share ALIAS | Share the profile's sessions with the other sharing profiles of its group (off by default) | --off, --group NAME, --allow-cross-org |
mcc link ALIAS [ITEMS] | Link read-mostly items to the default's copy instead of copying them; edits write through to the default (off by default) | --off |
mcc project set PROFILE | Make PROFILE the one mcc run starts in this project; also unset and list | --path, --allow, list --json |
mcc run [-- CLAUDE_ARGS] | Start Claude Code with the current project's profile; at its limit, ask whether to wait (the default) or start it anyway | --profile, --dry-run |
mcc env [PROFILE] | Print the shell line that points CLAUDE_CONFIG_DIR at the project's profile (or PROFILE), for eval or direnv | --shell |
mcc exec PROFILE -- CMD… | Run a command with a profile's CLAUDE_CONFIG_DIR and exit with its status; --all runs it once per profile | --all |
mcc config get|set|edit|path | Read or change ~/.mcc/config.toml; invalid values and edits leave the file unchanged | get KEY, set KEY VALUE, edit, path |
mcc statusline install | Opt-in: show the active profile in Claude Code's status line and cache each profile's rate limits; also uninstall | --prefix, -y |
mcc refresh-launchers [ALIAS...] | Rewrite launchers and shell aliases from the current templates | |
mcc doctor [PROFILE] | Check every profile's setup and print a fix for each problem; read-only, exits 1 when it finds one | --json, --json-v2 |
mcc delete ALIAS (rm) | Log out and remove a profile | -y, --keep-auth |
mcc completions SHELL | Print a shell completion script | bash, zsh, fish, elvish, powershell |
mcc help [COMMAND] | Usage and examples for any command |
mcc (no command) #
mcc [-q] [--no-color]
Once mcc is set up ([env] in ~/.mcc/config.toml, written by mcc init or the first-run setup), bare mcc shows one screen: Here: the profile mcc run starts in this directory and why (a project default, or none), then mcc list's table of every profile with its account (label, else organization), cached 5-hour and weekly usage, last use and sync state. Warnings follow on stderr for drift against the default, out-of-date launchers, missing directories and a project default naming no profile, with a pointer to mcc doctor when there is any. It is read-only and fast: no lock, no first-run setup, no log line, nothing written; usage comes from the mcc statusline cache only, never looked up live (even with [usage] live = true), and counts and sizes are left to mcc list --long. Emails stay hidden unless [privacy] show_email is set. Piped, it prints the same text without colors. Before setup, bare mcc prints the help and exits 2, as it always did; mcc help and mcc --help print the help either way.
$ mcc
Here: `work` (Acme) — the default for ~/code/app
NAME ACCOUNT 5H WEEK LAST USED SYNC
default ★ personal ██░░░░░░░░ 18% (3h) █░░░░░░░░░ 9% (5d) 2h ago —
work Acme ████░░░░░░ 42% (2h) ██░░░░░░░░ 18% (4d) 3m ago 3 behindmcc init #
mcc init [--force] [--shell zsh|bash|fish]
Detects your OS, architecture, terminal, shell, rc file, the claude binary, and whether ~/.local/bin is on your PATH (and offers to add it). The result is saved in ~/.mcc/config.toml. It runs automatically the first time you use mcc.
| Option | Effect |
|---|---|
--force | Re-run detection even if mcc is already initialized |
--shell <SHELL> | Shell whose rc file mcc manages: zsh, bash or fish (default: detected from $SHELL) |
$ mcc init $ mcc init --force --shell bash
mcc add #
mcc add [ALIAS] [--clone [--link ITEMS] [--copy-plugins] | --fresh] [--no-login | [--email ADDRESS] [--sso]] [--label LABEL] [--color COLOR] [-y]
If ~/.claude doesn't exist, add creates your default profile. Otherwise it creates a new profile in eight numbered steps:
- Validate the alias (see Alias rules)
- Create
~/.mcc/profiles/<alias> - Copy the setup from the default profile (clone only)
- Install the launcher
~/.local/bin/<alias> - Add the shell alias to your rc file (backed up first)
- Register the profile in
~/.mcc/config.toml - Log in with
claude auth login; finish the sign-in in your browser - Verify the login and show the account
If a step fails, the changes made so far are rolled back. Without an alias or a --clone/--fresh flag, add asks interactively.
After the login, add records the account under [profiles.<alias>.account] in ~/.mcc/config.toml (email, account UUID, organization name and UUID, as Claude Code reports them) and warns when another profile, the default included, is already logged in to the same account, since profiles on one account share its usage limits. It then asks for an optional label, such as personal or the account's organization, kept as label.
A profile signed in with an Anthropic Console account (API usage billing) gets a warning, without stopping: Claude Code stores a Console sign-in outside the profile's directory, so profiles don't keep it separate. To use a Claude subscription in it instead, run ALIAS auth login --claudeai.
| Option | Effect |
|---|---|
ALIAS | Command name for the new profile (prompted if omitted) |
--clone | Copy the default profile's setup and share its plugins (never credentials) |
--fresh | Start with an empty profile |
--link ITEMS | With --clone: link these items (skills, agents, commands, output-styles, claude-md) to the default's instead of copying them; see mcc link |
--copy-plugins | With --clone: give the profile its own copy of the default's plugins instead of sharing them |
--no-login | Skip claude auth login; log in later by running the alias |
--email ADDRESS | Passed to claude auth login --email: pre-fills the address on the sign-in page. mcc does not print it, and mcc.log records it as <redacted>; once signed in, the account's email (usually the same) is shown and logged like any profile's |
--sso | Passed to claude auth login --sso: forces the SSO sign-in flow |
--label LABEL | Label the account (e.g. personal, or the work organization) instead of being asked; 1–64 characters |
--color COLOR | Show the profile's name in this color in mcc list, mcc run and the status line: black, red, green, yellow, blue, magenta, cyan or white |
-y, --yes | Accept defaults without prompting |
$ mcc add # interactive: asks for the alias and clone/fresh $ mcc add work --clone # copy the default's setup, then log in $ mcc add lab --fresh --no-login # empty profile; log in later by running `lab`
mcc list #
mcc list [--json | --json-v2 | -l/--long] [--no-usage] [--show-email | --hide-email] alias: mcc ls
One row per profile, the default included, in a table that fits 120 columns: name, account (the profile's label, else its organization, after the email only when emails are shown; a long cell is cut with …), 5-hour and weekly usage (with a bar), last used, and a SYNC column saying how the profile compares with the default (✓, 3 behind, 2 local edits, 1 conflict; sync in --json). When projects have a default profile (mcc project set), a second table lists each project with its profile and account, marking the one that applies in the current directory with ← here. --long cards show them in a Default for row, and --json has a project_defaults array per profile. --long cards have everything else: the command, the organization and its ID, the label, skills, agents, commands, plugins (enabled/installed), MCP servers, hooks, size, last sync and how old cached usage is; --json has organization, organization_uuid and label too.
Account emails are hidden by default, as in mcc usage: account is null in --json and --json-v2 (so are an organization and label that contain an email, as personal plans' organization names do; no field is left out). --show-email shows them for one run, and show_email = true under [privacy] every time.
| Option | Effect |
|---|---|
--json | Print JSON to stdout instead of a table: a bare array (schema 1) |
--json-v2 | Print versioned JSON: {"schema": 2, "profiles": [...]}, the same objects as --json; fields are only ever added within a schema |
-l, --long | Show a detailed card per profile |
--no-usage | Skip fetching usage: no network, no keychain (same as MCC_NO_USAGE=1) |
--show-email | Show account emails for this run |
--hide-email | Hide account emails for this run, even with show_email = true in the config |
$ mcc list NAME ACCOUNT 5H WEEK LAST USED SYNC default ★ Acme ████░░░░░░ 42% (2h) ██░░░░░░░░ 18% (3d) just now — work personal █████████░ 85%! (35m) ██████████ 96%!! (3d) 2h ago ✓ lab — — — 1d ago 3 behind
$ mcc list --long $ mcc list --no-usage # offline: skip the usage lookup $ mcc list --json --show-email | jq '.[] | {name, account, skills, plugins_installed}' $ mcc list --json | jq '.[] | {name, five_hour: .usage.five_hour.percent, weekly: .usage.weekly.percent}'
mcc usage #
mcc usage [PROFILE | --all] [--json | --json-v2] [--show-email | --hide-email]
Shows only usage, as a compact table with one row per profile: for each window a bar with the percent used, the time until it resets, and the reset time in your local time zone. Pass a profile name to see just one; use default or claude for ~/.claude. An unknown name is a usage error (exit 2).
Account emails are hidden by default, so the output is safe to share on screen. --show-email adds an ACCOUNT column; to show it every time, set show_email = true under [privacy] in ~/.mcc/config.toml, which applies to mcc list too (see Configuration).
| Option | Effect |
|---|---|
PROFILE | Only this profile (default or claude for the default) |
--all | Look every account's usage up live for this run, the default included, with each profile's login instead of the statusline cache, save what it finds to that cache, and print a risk notice on stderr each time (see Usage limits). Can't be combined with PROFILE; MCC_NO_USAGE=1 still skips usage |
--json | Print one JSON object per profile with name, command, is_default, account and usage (account is null while emails are hidden) |
--json-v2 | Print versioned JSON: {"schema": 2, "profiles": [...]}, the same objects as --json |
--show-email | Show account emails for this run |
--hide-email | Hide account emails for this run, even with show_email = true in the config |
$ mcc usage # every profile, the default included $ mcc usage work # only the `work` profile $ mcc usage --all # every account looked up live (prints a risk notice) $ mcc usage --show-email # with each profile's account email $ mcc usage --json | jq '.[] | {name, weekly: .usage.weekly.percent}'
See Usage limits for how to read the output and where the data comes from.
mcc sync #
mcc sync (ALIAS | --all) [--dry-run] [--prune] [--force] [--only ITEMS] [-y]
Copies the default profile's setup into a profile. It plans the changes, copies every file or folder it is about to overwrite or remove (such as CLAUDE.md, skills, agents, settings.json and .claude.json) to <profile>/.mcc-backup/<timestamp>/, then applies them with progress. It is three-way: changes made only in the default are copied, edits made only in the profile are kept (local edits), and paths changed in both are conflicts, kept unless --force; see Three-way sync.
| Option | Effect |
|---|---|
ALIAS | Profile to update (required unless --all) |
--all | Sync every mcc profile |
--dry-run | Show what would change without writing anything |
--prune | Also remove items that exist in the profile but not in the default (asks for confirmation) |
--force | Also overwrite conflicts: paths changed in the default and edited in the profile (backed up first) |
--only ITEMS | Comma-separated list of items to sync: settings, claude-md, keybindings, statusline, agents, skills, commands, hooks, output-styles, plugins, mcp |
-y, --yes | Do not ask for confirmation |
$ mcc sync work --dry-run # preview what would change $ mcc sync work --only skills,agents # only some items $ mcc sync --all --prune --yes # make every profile mirror the default exactly $ mcc sync work --force # also overwrite conflicts
mcc diff #
mcc diff ALIAS [--only ITEMS]
Shows how a profile differs from the default's setup, as sync sees it, and writes nothing. Each differing path or MCP server is listed as new in default, changed in default, local edit, conflict or only in profile, with a line diff for text files (--- the default, as the profile receives it; +++ the profile). --only takes the same items as sync.
$ mcc diff work $ mcc diff work --only skills,settings
mcc rename #
mcc rename ALIAS NEW alias: mcc mv
Gives a profile a new name, and with it a new command. The new name is checked the same way add checks an alias: it must not be an existing profile, command, alias, function or shell builtin; a taken name is a usage error (exit 2) and nothing changes. Then mcc:
- Installs the launcher
~/.local/bin/<new> - Adds the new alias block to your rc file
- Renames the entry in
~/.mcc/config.toml - Removes the old launcher and alias block
If a step before the last fails, the new launcher and alias are removed again. The profile's directory stays where it is (~/.mcc/profiles/<old>): Claude Code ties a profile's macOS Keychain login to its directory path, and cloned settings refer to it, so moving it would log the profile out. The default profile can't be renamed; its command is always claude.
$ mcc rename work job # start it with `job` from now on
mcc share #
mcc share ALIAS [--group NAME] [--allow-cross-org] [--off] or: ALIAS --mcc-share [claude args…]
Turns session sharing on for a profile: its projects/ directory, where Claude Code keeps the sessions --resume lists, becomes a link to the store of its group (~/.mcc/shared/groups/NAME/projects with --group NAME, else ~/.mcc/shared/projects, the default group), shared by the group's sharing profiles. Joining a group with profiles of another organization is refused unless --allow-cross-org is passed. Starting the profile with --mcc-share as the first argument does the same before Claude Code starts; the flag itself is not passed on, and if sharing can't be turned on, Claude Code is not started. --off gives the profile its own copy of the shared sessions again. The first time sharing is turned on for a profile, mcc prints the terms-of-service note on stderr; later runs print a one-line reminder. See Session sharing.
$ mcc share work # share work's sessions $ work --mcc-share --resume # the same, then pick a session from any sharing profile $ mcc share work --off # stop sharing
mcc link #
mcc link ALIAS [ITEMS] [--off] or: mcc add ALIAS --clone --link ITEMS
Link mode, off by default and chosen per item: the profile's skills/, agents/, commands/, output-styles/ or CLAUDE.md (items skills, agents, commands, output-styles, claude-md) becomes a symlink to the default profile's, so nothing is duplicated and nothing drifts. sync and diff leave linked items alone: never compared, copied, pruned or recorded. Turning it on backs up the profile's own copy to .mcc-backup/ first. Write-through: editing a linked item in the profile, by hand or by Claude Code, changes the default's real files, and every other profile that links it; mcc prints this warning whenever link mode is turned on. --off removes only the symlink, never the default's files, and copies the default's item in its place. A failed step undoes the whole run. settings can't be linked (it is merged with the profile's overlay). A hand-written link entry that can't be linked, such as settings, is ignored with a warning that names the profile and the entry, and sync, diff and list keep treating that item as a copy; remove it with mcc config edit. Without ITEMS it shows each item's mode. The setting is kept as link = [...] under [profiles.<alias>].
plugins is shared, not symlinked: the profile's launcher, mcc run, mcc exec and mcc env set CLAUDE_CODE_PLUGIN_CACHE_DIR to ~/.claude/plugins, which replaces Claude Code's whole plugins root, so installed plugins, marketplaces, the plugin cache and plugin data are shared while enabledPlugins stays per profile in settings.json. Write-through: installing, updating or uninstalling a plugin in a sharing profile does it for the default and every sharing profile. A profile started without the variable (e.g. CLAUDE_CONFIG_DIR=… claude) has no plugins. mcc add --clone shares plugins unless --copy-plugins is given; for an existing profile, mcc link ALIAS plugins moves its own plugins/ to .mcc-backup/<timestamp>/ (remove it to free the space), and --off copies the default's plugins back in. Version caveat: this was verified on Claude Code 2.1.286; other versions may treat CLAUDE_CODE_PLUGIN_CACHE_DIR differently. If a sharing profile shows no plugins, mcc link ALIAS plugins --off gives it its own copy again (or clone with --copy-plugins).
$ mcc link work skills,agents # link work's skills/ and agents/ to ~/.claude's $ mcc link work skills --off # give work its own copy of skills/ again $ mcc add lab --clone --link skills # clone, linking skills/ instead of copying it $ mcc link work plugins # share ~/.claude/plugins instead of a copy
mcc project #
mcc project set PROFILE [--path DIR] [--allow PROFILE…] | unset [--path DIR] | list [--json | --json-v2]
set makes PROFILE (an mcc profile, or default / claude for ~/.claude) the one mcc run starts in a project: by default the top of the git repository you are in, else the current directory. --allow (repeatable or comma-separated) names the other profiles mcc run may offer when PROFILE is at its limit; setting the project again without it clears the list. unset removes the project default that applies here, or the one at --path. list shows every project with its profile and allowed profiles, marking the one that applies here; --json gives each project an allow array. See Per-project profiles. list --json prints a bare array of path, profile and allow objects, and list --json-v2 wraps it as {"schema": 2, "projects": [...]}.
$ mcc project set work # `mcc run` starts `work` in this repository $ mcc project set work --allow lab # …and may offer `lab` when `work` is at its limit $ mcc project set default --path ~/site # …and the default profile in ~/site $ mcc project list
mcc run #
mcc run [--profile NAME] [--dry-run] [-- CLAUDE_ARGS…]
Starts Claude Code with the current project's default profile, or with the default profile outside every project. mcc never switches accounts on its own: when that profile is at its 5-hour or weekly limit, mcc run asks whether to wait (the default, which starts nothing) or start it anyway, and offers other profiles only when the project allows them, without their usage (without a terminal it stops with exit code 2). --profile NAME starts NAME without checking usage. Starting a profile other than the project's prints a terms-of-service note on stderr. Arguments after -- are passed to claude. --dry-run prints the profile it would start on stdout, and why on stderr, without starting it.
$ mcc run $ mcc run -- --resume $ mcc run --profile lab # this time only; the project's default stays $ mcc run --dry-run
mcc env #
mcc env [PROFILE] [--shell zsh|bash|fish]
Prints the shell line that points CLAUDE_CONFIG_DIR at the profile mcc run would start here (the project's default, else the default profile, which prints unset CLAUDE_CONFIG_DIR), or at PROFILE, so plain claude, IDE extensions and scripts use it too. For a profile that shares the default's plugins it also sets CLAUDE_CODE_PLUGIN_CACHE_DIR. The shell is --shell, else bash inside a direnv .envrc, else your $SHELL; fish gets set -gx. Paths are single-quoted, so spaces and quotes are safe. It never checks usage and writes nothing but its log entry in ~/.mcc/logs/mcc.log; naming a profile other than the project's prints the same note as mcc run --profile. With direnv, put eval "$(mcc env)" in the project's .envrc and run direnv allow: the project's profile then applies whenever you cd into it.
$ eval "$(mcc env)" # this shell now uses the project's profile $ mcc env work # export CLAUDE_CONFIG_DIR='/Users/me/.mcc/profiles/work' $ mcc env default # unset CLAUDE_CONFIG_DIR (the default profile, ~/.claude) $ mcc env | source # the same in fish
mcc exec #
mcc exec (PROFILE | --all) -- CMD [ARGS…]
Runs any command with a profile's CLAUDE_CONFIG_DIR (unset for the default profile) and exits with its status, which makes Claude Code's own plugin and MCP commands work per profile. --all runs it once per profile, the default first, one after the other: each profile's output comes under its name, followed by its exit status, and mcc exits 0 only if the command succeeded everywhere (else with the first failing status). A command that can't be found counts as exit 127 (126 when it can't be run), and Ctrl+C stops at the current profile. mcc holds no lock while the command runs, so the command may run mcc itself.
$ mcc exec work -- claude mcp list $ mcc exec default -- claude plugin list $ mcc exec --all -- claude plugin marketplace update
mcc statusline #
mcc statusline install [--prefix] [--yes] · mcc statusline uninstall
Opt-in. Claude Code passes the session's 5-hour and weekly rate limits (rate_limits.five_hour and rate_limits.seven_day, with used_percentage and resets_at) to its status-line command on stdin. install and uninstall are the only mcc commands that change an existing default profile (a symlinked settings.json stays a symlink). install backs up ~/.claude/settings.json to ~/.mcc/backups/, records the current statusLine in ~/.mcc/state/default/statusline.json and sets mcc statusline in its place, never twice. --prefix starts the status line with the active profile's name, e.g. [work], or [work · Acme] when the profile has a label, in the profile's color (mcc config set profiles.work.color blue) unless NO_COLOR is set. Profiles get it with their next mcc sync; when [sync] exclude has "settings", install offers to add it to each profile directly (--yes accepts).
On every refresh the shim works out the profile from CLAUDE_CONFIG_DIR (unset means the default profile), saves the rate limits to ~/.mcc/state/<profile>/usage.json, runs your previous statusLine command with the same stdin and prints its output. It never reads a login, never takes mcc's lock and never writes ~/.mcc/config.toml. The data exists only for Pro and Max subscribers, after a session's first response, and an idle profile's file goes stale (see updated_at). A statusLine in a project's own .claude/settings.json overrides the shim there. uninstall restores the previous statusLine wherever the shim is set, with a backup, and leaves one you changed by hand alone.
$ mcc statusline install --prefix $ mcc statusline uninstall
mcc refresh-launchers #
mcc refresh-launchers [ALIAS...]
Rewrites the launcher and shell alias of the given profiles (all of them when none are given) from the current templates, so that <alias> --mcc-share works for profiles created by an older mcc: the alias then runs the launcher instead of calling claude directly. CLAUDE_CONFIG_DIR stays exactly the same, so logins are kept. mcc never rewrites existing launchers on its own. Launchers that are already current are left alone, and launchers mcc didn't write are skipped. If a step fails, the previous launchers and aliases are restored.
$ mcc refresh-launchers $ mcc refresh-launchers work lab
mcc doctor #
mcc doctor [PROFILE] [--json | --json-v2]
Checks every profile, the default included (or only PROFILE; default or claude for ~/.claude), and prints a fix for each problem. It doesn't change your setup: no ~/.mcc/config.toml write (not even the first-run setup), no lock, and no file written except its line in ~/.mcc/logs/mcc.log, and that only when the log folder already exists.
- Setup: mcc is initialized (
mcc init),claudeis found,~/.local/binis onPATH(sourcethe rc file, ormcc init --force). - No rc file sets
CLAUDE_CONFIG_DIRfor every shell (export, a bare assignment, fish'sset -gx; comments, aliases and mcc's own blocks are ignored): such a line makes plainclaudestop starting the default profile. The fix names the line to remove.CLAUDE_CONFIG_DIRset in the current shell is a warning (unset CLAUDE_CONFIG_DIR; fish:set -e CLAUDE_CONFIG_DIR). - Per profile: its directory exists with mode 0700 (
mcc delete,chmod 700); its launcher is there, mcc's, executable, starts its directory, sets the plugins root exactly when it shares plugins, and is current (mcc refresh-launchers ALIAS); its alias block is in its rc file (the block to paste). claude auth status, run through the launcher, reports the profile's directory asconfigDirectory(Claude Code 2.1.268 or later; skipped before) and a login (mcc exec ALIAS -- claude auth login). Token expiry is a warning, checked only with[usage] live = trueandMCC_NO_USAGEunset.- Session sharing:
projects/links to the group's store exactly when sharing is on and the store exists, and no.projects.mcc-share-*or.projects.mcc-unshare-*is left by an interruptedmcc share(mcc share ALIAS,--off). - Drift against the default, as
mcc listshows it (a warning:mcc sync ALIAS,--forcefor conflicts), and, with themcc statuslineshim installed, the shim in each profile's settings unless its overlay sets astatusLine(mcc sync ALIAS --only settings).
Each finding is ok, warn, problem or skipped. mcc exits 1 when there is a problem, after printing them all. --json prints a bare array of {"profile", "check", "status", "message", "fix"} objects; --json-v2 wraps it as {"schema": 2, "checks": [...]}.
$ mcc doctor $ mcc doctor work $ mcc doctor --json | jq '.[] | select(.status == "problem")'
mcc delete #
mcc delete ALIAS [-y] [--keep-auth] alias: mcc rm
Logs the profile out with claude auth logout (clearing its keychain entry), then removes its directory, launcher, shell alias block and registry entry. It asks you to type the name to confirm unless you pass --yes. It refuses to delete the default profile, and only removes launchers that mcc created. Given the old name of a renamed profile, it refuses (exit 2) and names the profile that still uses that directory.
| Option | Effect |
|---|---|
-y, --yes | Skip the confirmation prompt |
--keep-auth | Do not run claude auth logout before deleting |
$ mcc delete lab $ mcc delete lab --yes --keep-auth
mcc completions #
mcc completions bash|zsh|fish|elvish|powershell
Prints a completion script to stdout. It has no first-run side effects. Homebrew installs the bash, zsh and fish scripts for you; otherwise write the one for your shell:
$ mcc completions zsh > ~/.zfunc/_mcc # with fpath+=~/.zfunc in ~/.zshrc $ mcc completions bash > ~/.local/share/bash-completion/completions/mcc $ mcc completions fish > ~/.config/fish/completions/mcc.fish
Global flags #
| Flag | Effect |
|---|---|
-v, --verbose | Show detailed progress (always written to ~/.mcc/logs/mcc.log) |
-q, --quiet | Only print errors and requested data |
--no-color | Disable colored output (mcc also honors NO_COLOR) |
--version | Print the version |
-h, --help | Print help |
Clone & sync rules #
What is copied
Item (--only name) | Paths |
|---|---|
settings | settings.json, settings.local.json |
claude-md | CLAUDE.md |
keybindings | keybindings.json |
statusline | statusline.conf |
agents, skills, commands, hooks, output-styles | those directories |
plugins | plugins/installed_plugins.json, plugins/known_marketplaces.json, plugins/marketplaces/, plugins/cache/; only for a profile with its own plugins: one that shares the default's (a clone, unless --copy-plugins) gets none of these, see mcc link |
mcp | the mcpServers entry from ~/.claude.json, merged; the rest of the profile's state is kept |
Never copied: credentials, account identity (oauthAccount, userID), history, projects and sessions, todos, telemetry, caches and file history. Sessions can be shared instead, opt-in; see Session sharing.
Path rewriting
Each profile uses its own copies. In settings, plugin manifests and MCP server entries, any ~/.claude/…, $HOME/.claude/… or /Users/you/.claude/… path that points at a copied item (for example ~/.claude/hooks/notify.sh) is rewritten to the profile directory.
Paths to things that aren't copied, such as ~/.claude/statusline/run.sh, keep pointing at the default profile, so nothing dangles.
Symlinks
Symlinks stay symlinks. A link into the default profile is re-pointed into the copy. A relative link elsewhere (such as skills/x -> ../../.agents/skills/x) is resolved so it still works from the new location.
One-way sync, backups and pruning
sync only copies default → profile, because most tools assume the default config path. Before writing, it copies every file or folder it is about to overwrite or remove (such as CLAUDE.md, skills, agents, settings.json and .claude.json) to <profile>/.mcc-backup/<timestamp>/, at the same paths, so your own edits can be restored from there. --dry-run changes nothing in the profile and makes no backup. Files that exist only in the profile are kept unless you pass --prune, and pruning asks for confirmation (or needs --yes).
Three-way sync
add --clone and every sync record what they wrote in <profile>/.mcc-sync.json: each path and MCP server with a hash of its content. The next sync compares the default, the profile and that record for every path. Changed only in the default: updated (or added). Edited, or deleted, only in the profile: kept and reported as a local edit. Changed in both: a conflict, kept and reported; --force overwrites it after backing it up. --dry-run shows the same classification and writes nothing, not even the record. A profile without a record (created --fresh or by an older mcc), or with one that can't be read, is compared two-way once, taking every difference from the default, and the record starts with that sync. Because that sync can't tell your edits from the default's changes, it first warns with each path and MCP server it will replace and where they are backed up (<profile>/.mcc-backup/); --dry-run lists the same paths, and the warning shows even with --quiet. A sync that only adds files prints no warning. The record belongs to its profile and is never copied; [sync] extra can't name it.
Per-profile settings overlays
A profile can keep its own model, env, permissions or statusLine with an overlay: [profiles.<alias>.settings] in ~/.mcc/config.toml and/or <profile>/settings.mcc.json (which wins where both set a key). Clone and every sync write the default's settings.json (paths rewritten), then deep-merge the overlay onto it: objects merge key by key, arrays and other values replace the default's whole (an overlay permissions.allow is the profile's whole list), and null (JSON only) removes a key. The merged result is what the sync record holds, so overlay keys are never local edits or conflicts, and editing the overlay is applied by the next sync, with the usual backup. When [sync] exclude has "settings", the profile owns its settings.json and the overlay is not applied. An overlay statusLine replaces the default's, the mcc statusline shim included.
Configuration #
mcc keeps its environment and profile registry in ~/.mcc/config.toml. You can customize what sync and clone copy with a [sync] table, whether mcc list and mcc usage show account emails with a [privacy] table, and how usage is looked up with a [usage] table:
[sync] exclude = ["plugins"] # built-in items to skip extra = ["my-tool/config.yml"] # additional paths (relative to the config dir) to copy [privacy] show_email = true # show account emails in `mcc list` and `mcc usage` (default: false) [usage] # live = true # look usage up live with each profile's login (default: off) [profiles.work] share_sessions = true # default: false; set it with `mcc share work` [profiles.work.settings] # optional: merged onto the default's settings.json model = "sonnet" [projects."/Users/me/code/app"] profile = "work" # `mcc run` starts `work` here; set it with `mcc project set work` allow = ["lab"] # optional: offered when `work` is at its limit (`--allow lab`)
A corrupt config.toml makes mcc exit with code 3 (invalid input) instead of guessing.
You don't have to edit it by hand: mcc config set usage.live true, mcc config set sync.exclude plugins,mcp or mcc config set profiles.work.label "Acme (work)" check the value first and leave the file unchanged when it is invalid, and keep your comments. mcc config get KEY prints a value, mcc config path the file's location, and mcc config edit opens a copy in $VISUAL or $EDITOR, saved only when it is valid mcc config. No lock is held while the editor is open; if another mcc command changes the file meanwhile, nothing is saved and your copy is kept. mcc help config lists the settable keys.
An opt-in launch banner: with [launch] banner = true (mcc config set launch.banner true), starting a profile from its command or with mcc run prints one line on stderr, such as ▶ work · Acme · 5h 42% · week 18%: the profile's name in its color, its label and its cached usage. It is printed only when stderr is a terminal, never on stdout, and reads only the config and the usage cache, never the network or a token. Launchers call it only while it is on: after turning it on, run mcc refresh-launchers so existing launchers show it (and again after turning it off, to take the call out).
Session sharing #
Each profile keeps its sessions to itself unless you turn sharing on. Sharing is a per-profile setting, share_sessions under [profiles.<alias>] in ~/.mcc/config.toml, and it is off by default. Turn it on with mcc share <alias>, or by starting the profile with <alias> --mcc-share. Editing the key by hand does nothing on its own, because mcc share is what links the directory. Once two or more profiles share, claude --resume and /resume in any of them list the sessions of all of them.
The first time sharing is turned on for a profile, mcc prints this note on stderr and records when as share_note_acknowledged_at:
⚠ Session sharing makes conversation history available across your Claude Code accounts. Use it only between accounts you own. Don't use it to get around usage limits, and never let other people use your account or credentials — doing so can violate Anthropic's Consumer Terms (https://www.anthropic.com/legal/consumer-terms) and Usage Policy (https://www.anthropic.com/legal/aup), including the updated Usage Policy that takes effect November 12, 2026.
After that, each mcc share or --mcc-share prints a one-line reminder instead:
⚠ Session sharing is on: use it only between accounts you own, never to get around usage limits or to let other people use your account (Anthropic's Consumer Terms and Usage Policy; full note: mcc share --help).
- Groups: sessions are shared only within a group.
mcc share <alias> --group <name>uses~/.mcc/shared/groups/<name>/projects; without--group, the profile's recorded group (share_group) or else thedefaultgroup,~/.mcc/shared/projects. To change groups, run--offfirst. - Organizations: work transcripts resumed under a personal account fall under consumer terms. mcc compares the recorded accounts of the group's profiles (organization UUID, else name; the organization type tells personal plans, which have an organization of their own, from Team and Enterprise; an unknown type counts as a possible work organization). Another organization, or an account mcc can't identify, is refused unless you pass
--allow-cross-org. Organization ↔ personal is the strictest:--allow-cross-orgmust also be confirmed in a terminal, and--mcc-sharealways refuses it. Profiles that already shared before groups existed are warned, never cut off. - Shared: only the profile's
projects/directory (the session transcripts). It becomes a link to its group's store. Existing sessions are moved into the store without overwriting anything. If a file of the same name with different contents is already there, the store's copy is kept and the profile's copy goes to~/.mcc/backups/shared-projects-<alias>-<time>/. - Never shared: credentials (
.credentials.json, the keychain login), the account (.claude.json),policy-limits.json,remote-settings.json, prompt history, live session state (sessions/),shell-snapshots/,file-history/andtodos/. --offgives the profile a directory of its own again, with a copy of the shared sessions. The group's store stays for its other sharing profiles. mcc never deletes it, so remove it by hand once no profile uses it.mcc deleteof a sharing profile removes only its link.mcc renamekeeps sharing as it is. The default profile can't share.- Caveats:
mcc listmarks sharing profiles(shared), or(shared: NAME)in a named group, and their session counts include every sharing profile's sessions. Claude Code'scleanupPeriodDayscleanup in any sharing profile applies to the shared sessions of all of them.
Upgrading: profiles that already share keep ~/.mcc/shared/projects as the default group's store; nothing is moved. Launchers and aliases created by an older mcc stay exactly as they were. Run mcc refresh-launchers once so that <alias> --mcc-share works. mcc share works without it.
Per-project profiles #
To keep a project on one account, give it a default profile with mcc project set <profile> and start Claude Code there with mcc run. A project is a directory, by default the top of the git repository; it covers everything below it, and the deepest project containing the current directory applies. Outside every project, the default profile (~/.claude) is the default.
mcc run starts the project's default. It never switches to another account on its own. When the project's profile is at its 5-hour or weekly limit (100% used), it shows when the limit resets and asks what to do. Waiting is preselected: it starts nothing and exits. Starting the profile anyway comes next. Other profiles are offered only when the project allows them, by name and without their usage.
$ mcc project set work --allow lab $ mcc run ⚠ `work` (the default for ~/code/app) is at its 5-hour limit, resets in 35m ? Wait, or start a profile? › ❯ Wait — `work` resets in 35m Start `work` anyway Start `lab` instead
Picking a profile other than the project's, in the prompt or with --profile, prints this note on stderr:
⚠ You chose to start an account other than this project's. Use only accounts you own, and don't use several accounts to get around usage limits — doing so can violate Anthropic's Consumer Terms (https://www.anthropic.com/legal/consumer-terms) and Usage Policy (https://www.anthropic.com/legal/aup), including the updated Usage Policy that takes effect November 12, 2026.
- Allowed profiles:
mcc project set work --allow lablets the prompt offerlab(repeat--allow, or separate names with commas). Setting the project again without--allowclears the list. --profile NAMEstarts NAME without checking usage, this time only: the project's default doesn't change.- Without a terminal,
mcc runcan't ask. At the limit it stops with exit code 2 and namesmcc run --profile <profile>to start it anyway. - Unknown usage: only the project profile's usage is ever read. If it isn't known (nothing cached,
MCC_NO_USAGE=1, or, with the live lookup, offline or an expired login), that profile starts. - Sessions: Claude Code keeps sessions per profile, so in another profile
--resumeonly sees that profile's sessions, unless both profiles share sessions. - Why there's no automatic switching: Anthropic's seat rules are worded differently for each plan, and both rule it out. The Team plan: “Users can't route their work through another user's account to use that user's remaining usage.” The Enterprise plan: “Users can't use another user's account to get around their own spend limits or usage limits.” Its Consumer Terms also forbid bypassing its systems or protective measures, and its Usage Policy, updated with effect from November 12, 2026, applies to every account. So which account to use when one is at its limit is always your call.
- In
mcc list: a second table shows each project with its profile and account;--longcards have aDefault forrow, and--jsonaproject_defaultsarray. - Rename and delete:
mcc renameupdates the project defaults and allow lists naming the profile.mcc deleteremoves the project defaults naming it, and takes it off the allow lists.
Usage limits #
mcc list shows 5-hour and weekly usage in its 5H and WEEK columns (--long says how old those numbers are); mcc usage shows it in full.
$ mcc usage PROFILE 5-HOUR RESETS IN WEEKLY RESETS IN UPDATED default ★ ████░░░░░░ 42% 2h 14m (Sat Oct 10 16:00) ██░░░░░░░░ 18% 3d 4h (Wed Oct 14 00:00) 12m ago lab — (no recent usage cached; run /usage in Claude Code) work █████████░ 85%! 35m (Sat Oct 10 14:21) ██████████ 96%!! 3d 4h (Wed Oct 14 00:00) just now
Reading the bars
Each bar is the share of the limit used. ! after the percent marks 80% or more and !! marks 95% or more. In a colour terminal the bar is also green, yellow (80%+) or red (95%+), but the markers carry the same meaning, so nothing depends on colour alone (--no-color, NO_COLOR or piped output).
Narrow terminals
When the output wouldn't fit the terminal, bars shrink. mcc usage first drops the absolute reset time and keeps the time until the reset, then shrinks its bar in the same 10 → 5 → 0 cell steps as the mcc list table. From 80 columns up a compact bar always stays; below 80 columns bars disappear (leaving just the percent, such as 42%) when nothing fits. Set COLUMNS to override the detected width. Piped output gets full-size bars unless COLUMNS is set, and --json never has bars or colour.
Where the data comes from
By default, from the rate limits mcc statusline caches in ~/.mcc/state/<profile>/usage.json while you use Claude Code. No login is read and nothing touches the network. UPDATED (and · 12m ago in mcc run) is how old the cached numbers are (the last mcc usage --all saves to the same cache), and a window whose reset time has passed is obsolete and shown as —. A profile with nothing current cached (an idle profile, a Team or Enterprise seat that reports no rate limits, or no mcc statusline install yet) shows — and a hint to run /usage inside Claude Code.
Live lookup (opt-in). With live = true under [usage] in ~/.mcc/config.toml, mcc instead reads each profile's own Claude Code login (<config dir>/.credentials.json, or on macOS the login Keychain item Claude Code created for that config dir, under $USER or, when it is unset, the system's name for your user) and asks Anthropic's usage endpoint, https://api.anthropic.com/api/oauth/usage, the one behind Claude Code's /usage screen. The first command that does so prints a one-time disclosure and records it as live_disclosed_at.
Why it is off by default: Claude Code's legal and compliance page says developers may not collect or intermediate Claude.ai credentials, and the endpoint is undocumented, rate-limited and may change. When it changes, mcc shows "unavailable" rather than failing.
One live look at every account: mcc usage --all. Without changing the config, --all looks every profile's usage up live for that run only, the default included, reading and sending each profile's login the same way. What it finds is saved to the statusline cache, so the next mcc usage without --all, and mcc list and mcc run, show it with its age until a window resets or newer numbers are cached; an account it can't read keeps what was cached. Only percentages and reset times are saved, never the token. It can't be combined with a profile name, and MCC_NO_USAGE=1 still skips usage (no lookup, no notice). mcc list and mcc run have no --all.
Each time mcc usage --all looks usage up, it prints this risk notice on stderr (with -q too; --json on stdout stays clean):
⚠ --all looks usage up live for every account, the default included: mcc reads each profile's Claude Code login (its OAuth access token, from .credentials.json or the macOS Keychain) and sends it to Anthropic's undocumented, rate-limited usage endpoint (https://api.anthropic.com/api/oauth/usage). Anthropic says third-party tools may not collect or intermediate Claude.ai credentials (https://code.claude.com/docs/en/legal-and-compliance), so use this at your own discretion, only with accounts you own, and never to get around usage limits. Without --all, mcc usage reads the mcc statusline cache (unless [usage] live = true).
- Never fatal. If usage can't be determined (nothing cached; or, live: logged out, expired login, offline, API error), the profile shows
—orunavailablewith the reason, and the command still exits 0. Live requests run in parallel with short timeouts: 2 s to connect, 4 s total. - Tokens stay private. With the live lookup, a profile's access token is only sent to that endpoint, for its own profile. It is never printed, logged or written anywhere. mcc never refreshes tokens: if a login has expired, start the profile in Claude Code once (
work,claude, …) and it refreshes itself. - Turn it off with
mcc list --no-usageorMCC_NO_USAGE=1(which also applies tomcc usageandmcc run). Usage then shows—and nothing reads the cache, the network or the keychain.
JSON format
In mcc list --json every profile has a usage object. mcc usage --json prints one object per profile with name, command, is_default, account (null when logged out, or while emails are hidden, as they are by default) and the same usage object:
"usage": {
"status": "ok",
"reason": null,
"five_hour": { "percent": 42.0, "resets_at": "2026-10-10T16:00:00Z" },
"weekly": { "percent": 18.0, "resets_at": "2026-10-14T00:00:00Z" },
"source": "cache",
"updated_at": "2026-10-10T11:48:00Z"
}status is ok or unavailable. five_hour and weekly are null when there is no data (resets_at can be null too). source is cache, live or null (not looked up), and updated_at is when the numbers were cached, by the statusline or the last mcc usage --all (null for live lookups). When status is unavailable, reason is one of:
reason | Meaning |
|---|---|
not_logged_in | No Claude Code OAuth login found for the profile |
token_expired | The stored login has expired, or the API rejected it (HTTP 401); start the profile to refresh it |
unauthorized | The API refused the token (HTTP 403), for example a login without the profile scope |
rate_limited | HTTP 429 |
network | Offline, timeout or connection failure |
http_error | Any other HTTP status |
parse_error | The response wasn't the expected JSON |
disabled | Not fetched (--no-usage / MCC_NO_USAGE) |
no_data | Nothing current in the statusline cache: never cached, or every cached window has reset since; run /usage in Claude Code. The other reasons only come from the live lookup |
Alias rules #
An alias must be 1–32 characters: lowercase letters, digits, - or _, starting with a letter. It is rejected if any of these already uses the name:
- mcc's reserved names:
claude,mcc,default,help,all,path,share,link,refresh-launchers,project,run,env,exec,statusline,doctor - shell keywords and builtins
- existing mcc profiles
- executables on
$PATH - aliases and functions in your rc files (
.zshrc,.bashrc,.bash_profile,.profile, fish config, …) - anything your interactive shell resolves with
type <name>, which catches plugin-defined aliases
A rejected alias is a usage error (exit 2).
Files & locations #
| What | Where |
|---|---|
| Default profile | ~/.claude + ~/.claude.json (command: claude) |
| mcc profiles | ~/.mcc/profiles/<alias>/, used as CLAUDE_CONFIG_DIR |
| Launcher | ~/.local/bin/<alias>; works in any shell as soon as it's written |
| Shell alias | A managed block in your rc file, between # >>> mcc:<alias> >>> and # <<< mcc:<alias> <<< |
| Config & registry | ~/.mcc/config.toml |
| Log | ~/.mcc/logs/mcc.log; every run is appended here, and at about 1 MB it is moved to mcc.log.1 (replacing the previous one) |
| Shared sessions | ~/.mcc/shared/projects (the default group) and ~/.mcc/shared/groups/<name>/projects, only for profiles that opted in with mcc share |
| Project defaults | [projects."<dir>"] tables in ~/.mcc/config.toml, written by mcc project set |
| rc file backups | ~/.mcc/backups/ |
| Statusline state | ~/.mcc/state/<profile>/usage.json (from mcc statusline or mcc usage --all) and statusline.json (only after mcc statusline install); settings backups in ~/.mcc/backups/ |
| Sync backups | <profile>/.mcc-backup/<timestamp>/, also holding the profile's own copy of what mcc link replaces (plugins included) |
| Sync record | <profile>/.mcc-sync.json: a hash of each path and MCP server mcc last wrote, for three-way sync |
| Settings overlay | [profiles.<alias>.settings] in ~/.mcc/config.toml and <profile>/settings.mcc.json; see Per-profile settings overlays |
| Config lock | ~/.mcc/.lock, locked by every command that writes the config |
Set MCC_HOME to make mcc use another directory instead of $HOME for everything it reads and writes.
Environment variables #
| Variable | Effect |
|---|---|
MCC_HOME | Use this directory instead of $HOME for everything mcc reads and writes (useful for testing) |
MCC_CLAUDE_BIN | Path to the claude binary |
MCC_NON_INTERACTIVE | Set to any value (even empty) to never prompt, as when stdin or stderr isn't a terminal: required prompts stop and name the flag to pass instead, and optional ones take their default (useful in scripts and CI) |
MCC_NO_USAGE | Any value except empty or 0: same as mcc list --no-usage; mcc usage shows usage as not fetched |
COLUMNS | Terminal width used to size usage bars (default: detected width; unlimited when piped) |
MCC_USAGE_URL | Test/debug override for the usage endpoint. It receives bearer tokens, so only https:// URLs and http:// on loopback (127.0.0.1, localhost, [::1]) are accepted; any other value is refused and usage is not fetched at all |
MCC_SECURITY_BIN | Test/debug override for the macOS security binary used to read Keychain logins (default /usr/bin/security) |
NO_COLOR | Disable colors |
Exit codes #
| Code | Meaning |
|---|---|
0 | Success |
1 | Runtime error (I/O failure, claude missing, …), or mcc doctor found a problem |
2 | Usage error (bad arguments, invalid or taken alias, confirmation needed without a terminal) |
3 | Invalid input (corrupt config.toml or JSON) |
130 | Interrupted (Ctrl+C) |
Troubleshooting #
The new command isn't found
The launcher lives in ~/.local/bin. If that directory isn't on your PATH, run mcc init --force; it checks and offers to add it. The shell alias only applies to terminals opened after mcc add.
Usage shows — or unavailable
— means nothing current is cached for that profile. Run mcc statusline install once (profiles get it with their next mcc sync), then use the profile in Claude Code, or run /usage in it; the data exists only for Pro and Max plans. unavailable comes from the opt-in live lookup: run mcc list --long or mcc usage to see the reason. For token_expired, start that profile in Claude Code once (for example work) so it refreshes its own login; mcc never refreshes tokens itself. For not_logged_in, run the profile's command and sign in.
claude isn't detected
Point mcc at the binary with MCC_CLAUDE_BIN=/path/to/claude, or put it on your PATH and run mcc init --force.
Something went wrong
Run mcc doctor first: it checks every profile's setup and prints a fix for each problem. Every run is logged to ~/.mcc/logs/mcc.log; add --verbose to see the same detail in the terminal. Your rc file backups are in ~/.mcc/backups/. If you think you've found a bug, open an issue. Report security problems privately as described in SECURITY.md.
Uninstall #
Delete every mcc profile (this logs each one out), remove the binary, then remove mcc's state. Your default ~/.claude profile is left alone.
$ mcc statusline uninstall # if you ran mcc statusline install: puts your previous statusLine back $ for p in $(mcc list --json | jq -r '.[] | select(.is_default | not) | .name'); do mcc delete "$p" --yes; done $ brew uninstall mcc # if you installed with Homebrew $ cargo uninstall mcc # if you built from source with cargo $ rm -f ~/.local/bin/mcc # if you used the install script $ rm -rf ~/.mcc