cc-viewer
v1.7.8
Published
Claude Code logging, visualization, and management toolkit — launch a web viewer alongside Claude Code with full request/response tracing, proxy, and mobile support
Downloads
118,146
Maintainers
Readme
CC-Viewer
🌐 Website & feature tour: weiesky.github.io/cc-viewer — available in 18 languages (e.g. 简体中文, 日本語).
Based on Claude Code, a Vibe Coding tool that distills and accumulates real development experience:
English | 简体中文 | 繁體中文 | 한국어 | 日本語 | Deutsch | Español | Français | Italiano | Dansk | Polski | Русский | العربية | Norsk | Português (Brasil) | ไทย | Türkçe | Українська
Usage
Prerequisites
- Make sure nodejs 20.0.0+ is installed; Download and install
- Make sure claude code is installed; Installation guide
Install ccv
Install via npm
npm install -g cc-viewer --registry=https://registry.npmjs.orgInstall via Homebrew (recommended for macOS / Linux)
brew tap weiesky/cc-viewer
brew install cc-viewer
brew upgrade cc-viewer # use this to upgrade; do NOT use npm install -g to upgrade a brew-installed ccvHow to start
ccv is a drop-in replacement for claude — all arguments are passed through to claude while the Web Viewer is launched alongside it.
ccv # == claude (interactive mode)The command I use most often is:
ccv -c --d # == claude --continue --dangerously-skip-permissions
# ccv passes through every Claude Code launch argument — feel free to combine them however you likeOnce started in programming mode, the web page opens automatically.
cc-viewer also ships as a native desktop app: download page
Choose the Claude executable
On the local CCV page, open Global Settings → Claude executable to choose the
Claude Code installation used by CLI, ccv run -- claude, and the desktop app.
CCV suggests executables found in CodeFuse, PATH, npm, and common native-install
locations. You may also enter an absolute path (or a ~/... path). The selection
is saved as claudeExecutablePath in ~/.claude/cc-viewer/preferences.json and
takes effect on the next launch.
An explicit selection is authoritative: if it is later missing or not executable,
CCV stops with an error instead of silently launching another version. Clear the
field to restore automatic discovery. For headless setup, write the same absolute
path to claudeExecutablePath manually. Executable selection is a machine-local
admin setting and is not exposed to LAN clients. CCV disables Claude Code's
self-updater for processes it launches, so upgrades remain under the control of
the selected installation or its package manager.
Upgrading to 1.7.0 (log format v2)
Since 1.7.0, logs are stored in a per-session directory format (wire-format v2) instead of single .jsonl files — roughly 90% smaller on disk. Existing v1 .jsonl files are never modified or deleted; the log dialog lists v2 sessions by default, and a small “View legacy (v1) logs” entry (shown while old files exist) opens a v1 view where they can be viewed, migrated, or deleted. On startup, cc-viewer offers one-click migration when legacy logs are found (strongly recommended when continuing an old conversation with claude -c, whose first half lives in the old files). You can also migrate from the terminal:
ccv convert <project> # migrate one project
ccv convert --all # migrate every project
ccv verify <v1-file> # check a v1 file against its converted sessionsA session that fails golden verification is held in sessions-quarantine/ for inspection instead of failing the whole migration — the other sessions still migrate.
Logger mode
If you still prefer the native claude tool or the VS Code extension, use this mode.
In this mode, launching claude will automatically start a logging process that records request logs to per-session directories under ~/.claude/cc-viewer/yourproject/sessions/ (wire-format v2)
Enable logger mode:
ccv -loggerWhen the console cannot print a specific port, the default first port is 127.0.0.1:7008. If multiple instances exist, ports increment sequentially — 7009, 7010, and so on.
Uninstall logger mode:
ccv --uninstallTroubleshooting
If you run into start-up issues, here's the ultimate troubleshooting recipe: Step 1: Open Claude Code in any directory; Step 2: Give Claude Code the following instruction:
I have installed the cc-viewer npm package, but running ccv still doesn't work properly. Check cc-viewer's cli.js and findcc.js and adapt them to the local Claude Code deployment based on the specific environment. Keep the scope of changes confined to findcc.js as much as possible.Letting Claude Code diagnose the problem on its own is more effective than asking anyone or reading any documentation!
Once the instruction is done, findcc.js will have been updated. If your project frequently needs local deployment, or your forked code often runs into installation issues, just keep this file — next time you can simply copy it over. At this stage many projects and companies use Claude Code on server-side hosted deployments rather than on Mac, so I split out findcc.js to make it easier to keep tracking upstream cc-viewer source updates.
Note: this app conflicts with claude-code-switch and claude-code-router — there is a proxy contention problem, so make sure you turn off claude-code-switch and claude-code-router when using it. cc-viewer provides built-in proxy hot-reload that can replace them.
Other helper commands
See:
ccv -hSilent Mode
By default, ccv runs in silent mode when wrapping claude, keeping your terminal output clean and consistent with the native experience. All logs are captured in the background and can be viewed at http://localhost:7008.
Once configured, just use the claude command as usual. Visit http://localhost:7008 to open the monitoring UI.
Features
Programming mode
After launching with ccv you'll see:
You can view the code diff directly right after an edit:
While you can open files and code by hand, that's not recommended — that's the old-school way!
Code search
The activity bar includes a VS Code-style Search across files view (the magnifier icon, next to File Explorer and Git). Type a keyword or regular expression and get matches grouped by file with the matched text highlighted; click a result to jump straight to that line with the match selected. The usual toggles are there — Match Case, Match Whole Word, Use Regular Expression, and a "…" expander for files to include / exclude globs. Search is scoped to the current project and honors .gitignore (it uses ripgrep when it's installed for speed, and falls back to a built-in scanner otherwise, so there's nothing extra to install).
You can also replace across files: expand the replace row (the chevron next to the search box), and each match shows an inline before/after preview. Replace a single match, all matches in one file, or everywhere (replace-all asks for confirmation first). Regex mode supports $1/$& capture-group substitution. Replacements write directly to disk — files with unsaved edits open in the viewer are skipped, and there's no built-in undo, so lean on version control to revert.
Mobile programming
You can even scan a QR code and code from a mobile device:
Everything you imagined about mobile coding — plus a plugin mechanism: if you need to customize for your own coding habits, stay tuned for plugin hook updates.
Password protection
By default, remote (LAN) access requires the ?token= query that ccv prints at startup. As an alternative that's friendlier to share, scan, or bookmark, you can turn on password login:
- Start with
ccv --usePasswordto enable it immediately. A bare flag auto-generates a 6-character password (uppercase letters + digits) and prints it to the console;ccv --usePassword=<your-password>sets a specific one. The password is shown in uppercase but matched case-insensitively at login, so it's easy to type on a phone. - The machine that opens ccv on
127.0.0.1is the admin: it never needs a password and is the only one allowed to view or change it. Open the QR-code popover — directly below the QR you can enable protection, edit/copy the password, or turn it back off. - Remote devices opening the LAN URL (without a token) are shown a minimal password page; entering the correct password sets an
HttpOnlycookie and the page refreshes into the app. The existing?token=URL keeps working in parallel. - An empty password means no protection at all — it is allowed, but the admin UI shows a clear security warning.
- Global default + per-project override: by default one password covers every project. From the QR popover the admin can switch between This project and Global — set a project-specific password that overrides the global default for that project only, or remove the override to inherit the global setting again. (A disabled project override means "no protection for this project", which is different from removing it.)
- The on/off state and password(s) are persisted alongside your other settings in cc-viewer's
preferences.json— a globalauthkey plus an optionalauthByProjectmap (the password is base64-obfuscated, not stored as raw plaintext; file mode0600). The login cookie is tied to the per-launch token, so restarting ccv requires remote devices to log in again.
Model-specific system prompts
The Edit System Prompt modal (hamburger menu → Edit System Prompt) is tabbed:
- The Default tab keeps the classic behavior: it writes
CC_SYSTEM.md(override) orCC_APPEND_SYSTEM.md(append) into the current workspace, injected as--system-prompt-file/--append-system-prompt-fileon the next ccv launch. - Model tabs: click + Add model, type a name such as
opusorGemini3, and pick a scope — Global (~/.claude/cc-viewer/system_prompt/, applies to every workspace) or Workspace (<project>/system_prompt/). Each tab has its own Append/Override switch and Markdown preview. - Entries are stored as uppercase files:
OPUS_SYSTEM.md(override) orOPUS_APPEND_SYSTEM.md(append). Matching is fuzzy — a case-insensitive substring of the model ID resolved from the ACTIVE configuration (an active third-party proxy profile's model mapping > the launch environment'sANTHROPIC_MODEL/CLAUDE_MODEL> themodelconfigured insettings.json; with no configuration signal, no entry is injected), soopusmatchesclaude-opus-4-8[1m]regardless of version. Switching the proxy profile mid-session re-matches only after the claude session is restarted, and a--modelflag passed through extra args is not consulted (known limitations). A workspace match beats a global one; within a scope the longest name wins; a matched entry fully replaces the Default files for that launch. - Saving a tab empty deletes the entry. Model switches made mid-session apply at the next relaunch. Set
CCV_DISABLE_AUTO_SYSTEM_PROMPT=1to disable all automatic injection. You may commit<project>/system_prompt/to share prompts with your team, or add it to.gitignoreto keep them private.
Logger mode (view the complete Claude Code session)
- Captures every API request from Claude Code in real time, guaranteeing the raw payload rather than a censored log (this matters a lot!!!)
- Automatically identifies and labels Main Agent and Sub Agent requests (subtypes: Plan, Search, Bash)
- MainAgent requests support Body Diff JSON, showing only the diff against the previous MainAgent request (only changed/added fields) in a collapsed view
- Each request inlines Token usage stats (input/output tokens, cache creation/read, hit rate)
- Compatible with Claude Code Router (CCR) and other proxy scenarios — falls back to matching requests by API path pattern
Star History
License
MIT
