Skip to content
vistaclair logo

vistaclair

Agent inspector, control room, and transparent proxy for Claude Code.

npm downloads License Node.js

npx vistaclair

I built this because I wanted to see what Claude Code actually sends to the LLM — the full requests, tool calls, hooks, subagent threads, token counts. The Inspector shows all of it on the wire, in real time, across sessions. From there it grew into a full control surface: multi-tab CLI sessions I can steer from a phone over a tunnel, proxy rules that rewrite or reroute requests to OpenAI/Gemini/DeepSeek/Ollama before they hit the API, and an integrated MCP server for custom tools. I use it daily.

vistaclair.mp4
vistaclair demo

Getting started

Requires: Node.js 18+ and Claude Code CLI (authenticated).

npm install -g vistaclair
vistaclair

Or clone:

git clone https://github.com/hpfrei/vistaclair.git
cd vistaclair && npm install && npm start

Open http://localhost:3457 and log in with the auth token printed to the console.

Tip

Use Claude through the proxy — run this in any terminal to route all traffic through vistaclair:

ANTHROPIC_BASE_URL=http://localhost:3456 claude

Works with interactive sessions, claude -p "prompt", and IDE integrations. Traffic appears in the Inspector.

Tip

Custom port: npm start -- 8080 or DASHBOARD_PORT=8080 npm start

Environment variables

Variable Default Description
AUTH_TOKEN auto-generated Dashboard auth token
PROXY_PORT 3456 API proxy port (localhost only)
DASHBOARD_PORT 3457 Web dashboard port (all interfaces)
ANTHROPIC_TARGET_URL https://api.anthropic.com Upstream API URL
MAX_HISTORY 200 Max interactions kept in memory

Warning

The dashboard binds to 0.0.0.0 for remote access. It is protected by the auth token, but do not expose it to untrusted networks without TLS/VPN.

Supervisor and rescue page

npm start, npm run dev and vistaclair run bin/supervisor.js, which starts server.js as a child process (node server.js still runs unwrapped; server mode, VISTACLAIR_SERVER=1, is never wrapped). The supervisor keeps one auth token for every restart, so the header's Restart button gives you a fresh server process under the same login. Server output is echoed to the terminal and appended to data/logs/server.log under the data home.

If the server cannot come back — it exits during startup, does not answer /api/ping within VISTACLAIR_BOOT_TIMEOUT_MS (default 120 s), crashes 3 times within a minute, or stops answering pings while running for VISTACLAIR_HANG_TIMEOUT_MS (default 180 s) — the supervisor stops it and serves a rescue page on the dashboard port itself: the reason, the log tail, a shell in the browser (your login shell in the install directory; one-command-at-a-time if node-pty is unavailable) and a Retry start button. Fix the problem in the shell (e.g. git revert, npm install) and press Retry; the page switches to the dashboard once it answers.

The rescue page asks for the same credentials as the dashboard: a Telegram session already in your browser, or the auth token — the token only from the host itself once Telegram login is configured. Ctrl-C stops the supervisor and the server.

Claude subscription and terms

vistaclair runs on your own machine with your own Claude credential: each user signs in to Claude Code with their own Claude account, or adds their own Anthropic API key. Usage is under Anthropic's terms — see Use the Claude Agent SDK with your Claude plan and Legal and compliance. vistaclair never reads or stores your Claude login: sign-in runs Claude Code's own claude auth login, and Claude Code's requests pass through the local inspector proxy to Anthropic without vistaclair touching their credentials (the inspector redacts Authorization / x-api-key and does not write request headers to the saved interactions).

Sign in to Claude — the pill in the header shows whether Claude Code is signed in (plan and email, from claude auth status) and opens a sign-in window when it isn't. It runs claude auth login in a small terminal: open the sign-in page it prints, sign in on Anthropic's site, and paste the code it shows if asked. The window also opens by itself when a session's Claude login is refused, so you never need a terminal to sign in again.


What it does

Inspector — Full request/response capture across all sessions. System prompts, message history, tool definitions, tool call inputs/outputs (JSON tree), thinking blocks, SSE event stream, cURL export. Token breakdown (input, output, cache read/create, reasoning) and cost tracking per turn, per group, per session. Subagent tracking with color-coded parallel swimlane view. Hook events nested under the turns that triggered them. All interactions saved to disk as JSON.

CLI — Multi-tab Claude Code terminal in the browser. Per-session model routing, directory spawning, session save/resume. Paste screenshots from clipboard or drag-drop files directly into a session — works over a tunnel from any device. AskUserQuestion appears inline — answer from any browser and Claude continues. Forms can show pictures: options with an image become a thumbnail grid to pick from, and a question's images are shown for the user to comment on (local paths, paths relative to the session's directory, URLs or data URIs; a zoom button opens each one large).

