{"slug": "show-hn-cfswitch-switch-between-multiple-cloudflare-accounts-in-wrangler", "title": "Show HN: Cfswitch – Switch between multiple Cloudflare accounts in Wrangler", "summary": "Cfswitch, a new CLI tool, enables seamless switching between multiple Cloudflare accounts in Wrangler by using named auth profiles injected as environment variables. Built for AI agents and CI pipelines, it eliminates the need for repeated logout/login steps during deployments. The tool is fully non-interactive, has no runtime dependencies, and supports commands like wizard, add, and wrangler execution.", "body_md": "Switch Cloudflare / wrangler auth between multiple accounts. Built for AI agents and CI first, humans second.\n\n`wrangler login`\n\nonly holds one OAuth session at a time. If you (or your coding agent) juggle several Cloudflare accounts, every deploy becomes a logout/login dance. `cfswitch`\n\nfixes this with named auth profiles injected as environment variables (`CLOUDFLARE_API_TOKEN`\n\n/ `CLOUDFLARE_ACCOUNT_ID`\n\n), which wrangler always honors over its OAuth login, per [Cloudflare's docs](https://developers.cloudflare.com/workers/wrangler/system-environment-variables/).\n\nDesign rules:\n\n- It never prompts. Every command is fully non-interactive, so any agent, script, or CI job can run it safely.\n- No runtime dependencies. One bundled file, Node ≥ 18, so\n`npx cfswitch-cli`\n\nruns without installing anything. `--json`\n\non every read command, clean exit codes, errors on stderr.- Token values are only ever printed by\n`cfswitch env`\n\n, whose whole job is printing them.\n\n```\nnpm install -g cfswitch-cli   # installs the `cfswitch` command (or: bun add -g cfswitch-cli)\n# or zero-install:\nnpx cfswitch-cli help\ncfswitch wizard\n```\n\nThis opens the Cloudflare dashboard with a pre-filled token (Workers, Pages, KV, R2, D1, routes) and watches your clipboard. You log in and click Continue to summary, Create Token, then Copy. The moment the token hits your clipboard, cfswitch verifies it, looks up which accounts it can reach, and saves a pinned profile for each. Switch dashboard accounts and repeat; Ctrl-C when done. Use `cfswitch wizard --print-url`\n\nif you just want the pre-filled URL (say, to open on another machine).\n\nCreate an API token for each account at [dash.cloudflare.com/profile/api-tokens](https://dash.cloudflare.com/profile/api-tokens) (the **\"Edit Cloudflare Workers\"** template covers Workers + Pages deploys). Then:\n\n```\n# add profiles (token via flag, stdin, or CFSWITCH_TOKEN env; never a prompt)\ncfswitch add personal --token cf_xxx --account-id 6f9x...\necho \"$WORK_TOKEN\" | cfswitch add work --token-stdin\n\n# sanity-check them against the Cloudflare API\ncfswitch verify work\ncfswitch accounts work        # list account IDs this token can reach\n\n# run wrangler as any account, from any directory\ncfswitch wrangler -p personal whoami\ncfswitch wrangler -p work deploy\ncfswitch wrangler -p work pages deploy out\n\n# or set a default and stop passing -p\ncfswitch use work\ncfswitch wrangler d1 list\n```\n\n| Command | What it does |\n|---|---|\n`wizard [--name <s>] [--print-url] [--no-browser]` |\nGuided setup: pre-filled dashboard URL + clipboard watch, then auto-created pinned profiles. |\n`add <name> --token <T> [--account-id <ID>] [--note <s>]` |\nSave/update a token profile. Also accepts `--token-stdin` or `$CFSWITCH_TOKEN` . |\n`login <name>` |\nOAuth alternative: runs `wrangler login` inside an isolated config dir, so multiple OAuth sessions coexist. |\n`list [--json]` |\nList profiles. Tokens are never shown. |\n`use <name>` |\nSet the default profile. |\n`current [--json]` |\nShow the active profile and where it came from. |\n`remove <name>` |\nDelete a profile (and its isolated OAuth state, if any). |\n`verify [<name>] [--json]` |\nCheck the token against `/user/tokens/verify` (falls back to the account-scoped endpoint for account-owned tokens). Exit 1 if invalid. |\n`accounts [<name>] [--json]` |\nList account IDs the token can access; use this to find the right `--account-id` . |\n`env [<name>] [--json]` |\nPrint `export` lines: `eval \"$(cfswitch env work)\"` . |\n`exec [-p <name>] -- <cmd> [args…]` |\nRun any command with the profile's env injected (wrangler, terraform, curl, …). |\n`wrangler [-p <name>] [args…]` |\nRun wrangler as the profile. Resolves local `node_modules/.bin/wrangler` , then PATH, then `npx wrangler` . |\n\nProfile resolution for commands that take an optional name: explicit arg / `-p`\n\n, then the `$CFSWITCH_PROFILE`\n\nenv var, then the default set via `use`\n\n. The env var lets you pin an agent session or CI job to one account.\n\nRewriting wrangler's global OAuth state (`~/.config/.wrangler/config/default.toml`\n\n) to \"switch\" accounts is racy: two concurrent agents would fight over one global file, and newer wrangler versions move OAuth creds into the OS keychain. Environment-variable injection is Cloudflare's documented CI path, is stateless per-process, and lets any number of concurrent processes each use a different account safely.\n\nIf you really want OAuth (e.g. no permission to create API tokens), `cfswitch login <name>`\n\ngives each profile its own `XDG_CONFIG_HOME`\n\n(with `CLOUDFLARE_AUTH_USE_KEYRING=false`\n\n), so sessions live side by side and never clobber your real wrangler login.\n\n- Profiles live in\n`~/.config/cfswitch/profiles.json`\n\n, created`0600`\n\nin a`0700`\n\ndir. - Prefer scoped tokens (per-account, minimum permissions, optional TTL/IP filters) over the Global API Key.\n`list`\n\n,`current`\n\n,`verify`\n\n, and`accounts`\n\nnever output token values; only`env`\n\ndoes, and only because that's its job.\n\nThere are three ways to teach an agent about cfswitch. Pick one.\n\nThis repo is its own plugin marketplace:\n\n```\n/plugin marketplace add dukeeagle/cfswitch\n/plugin install cfswitch@cfswitch\n```\n\nThe skill ships in [ skills/cfswitch/](/dukeeagle/cfswitch/blob/main/skills/cfswitch/SKILL.md) and tells agents when and how to use cfswitch:\n\n```\n./install-skill.sh           # symlinks into ~/.agents/skills (hub, read by Cursor);\n                             # ~/.claude/skills and ~/.codex/skills chain through it\n./install-skill.sh --copy    # copy instead of symlink (survives deleting this repo)\n./install-skill.sh --uninstall\n```\n\nThe installer never clobbers an existing real directory at any of those paths, and re-running it is idempotent.\n\n[AGENTS.md](/dukeeagle/cfswitch/blob/main/AGENTS.md) is a compact, copy-pasteable ruleset. Drop it into your project, or point your agent at `npx cfswitch-cli help`\n\n, which is written to be sufficient on its own.\n\n[cfman](https://github.com/novincode/cfman) had the core idea first: store named tokens, inject them as env vars. cfswitch rebuilds that idea for agents, adding JSON output, `exec`\n\n/`env`\n\nprimitives, the token wizard, isolated OAuth profiles, and a no-prompts guarantee.\n\nMIT", "url": "https://wpnews.pro/news/show-hn-cfswitch-switch-between-multiple-cloudflare-accounts-in-wrangler", "canonical_source": "https://github.com/dukeeagle/cfswitch", "published_at": "2026-07-07 18:12:32+00:00", "updated_at": "2026-07-07 18:30:04.580165+00:00", "lang": "en", "topics": ["developer-tools", "ai-agents"], "entities": ["Cloudflare", "Wrangler", "cfswitch", "npx", "npm"], "alternates": {"html": "https://wpnews.pro/news/show-hn-cfswitch-switch-between-multiple-cloudflare-accounts-in-wrangler", "markdown": "https://wpnews.pro/news/show-hn-cfswitch-switch-between-multiple-cloudflare-accounts-in-wrangler.md", "text": "https://wpnews.pro/news/show-hn-cfswitch-switch-between-multiple-cloudflare-accounts-in-wrangler.txt", "jsonld": "https://wpnews.pro/news/show-hn-cfswitch-switch-between-multiple-cloudflare-accounts-in-wrangler.jsonld"}}