browserctrl maps Claude-in-Chrome device ids to the Chromium browser, profile, signed-in email and display name behind them, says which profiles are open right now, and resolves a nickname to an id. It is a CLI and a Go library (github.com/khanakia/browserctrl/browser); the repository README is the landing page.
Important
Requires the Claude in Chrome extension, installed per profile. The device id is minted by the extension on its first run in a profile and exists nowhere else, so a profile without the extension has no id and is not listed (see list --profiles).
go install github.com/khanakia/browserctrl@latestOr from a clone: task build produces bin/browserctrl, task install puts it on $GOPATH/bin.
| Guide | Covers |
|---|---|
| Command reference | every verb — list · find · skills · completion · --version — every flag (--running, --reachable, --profiles, --account-alias, …), real output, exit codes, the JSON shape, and how Claude accounts decide which browsers a session can reach |
| Recipes | Claude Code integration end to end, which Claude account each browser is on, why a profile is missing, shell and jq workflows, custom --user-data-dir roots, naming browsers, using the fixture package in your own tests |
| Go API | importing browser and browser/browsertest — Scan, Match, OnlyRunning, OnlyAccount, ReadClaudeAccounts, ClaudeConfigPaths, ReadProfiles, ReadExtensionStore, DefaultRoots, fixtures |
- Read-only. The tool never opens a live browser store. Each extension LevelDB is copied to a temp dir, opened read-only, and the copy is deleted before the command returns.
Local Stateis read, never written, and so are the Claude Code configs consulted to name accounts; login tokens are never looked up or printed. - Never a wrong "idle". The running probe answers
running,idle, orunknown; on a platform or file where it cannot tell (Windows, or an unreadableLOCK) it saysunknown, and--running/OnlyRunningexcludeunknownrather than guess. - One bad profile never hides the others. A store that cannot be read (for example a snapshot taken mid-compaction) is reported inline in its own row with an
errorfield; the scan continues. - Stable machine interface.
--jsonemits the sameEntryobjects on every verb; exit codes are0success,1failure or no match,2ambiguous match (candidates on stderr). - No network, no flags, no daemon. Nothing leaves the machine and the browser is never relaunched with
--remote-debugging-port.