Agent SDK sessions — From the CLI tab's + menu, New CLI in directory… asks for the session type and opens a session or an orchestrator run on the Claude Agent SDK, in an HTML panel. The terminal engine stays as a fallback: the ⚙ menu on the CLI tab strip has Use the terminal engine for new sessions (off by default), for the case where Agent SDK use on subscriptions becomes restricted; open terminal tabs and their resumes keep working either way. The same dialog (also used by Pro's Change app) asks whether to bill it to your Claude subscription (the default) or your Anthropic API key (added on the Models page) when both are set up, and otherwise names the one in use; for an orchestrator, its own model (Opus or Fable, 1M context). A collapsed, off-by-default Route to other models section can send a model family (fable, opus, sonnet, haiku) to any usable model from the Models page, for the whole session or run — orchestrator, workers and subagents — through the proxy; it warns when the target bills per token elsewhere or has a smaller context. A run is drawn as a diagram: the orchestrator box on top, its workers in a row below, joined by lines that flash when they message each other. Each box carries its name, model, state and cost on its border, with the main agent's context use (% of the window, warmer as it nears auto-compaction) beside the Inspector button, and a toggle between Live — its TODO on top and, below a movable divider, its text and the description of each tool call, subagents' included under numbered chips (Explore 1, Explore 2, …) — and its NOTES; the Inspector button opens the full stream with thinking and tool calls. Clicking the model switches the live session to another model, keeping its context and cost. One composer at the bottom takes text and pasted or attached images; on send it asks which session the message is for, then for a confirmation. The orchestrator can start each worker on fable, opus, sonnet or haiku.

Worktree landing — In a git repo, each worker of an orchestrator run works in its own worktree on branch orch/<run>/<worker> and commits there. Its done report lands the branch, by code: rebased onto the base branch recorded at launch, the repo's check run, merged with --no-ff (Merge orch/<run>/<worker>: <summary>). Uncommitted changes, a conflict (rebase aborted, base untouched) or a failing check go back to the worker; the owner's uncommitted changes to files the merge touches stop it with nothing changed. launch_cli takes an optional area (repo-relative paths or globs): an overlap with a running worker's area in the same repo is named in the launch result, and every few minutes a file changed (committed or not) in two live worktrees of one repo becomes one orchestrator event per file and worker pair. Each landing is recorded in the run; the orchestrator's undo_landing reverts one with a new commit. A closed or exited worker's worktree, and end_run's, is removed once its branch is merged and nothing uncommitted is left (git worktree remove and git branch -d, never forced); otherwise it is kept, with the reason and files. A versioned .vistaclair-worktree.json (nearest from the worker's directory up to the repo root) declares gitignored paths to symlink from the main checkout into each worktree and an optional check, e.g. { "links": [".data", "node_modules", ".venv"], "check": "npm test" }; links are relative to the file, recorded in the run, never counted as changes or committed, and unlinked (their targets untouched) at teardown.

Isolated simple CLI — A simple (non-orchestrator) session can opt into the same isolation: "Own git worktree" in the new-CLI directory picker, or isolation: "worktree" on cli:open / openCli. It then works in data/worktrees/cli/<id> on branch cli/<id> from the main checkout's branch (its base), with the declared links. The ⤵ button on its tab, cli:land, or POST /api/cli-isolation/land { tabId | sessId } lands it like a worker (Merge cli/<id>: <title>); the outcome (landed sha, nothing to land, or why not, with the files) is shown as a toast and recorded in the session (GET /api/cli-isolation/status). At close or exit it lands first only with "Land on close" (landOnClose: true, default off); then its worktree goes when merged and clean, else it is kept with the reason. A shutdown keeps every worktree; a landing cut off by a restart has its rebase aborted and is recorded as interrupted. A resumed session whose worktree went gets it back at the same path.

Provider routing — Route through Anthropic, OpenAI, Gemini, xAI (Grok), DeepSeek, Kimi, or Ollama. 40+ models pre-configured. The proxy translates Anthropic Messages API to the target format transparently.

Proxy rules — JavaScript middleware that intercepts every request. Swap models, strip tools, inject prompts, short-circuit responses. Describe in English, vistaclair generates the JS. Hot-reloaded, toggleable.

MCP tools — Define custom tools in the browser with typed parameters and a JS handler. Claude gets the capability instantly. Built-in: vista-AskUserQuestion (routes questions to dashboard UI).

File manager — Browse, preview, and manage files on the remote machine. Monaco editor, multi-select, integrated shell.

Skills, agents, hooks — Create and edit .claude/ skills, agents, and hooks from the dashboard.


Architecture

vistaclair architecture

Two servers, one process:

Server Port Binding Purpose
Proxy :3456 127.0.0.1 Intercepts Claude API calls for inspection and routing
Dashboard :3457 0.0.0.0 Web UI, REST API, WebSocket (auth-protected)

Every claude process gets a unique instance ID in its base URL (http://localhost:3456/i/{id}), so concurrent sessions are fully isolated.

Request flow diagram

License

Apache 2.0 — see LICENSE. Copyright 2026 hpfreilabs.com

Everything above is free and open source. vistaclair Pro adds the Apps Platform as a separately licensed commercial add-on. Learn more →

Releases

Packages

Contributors

Languages