---
name: claude-subs
description: Set up and run two or more Claude subscriptions (Pro or Max) in Claude Code with ONE shared workspace (the same CLAUDE.md, skills, commands, agents, hooks, settings, memory and chat history), each account signed in through Anthropic's own login. No proxy, no token sharing. Adds claude-a / claude-b / claude-auto shell commands, a status line that shows which account a session bills and records its usage, and a one-command pivot when a limit hits. Use when the user wants a second Claude account or subscription in Claude Code, wants to switch between Claude accounts, wants to keep building after hitting the 5-hour or weekly limit, or asks about proxies like CLIProxyAPI for multiple accounts.
---

# claude-subs: two Claude subscriptions, one workspace

You are setting up a second (or third) Claude subscription for this user so that every account
sees the same Claude Code workspace. The tool that does the work is `scripts/claude-sub` in this
skill's folder (Claude Code shows that folder as the skill's base directory). Work through the
steps in order. Report each result in plain words as you go.

## What the user ends up with

| Command | What it does |
|---|---|
| `claude` or `claude-a` | the main account (the login in `~/.claude`), same as today |
| `claude-b` | the second account, with the same CLAUDE.md, skills, memory, hooks, settings, history |
| `claude-auto` | starts whichever account has the most room left |
| `/exit`, then `claude-b -c` | continues the same chat on the other account when a limit hits |
| `claude-sub status` | both accounts, their emails, last-seen 5-hour and weekly use |

## Ground rules while you run this skill

1. Never read, print, copy or move login secrets: keychain passwords, any `.credentials.json`
   content, tokens. Checking that a login exists is fine; the script does it without reading secrets.
2. Never link credential files between accounts, and never work around the script's refusal to.
3. Never install or recommend a proxy that holds Claude logins (CLIProxyAPI and similar). If asked,
   explain why with the section "Why not a proxy" below.
4. The browser sign-in is the user's step. You cannot and must not do it for them.
5. The script backs up the shell file and `~/.claude/settings.json` before it edits them
   (to `~/.local/state/claude-sub/backups/`). Do not edit those files by other means.
6. Buying a second plan is the user's decision. If they do not have one yet, finish setup and tell
   them the login step waits for it. It must be a different email from the main account.

## Step 1: Preflight

Run these and read the results:

```bash
uname -s                                   # Darwin or Linux (Windows: inside WSL only)
command -v claude && claude --version      # Claude Code 2.x or newer
claude auth status --json                  # need "loggedIn": true and "authMethod": "claude.ai"
echo "$SHELL"                              # zsh or bash get the shell commands automatically
ls -d ~/.claude-* 2>/dev/null              # existing folders that start with .claude-
env | cut -d= -f1 | grep -E '^(CLAUDE_CONFIG_DIR|ANTHROPIC_API_KEY)$'
python3 --version                          # 3.8 or newer
```

Stop and explain when:
- `claude` is missing, or `claude auth status` fails: Claude Code is not installed or too old. Suggest `claude update`.
- `authMethod` is not `claude.ai`: the main login is an API key, not a subscription. This skill is for subscriptions.
- `CLAUDE_CONFIG_DIR` is set: the user already runs a custom config folder. This skill assumes `~/.claude` is the main account. Ask them to run it from a shell without that variable.
- The account name they want already exists as `~/.claude-<name>` and does not contain `.claude-sub.json`: pick another name.

Not a blocker, but say it: when `ANTHROPIC_API_KEY` is exported, `claude -p` (headless) bills that
API key before the plan. The commands this skill adds drop the key for `-p` runs so the plan pays.

Ask at most once, only if unclear: the name for the new account (default `b`), and whether they
already have the second plan.

## Step 2: Install the tool

```bash
SKILL_DIR="<this skill's base directory>"
mkdir -p ~/.local/bin
cp "$SKILL_DIR/scripts/claude-sub" ~/.local/bin/claude-sub
chmod +x ~/.local/bin/claude-sub
~/.local/bin/claude-sub help | head -3
```

## Step 3: Set up the account

```bash
~/.local/bin/claude-sub setup b
```

