Skip to main content

Keep Claude Code's Remote Control and Artifacts on one account while inference follows cswap's account swap

Project description

cswap-pin

Keep Claude Code's Remote Control and Artifacts on one account while inference keeps following cswap's account swap.

The problem

cswap swaps the on-disk credential, so everything follows the swap — including two things that are not inference and that you usually want to stay put:

  • Remote Control — a session's owner is fixed at creation by whichever bearer created it. Swap accounts and the phone/web loses the session; stale "ghost" sessions pile up on the old account.
  • Artifacts — owned by the publishing bearer. After a swap a republish 403s and the artifact "disappears" from the account you are logged into.

Claude Code resolves all of these through one credential accessor and has no per-operation token selector, so splitting auth per operation inside one session means intercepting the requests.

How it works

A local MITM forward proxy that swaps the Authorization bearer on exactly the routes whose server-side ownership is decided by it, and passes everything else — /v1/messages above all — through untouched.

claude session
  HTTPS_PROXY ─► cswap pin proxy ──► (whatever HTTPS_PROXY was already set) ──► api.anthropic.com
                   swaps bearer on: /v1/code/sessions*, /v1/sessions/*,
                                    /api/frame/*, /v1/ultrareview/*
                   passes through:  /v1/messages, /api/oauth/usage, everything else

Inference keeps billing whichever account cswap has swapped onto. Only the claude.ai-side assets are pinned.

Install

uv tool install 'claude-swap[pin]'      # or: pipx install 'claude-swap[pin]'

The pin is an optional extra of claude-swap, not a standalone tool: it reads cswap's account store and rewrites the config cswap already manages. Installing cswap-pin on its own does nothing useful.

Use

cswap pin 2          # RC / artifacts / ultrareview → account 2
cswap pin            # show the current pin
cswap pin --clear    # remove it

The pinned account is re-read per request, so cswap pin <other> takes effect under a live daemon — no session restart. The one thing a re-pin cannot move is a Remote Control session that is already open: the server fixed its owner when it was created, so reconnecting inside it is what mints a new one under the new pin.

Requirements

  • Python 3.10+
  • claude-swap — a peer, not a dependency: this package is loaded by it (see src/cswap_pin/_host.py for the exact surface it borrows)
  • cryptography (installed automatically) for the MITM CA

Why a separate package

Upstream did not want a MITM proxy shipped inside claude-swap itself and asked for a companion distribution exposed through an optional extra. See realiti4/claude-swap#198.

Trust

The proxy generates its own CA to re-sign api.anthropic.com and names it in NODE_EXTRA_CA_CERTS. Node accepts exactly one file there, so an existing CA (a corporate MITM, another local proxy) is merged, never replaced — otherwise the session silently loses trust in every host the other proxy re-signs.

The proxy also requires a per-daemon credential on CONNECT: it listens on loopback, which carries no identity, and without one any local process could have a junk bearer replaced with the pinned account's real token.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cswap_pin-0.1.1.tar.gz (91.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cswap_pin-0.1.1-py3-none-any.whl (48.8 kB view details)

Uploaded Python 3

File details

Details for the file cswap_pin-0.1.1.tar.gz.

File metadata

  • Download URL: cswap_pin-0.1.1.tar.gz
  • Upload date:
  • Size: 91.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.18 {"installer":{"name":"uv","version":"0.11.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"22.04","id":"jammy","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for cswap_pin-0.1.1.tar.gz
Algorithm Hash digest
SHA256 9d77c53aa50f0a30b4cf434ff2ec48b540411d24aa09156f4a5e0abb4f23017b
MD5 074d46fa0c38c583fe213396c08aa841
BLAKE2b-256 73c41535ee1c47391626ebeec55b66ad595f56292d40ff1359ed297d9e48e3cf

See more details on using hashes here.

File details

Details for the file cswap_pin-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: cswap_pin-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 48.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.18 {"installer":{"name":"uv","version":"0.11.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"22.04","id":"jammy","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for cswap_pin-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 4ff707482e29aebab6c157651af44d47dc9725f1e168fd5a5dab46bc4d7be4f3
MD5 6aa83efae9e7c0d96d27a7d7aaebec5d
BLAKE2b-256 f2f83f5ee753a7a5c0d6ab0bc6c1f5b7cccdebb01c74679c1b362137e6c261b8

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page