A web UI for Claude Code that replaces default terminal prompts with a browser-based interface. Approve/deny tool calls, submit prompts, upload images, manage sessions, and export conversations from any browser or Feishu.
Transcript-driven, cross-platform (Tmux on Linux/macOS, Windows Terminal on Windows), 3 Python hooks.
- All session state is derived from Claude Code's transcript JSONL files — the server doesn't maintain a state machine
- Prompts are delivered via platform-native mechanisms (
tmux send-keyson Linux/macOS,WriteConsoleInputon Windows) — no file polling for prompt submission - Only 3 hook scripts (all Python, no external dependencies like jq or curl)
Permission approval flow:
Claude Code Web browser
| |
|-- PermissionRequest hook ------> |
| (hook-permission-request.py) |
| writes .request.json to |
| /tmp/claude-webui/ |
| |
| server.py |
| reads transcript JSONL |
| derives session state |
| serves dashboard ----> | User sees request
| | clicks Allow / Deny
| writes .response.json <--|
| |
|<-- hook reads response |
| (allow or deny) |
Prompt submission flow:
Claude Code Web browser
| |
| server.py |
| shows session dashboard |
| with prompt input ----> | User types prompt
| | clicks Send
| |
|<-- prompt delivered via |
| tmux send-keys (Linux/macOS) |
| or WriteConsoleInput (Windows) |
server.py— Python HTTP server (port 19836). Session registry, transcript parser, multi-session dashboard.hook-permission-request.py—PermissionRequesthook. Auto-allow check, writes.request.json, polls for.response.json.hook-session-start.py—SessionStarthook. Registers session with server (transcript path, tmux/console info, cwd).hook-session-end.py—SessionEndhook. Deregisters session, cleans up files.platform_utils.py— Cross-platform utilities. OS detection, temp directory paths, process tree walking.win_send_keys.py— Windows console input helper. Injects keyboard input viaWriteConsoleInputW.channel_feishu.py— Optional Feishu (Lark) notification channel.install.sh/uninstall.sh— Hook installation scripts (Linux/macOS).install.ps1/uninstall.ps1— Windows equivalents (PowerShell).
- Multi-session dashboard — see all active Claude Code sessions at a glance
- Transcript-derived state — idle, working, needs approval, question, plan review
- Allow / Deny — approve or reject individual tool calls
- Always Allow — approve and add pattern to
settings.local.json - Allow Path — for Write/Edit tools, allow all operations under a directory
- Split Always Allow — compound Bash commands split into individual patterns
- Session-level auto-allow — auto-approve specific tools for a session
- Prompt submission — send follow-up prompts from the dashboard (via tmux on Linux/macOS, console input on Windows)
- AskUserQuestion support — answer Claude's questions with option selection or custom text
- Plan review — approve, deny, or provide feedback on plans
- Image upload — attach images in the prompt area
- Feishu integration — optional notification channel for mobile approval
- Graceful fallback — hooks auto-approve when server is offline
- Auto-cleanup — zombie sessions (dead PIDs) cleaned up automatically
- Dark-themed, mobile-friendly UI
Linux/macOS:
- Python 3
- tmux (required for prompt delivery)
- Bash,
jq(for install/uninstall scripts)
Windows:
- Python 3
- PowerShell 5.1+ (for install/uninstall scripts)
-
Clone this repo:
git clone https://github.com/gooooloo/claude-code-webui.git
-
Start the server:
/path/to/claude-code-webui/server.py
-
Install the hooks:
Linux/macOS:
# For a single project (run from project directory): /path/to/claude-code-webui/install.sh --project # Or install globally (all projects): /path/to/claude-code-webui/install.sh --global # Or both: /path/to/claude-code-webui/install.sh --all
Windows (PowerShell):
# For a single project: \path\to\claude-code-webui\install.ps1 -Scope Project # Or install globally: \path\to\claude-code-webui\install.ps1 -Scope Global # Or both: \path\to\claude-code-webui\install.ps1 -Scope All
-
Restart Claude Code if it's already running — hooks are loaded at startup.
-
Open
http://localhost:19836in your browser (or use your machine's LAN IP from a phone/tablet). -
Run Claude Code — on Linux/macOS run it inside tmux; on Windows run it in Windows Terminal. The dashboard will show your sessions and let you interact.
Windows limitation: Prompt delivery uses
AttachConsole/WriteConsoleInputW, which does not support Windows Terminal split panes. If you split a window into multiple panes, prompts may be delivered to the wrong pane or fail entirely. Use one Claude Code session per window (multiple windows are fine).
The server binds to 127.0.0.1:19836 by default (local access only). To allow LAN access (e.g. approve requests from a phone or another device), use --lan:
python3 server.py --lanThis binds to 0.0.0.0:19836, making it accessible from your local network.
There is no authentication on the web UI. Anyone on your network who can reach port 19836 can approve or deny requests. Use on trusted networks only, or add your own auth layer.
MIT