This is safe to re-run. It:
- creates `~/.claude-b`, where every shared entry is a link back into `~/.claude`, and the per-login
  items (login, background daemon, telemetry, Claude Code's own config backups) stay separate;
- seeds `~/.claude-b/.claude.json` without any identity, then copies the MCP servers, folder trust,
  and the "do not use this API key" answer across (every launch keeps these in step);
- adds `claude-a`, `claude-b`, `claude-auto` to `~/.zshrc` (bash: `~/.bashrc` on Linux,
  `~/.bash_profile` on macOS) between `# >>> claude-sub >>>` markers;
- sets the status line to show `[A]` or `[B]` and record usage. An existing status line is kept and
  wrapped, not replaced.

Options: `--rc FILE` (another shell file), `--no-shell`, `--no-statusline`. For more accounts, run
`setup c`, `setup work`, and so on.

## Step 4: The sign-in (the user's step)

Tell the user, word for word:

1. Open a NEW terminal tab (it loads the new commands).
2. Run: `claude-sub login b`
3. The browser opens. Look at the email on the page. It must be your SECOND account. If it shows
   your main account, switch account on that page, or paste the printed link into a private window.
4. Come back here and say "done".

`claude-sub login` checks the result itself. It refuses when the second slot signed in to the same
account as the main one, and it tells the user how to fix that (`claude-sub logout b`, then log in
again). On macOS it also checks that the login landed in its own keychain slot. If it did not, the
Claude Code version is too old: `claude update`, then log out and in again.

## Step 5: Verify (you do this)

```bash
~/.local/bin/claude-sub doctor
~/.local/bin/claude-sub status
~/.local/bin/claude-sub exec b -p "Reply with exactly: OK" --output-format json --no-session-persistence
```

Pass: doctor prints `doctor: all good`, status shows two different emails, and the last command
returns `"result": "OK"` with `"is_error": false`. If `--no-session-persistence` is an unknown
option in their version, drop it. It only keeps the test out of `claude -c`.

To show exactly which tool servers the new account has, compare the `mcp_servers` list in the
first line of these two runs:

```bash
~/.local/bin/claude-sub exec a -p "hi" --output-format stream-json --verbose --no-session-persistence | head -1
~/.local/bin/claude-sub exec b -p "hi" --output-format stream-json --verbose --no-session-persistence | head -1
```

## Step 6: Teach the daily flow

- Start work: `claude-auto`, or pick one with `claude-a` or `claude-b`.
- The status line shows which account the session bills: `[A]` or `[B]`.
- Limit hit mid-task: type `/exit`, then `claude-b -c`. The same chat continues on the other
  account, because the chat history is shared. With several chats open in one folder, use
  `claude-b --resume <session-id>` or the `/resume` picker so it continues the right one.
- Scripts and cron: `claude-sub exec b -p "..."` runs on account b and bills the plan.

## Step 7: What stays separate per account

Tell the user these, and offer to help with the first two:
- claude.ai connectors (Gmail, Calendar, Drive, Slack and so on) belong to each claude.ai account.
  To use them on account b, connect them on claude.ai while signed in as that account. Only the
  ones they need.
- MCP servers with their own OAuth show `needs-auth` on the new account. Fix: type `/mcp` in a
  session on that account and sign in once.
- Artifacts, Remote Control, push notifications and the session list in the Claude app follow the
  login that ran the session.
- Everything local is shared: CLAUDE.md, rules, skills, commands, agents, hooks, settings, plugins,
  memory, chat history, and the MCP servers configured on this machine.

## How it works (for your answers)

- Claude Code reads everything from the folder in `CLAUDE_CONFIG_DIR` (default `~/.claude`), and
  keeps that folder's login in its own slot: on macOS the keychain item
  `Claude Code-credentials-<first 8 hex of sha256(folder path)>`, on Linux
  `<folder>/.credentials.json`. The folder's `.claude.json` holds the account identity.
- `~/.claude-b` links every shared entry back into `~/.claude`, so both logins read and write the
  same files. A settings change made in a b session lands in the shared `settings.json`.
- Each `claude-b` launch runs `claude-sub sync b`: new items in `~/.claude` get linked, and a link
  that Claude Code turned into a real file is moved to `~/.claude-b/.diverged/` and relinked (the
  user sees a warning). Names that look like credentials are never linked.
- Keep the folder path exact. The login slot is keyed by the path string, so a moved or renamed
  `~/.claude-b` looks signed out.

## Why not a proxy

Proxies such as CLIProxyAPI sit between Claude Code and Anthropic, hold the OAuth tokens of several
accounts, and rotate requests across them. Anthropic's Claude Code legal page says developers "may
not collect, store, or intermediate Claude.ai credentials or session tokens", that "sign-in to a
Claude account must complete through Anthropic's own flow", and that Anthropic may enforce this
"without prior notice": https://code.claude.com/docs/en/legal-and-compliance. The same page allows
"an end user signing in to the unmodified Claude Code binary with their own Claude subscription",
which is all this skill does. Proxy users have reported disabled accounts ("This organization has
been disabled"). Rules change, so point the user to that page for the current wording.

## Gotchas

1. **Wrong account in the browser.** The browser is often signed in to the main account already.
   `claude-sub login` refuses a same-account login; the fix is logout, then login with the other
   account (switch account on the page, or use a private window).
2. **Old Claude Code on macOS.** Older versions kept one keychain login for every folder.
   `claude-sub login` checks the per-folder slot. Fix: `claude update`, then log out and in again.
3. **Headless billing.** `claude -p` with an exported `ANTHROPIC_API_KEY` bills the API key. Use
   `claude-a -p`, `claude-b -p` or `claude-sub exec <name> -p`, which drop the key for that run.
4. **Hooks that match paths as text.** In a b session, Claude Code names the memory folder and
   skill paths under `~/.claude-b/...`. A hook that checks `startswith("~/.claude/...")` misses those
   writes. Rewrite the path first:

   ```python
   import os
   HOME = os.path.expanduser("~")

   def canon(p):
       """~/.claude-<name>/<linked entry> -> ~/.claude/<entry>; per-login items stay as they are."""
       if p.startswith(os.path.join(HOME, ".claude-")):
           shadow, _, rest = p[len(HOME) + 1:].partition(os.sep)
           first = rest.split(os.sep, 1)[0]
           link = os.path.join(HOME, shadow, first)
           if first and os.path.islink(link) and os.readlink(link) == os.path.join(HOME, ".claude", first):
               return os.path.join(HOME, ".claude", rest)
       return p
   ```

   Do not use `realpath` for this: on macOS it also turns `/tmp` into `/private/tmp` and can break
   other path rules.
5. **Two machines.** Run the skill on each machine. Each machine signs in once per account.
6. **Symlinked dotfiles.** The script edits the shell file and `settings.json` in place, so a
   symlink into a dotfiles repo stays a symlink.

## Undo

```bash
claude-sub uninstall b
```

It signs account b out, moves `~/.claude-b` to `~/.claude-b.removed-<time>`, and, when b was the
last extra account, removes the shell block and restores the old status line. Nothing is
hard-deleted. On macOS it prints the command to remove the saved login, in case one is left.
