Multiple windows for Claude Desktop with different APIs at the same time: keep your official Claude subscription in one window and run other windows on custom / third-party APIs (cc-switch). Windows.
翻譯準備中
外掛Python · PowerShellGitHub @TonF1917自行安裝營運者未確認
試用過了嗎? 點一下就好,不需要登入。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
安裝型專案無需部署網域也可驗證。個人儲存庫可透過 GitHub 登入驗證,組織儲存庫可使用上方的儲存庫驗證檔案。
Multiple windows for Claude Desktop with different APIs at the same time: keep your official Claude subscription in one window and run other windows on custom / third-party APIs (cc-switch). Windows. 多开 Claude Desktop,多个窗口同时使用不同 API(官方订阅 + 第三方 API 同时工作)。
翻譯準備中
取自儲存庫 README
正在載入完整 README。
檢視完整 README ↗English · 简体中文
Use several Claude Desktop windows at once, each on a different API. Keep your official Claude subscription in one window and run as many other windows as you like on custom / third-party APIs (driven by cc-switch). Multi-API, multi-window, multi-account Claude Desktop - on Windows (tested) and macOS (experimental).
Every window has its own data, its own recoloured icon (desktop, taskbar, system tray), its own taskbar button and - if you choose - its own API. The default third-party colour is the official icon in purple-black with a white star; pick any palette (Gemini, GPT, Perplexity, DeepSeek, WorkBuddy) or any #RRGGBB.
Unofficial community tool. Not affiliated with or endorsed by Anthropic or cc-switch. Icons are generated locally from the icon of your installed app; no Anthropic artwork is shipped in this repository.
claude:// links open in the window you used last (or a fixed one).ipwho.is and ipapi.co through the instance proxy before launch, automatically aligns TZ, --lang, and Accept-Language (COUNTRY_NETWORK_MAP) to the verified exit country, persists .proxy-identity.json, and supports strict proxyExitPolicy: "block" to abort launch on exit IP drift or GeoIP conflict.shield.cjs): Injects a Node.js network circuit breaker via NODE_OPTIONS that periodically re-verifies the proxy exit IP (CLAUDE_MULTI_STARTUP_IP) and immediately quarantines outbound http, https, and fetch requests if the proxy drops or drifts mid-session.--disable-quic, and pre-writes Default/Preferences (webrtc.ip_handling_policy = "disable_non_proxied_udp") while cleaning stale DevToolsActivePort files. Raw WebRTC UDP cannot be blocked from the command line — --force-webrtc-ip-handling-policy and --dns-prefetch-disable no longer exist in Chromium 156, the --webrtc-ip-handling-policy switch string is absent from Claude.exe, and the Preferences value is never propagated to the renderer. What actually works is udp-guard (a firewall rule blocking the host exe's outbound UDP) — see item 5 under "Multi-Official Account Support"..profile-identity.json): Locks each user-data-dir to its owning instanceId and rejects symbolic links to prevent accidental cross-account profile contamination.Requirements: Windows 11 (10 should work), PowerShell 5.1+, Claude Desktop from the Microsoft Store (AnthropicPBC.Claude), cc-switch with a Claude Desktop provider.
git clone https://github.com/TonF1917/claude-desktop-multiple-windows-different-api
cd claude-desktop-multiple-windows-different-api
.\claude-multi.ps1 install # icons + shortcuts for every window in instances.json
.\claude-multi.ps1 gui # or use the Desktop shortcut "Claude Multi Manager"
Then right-click each new Desktop shortcut and choose Pin to taskbar (Windows does not let scripts pin).
| Command | What it does |
|---|---|
gui | the manager window |
add -Id off2 -Name "Claude Official 2" -Kind official -Palette perplexity [-Proxy <url>] [-Timezone <tz>] | add a secondary official direct window (supports custom tint, dedicated proxy & process timezone) |
add -Id gem -Name "Claude Gemini" -Palette gemini [-Provider <id>] [-Proxy <url>] [-Timezone <tz>] | add a third-party window (any palette name or "#E11D48") |
init [-Id <id>] (alias setup) | provision/repair instance environment (creates Data dir, mirrors MCP config, junctions sessions, generates tinted icon & desktop shortcut) |
check [-Id <id>] (alias test-ip) | audit instance egress IP, residential/datacenter status, risk score (0-100), Claude region eligibility & timezone alignment |
install [-Force] | (re)build icons and shortcuts; rewires your existing pinned Claude shortcuts |
launch -Id gem | start a window |
udp-guard [-Id <id>] | install/repair the raw-WebRTC-UDP guard (firewall rule blocking the host exe's outbound UDP); needs elevation; re-run after an app upgrade |
list, providers, sync, remove -Id gem, icons -Force, uninstall | housekeeping |
The manager GUI exposes the same options: a kind selector next to Add, click-to-edit Proxy (credentials are masked in the grid and the output pane) and Timezone (common IANA zones or typed), Init / Check buttons that run in a background process and stream into an output pane, plus Stop.
The port lives in macos/ (Python 3, standard library only) and now mirrors the Windows feature set: multiple official windows, per-window kind / proxy / timezone, init / check, and a GUI with every option.
Honest status: it was written without access to a Mac. Config handling, palettes, proxy / timezone / launch-argument planning, secret masking, the egress check (against stubbed answers),
initfile provisioning and the GUI are exercised on Windows. The macOS-only steps - cloningClaude.app(cp -c),sips/iconutilicon tinting, ad-hoccodesign, starting the cloned binary and process matching throughps- follow the documented tool behaviour but have never been run on real hardware. Expect rough edges and please send the terminal output.
Get it: download ClaudeMulti-macOS-v1.2.0.zip (built by macos/build_release.sh), unzip, double-click Claude Multi.command (first time: right-click -> Open), or from a clone:
python3 macos/claude_multi.py gui
python3 macos/claude_multi.py add --id off2 --kind official --palette perplexity --proxy http://127.0.0.1:7890 --timezone America/Toronto
python3 macos/claude_multi.py add --id gem --name "Claude Gemini" --palette gemini [--provider <cc-switch id>]
python3 macos/claude_multi.py init [--id off2] # data dir, MCP-config link, session link, tinted Claude.app clone (~/Applications/Claude Multi)
python3 macos/claude_multi.py check [--id off2] # egress IP, residential/datacenter, risk, region, timezone alignment
python3 macos/claude_multi.py launch --id off2 # also: stop, restart, list, remove, install, uninstall, sync, providers
python3 macos/claude_multi.py agent & # session mirroring + silent background refresh
| Command | What it does |
|---|---|
add --id --name --kind official/3p --palette --proxy --timezone [--provider] [--lang] [--no-init] | add a window (3p is stored as cc-switch, like on Windows) |
init / setup [--id] [--force] | provision the data dir; mirror claude_desktop_config.json (symlink, else hardlink, else copy); link claude-code-sessions / local-agent-mode-sessions; build the tinted clone. Idempotent |
check / test-ip [--id] | exit IP through the window's proxy (HTTP/HTTPS proxies only - urllib has no SOCKS), IP type, risk score, Claude region, timezone match |
launch / stop / restart --id | run the window (see below) |
list, remove --id, uninstall, install [--force], sync, providers, agent, gui | housekeeping |
What a launch does on macOS. The window's own binary is executed directly (the primary official window runs the stock Claude.app; every other window runs its tinted clone), so the environment really reaches the process:
--proxy-server is unconditionally passed to Electron with credentials stripped, guaranteeing Chromium routes all traffic through the proxy and preventing direct gateway bypass.--use-mock-keychain and --password-store=basic prevent multi-instances from colliding on macOS Keychain "Claude Safe Storage", avoiding ad-hoc signature prompts and cookie wipeouts.--webrtc-ip-handling-policy=disable_non_proxied_udp and --force-webrtc-ip-handling-policy strictly block direct UDP STUN bypass.TZ=<timezone> for that process only, plus --lang=<locale> derived from the timezone (override with "lang").--webrtc-ip-handling-policy=disable_non_proxied_udp; --user-data-dir=~/.claude-multi/<id>/Claude for every window except the primary official one.--kind official, id other than official) get an isolated data dir, any configLibrary is deleted before every start, and the sibling Claude-3p is never created, so they stay pure 1P and never pick up a cc-switch profile.http://***@host:port) in list, the GUI, errors, the output pane and ~/.claude-multi/claude-multi.log; they remain in plain text in instances.json and in the child's environment.Limits / not ported: pin / MCP-server sync, claude:// routing and tray icon. The primary official window cannot be isolated from cc-switch like on Windows (there is no LOCALAPPDATA to redirect): launching it while cc-switch has a third-party profile applied can switch it to third-party mode. The python3 from the Xcode tools may ship an old Tk; if gui fails, install Python from python.org or use the CLI.
In addition to 1 Official + N Third-Party windows, the tool now fully supports running multiple official subscription accounts (1P) and third-party accounts (3P) concurrently side-by-side:
Pure Direct Multi-Official Connections: The primary official instance uses the default home directory. Secondary official instances (e.g., official2) get isolated virtual data directories and private LOCALAPPDATA with empty Claude-3p, completely stripping configLibrary checks to guarantee 100% pure 1P direct connections without session collisions.
Dedicated Network & Proxy Isolation (-Proxy): Bypasses the client-side block on --proxy-server by dynamically injecting $env:HTTPS_PROXY at the child-process level. Assigns dedicated residential proxy exits per account to prevent multi-account IP association bans.
Process-Level Timezone Alignment (-Timezone): Dynamically injects $env:TZ (e.g. America/Toronto, Asia/Jakarta) into the child process. The Electron / V8 JavaScript layer aligns 100% with the egress IP's physical location without mutating Windows system timezone, eliminating cross-regional mismatch flags.
Automated Provisioning & Egress Audit (init & check):
.\claude-multi.ps1 init [-Id <id>]: Provisions the complete environment in one click (creates Data dir, mirrors MCP claude_desktop_config.json, junctions claude-code-sessions, and generates tinted icons and shortcuts)..\claude-multi.ps1 check [-Id <id>]: Audits all instances' egress IP, residential/datacenter status, fraud risk score (0-100), Claude regional support, and timezone alignment.Raw UDP Leak Blocking (udp-guard): --proxy-server only proxies TCP, so WebRTC STUN goes straight out of the physical NIC and hands the peer your real public IP. The command line cannot stop it — --force-webrtc-ip-handling-policy no longer exists in Chromium 156 (silently ignored), the --webrtc-ip-handling-policy switch string is not present in Claude.exe (Electron never compiled it in), and webrtc.ip_handling_policy written to Preferences is not propagated to the renderer. What actually works is a firewall rule that blocks the host exe's outbound UDP:
.\claude-multi.ps1 udp-guard [-Id <id>] # run from an elevated PowerShell
The rule targets only the Claude host Claude.exe (53/UDP is left open so name resolution keeps working) and does not affect other programs on the machine. To verify: after enabling it, a STUN Binding Request to must time out. Every launch also checks the rule and writes a line to when the path no longer matches. Set to turn the automatic check off.
Choose a Claude Desktop provider in cc-switch (not "Official"). cc-switch starts its gateway on 127.0.0.1:15721 and writes the profile into the shared 3P config folder. Windows that follow cc-switch use that gateway and its currently selected provider. Windows with a specific provider get a profile built from that provider's own base URL, key and model routes and talk to its upstream directly (Anthropic-format providers only; model ids are the real upstream ids). That is how two windows use two different APIs at the same moment. A hand-written profile can be set per window with "profile": "path\\to\\profile.json" (see examples/profile.example.json).
When cc-switch is set to Official, third-party windows have no profile and show the normal sign-in screen.
| Item | Synced? | How / when it shows up in another window |
|---|---|---|
| Sessions (new ones, titles, archive state) | yes | files mirrored within seconds; the other window loads them after its silent background restart |
| Pinned / starred sessions and pin order | yes | the isStarred flag in each session, plus starred-* and pinnedOrder in claude_desktop_config.json; written into a window only while it is closed (or just before its background restart) so the app cannot overwrite it |
| MCP servers | yes | same mechanism (mcpServers); switch off in the GUI |
| Conversation transcripts | yes (natively) | they live in ~\.claude\projects, shared by every window |
| Login, provider, model list, window size/position | no | per window on purpose |
Known limit - pins. Each Claude Desktop keeps its pinned list in memory and rewrites it itself: a running window keeps showing its own pins until it is restarted, and a starting window trims the list it reads (tested: 17 pins written while closed came back as 12 within 8 seconds; the dropped ones are sessions created after 12 Oct 23:50 plus one older one - the rule is the app's, not ours). This tool keeps the config files identical and never lets an empty or new window wipe them, but it cannot force two windows to display the same pins.
Why not instantly? Claude Desktop does read these folders - but only when it starts, and again only when the signed-in account or organisation changes. It has no file watcher, rewriting its config.json does not make it re-read anything, and remote debugging is blocked in the production build, so nothing outside the app can tell a running window to re-read the folder. The closest safe thing is the silent restart: a window restarts in the background only if it is not focused, has not written a session file in the last 45 s, and none of its agent/tool child processes is using CPU. The restarted window comes back minimised and without taking the focus (it is started with SW_SHOWMINNOACTIVE), and syncing shows no pop-ups at all: notifications are off by default and can be switched on in the manager. A window you are using right now (focused and keyboard/mouse input in the last 90 s) is never restarted: you get a Windows notification with a Reload now button instead (or use Restart selected in the manager); once you have been idle for 90 s it is refreshed automatically. Session folders may be shared between windows through junctions - the check is therefore per running window ("does it know every session file that exists?"), not based on copying. The official window is excluded unless you tick Also live-refresh the official window (it may hold unsent drafts).
Same session in two windows. Every window runs its own Claude Code process per session (--resume=<id>). If you send in both, both append to the same transcript while each keeps its own context, so the history interleaves and the windows disagree. The agent notifies you when a session is live in two windows and one of them is working - keep a session active in one window at a time.
How sessions look. Every window shows the same merged list; there is no per-window badge. A session keeps its folder, model and effort, but when you open it in another window it runs through that window's login/provider (subscription in the official one, the chosen provider in a third-party one).
configLibrary from %LOCALAPPDATA%\Claude-3p; cc-switch writes the third-party profile there; a profile with disableDeploymentModeChooser forces every window that reads it into 3P mode - including the official one on its next start.--user-data-dir and CLAUDE_USER_DATA_DIR do not help on Windows. The production build strips the env var and overrides the data dir in 3P mode, so a second 3P window collides with the first and exits silently.%LOCALAPPDATA% does. The 3P data dir is derived from that variable, so each extra window starts with its own private LOCALAPPDATA (~\.claude-multi\<id>\Local) and its own profile.LOCALAPPDATA whose Claude-3p is empty (Claude and Packages are junctions to the real ones), so it can never be forced into 3P.SHGetPropertyStoreForWindow, WM_SETICON) and re-skins the window's notification-area icon (Shell_NotifyIcon, NIM_MODIFY); the shortcuts carry matching IDs.AppData\*\ClaudeMulti. Explorer and the taskbar render a blank page for .ico files under such a folder (a .ico anywhere else works), so icons are generated into ~\.claude-multi\icons.MIT - see LICENSE.
stun.l.google.com:19302GUARD~/.claude-multi/launch-audit.log"settings": { "udpGuard": false }