A lightweight, self-hosted web chat interface for Claude Code CLI, accessible over LAN.
一个轻量级的自托管 Web 聊天界面,基于 Claude Code CLI,支持局域网访问。
- Multi-turn conversation / 连续对话 — session persistence via
--resume - Real-time streaming / 实时流式输出 — SSE-based streaming with de-duplication
- File upload & download / 文件上传下载 — drag & drop or click to attach files
- Tool call display / 工具调用展示 — shows when Claude uses Bash, Read, Write, etc.
- Dark mode / 深色模式 — toggle with localStorage persistence
- Token auth / Token 认证 — optional
AUTH_TOKENfor LAN security - Systemd service / 系统服务 — auto-start on boot with
claude-web.service - Mobile friendly / 移动端适配 — responsive design
The UI is inspired by claude.ai with a warm cream color palette.
界面参考 claude.ai 设计,使用暖色调配色方案。
- Node.js 18+
- Claude Code CLI installed and authenticated Claude Code CLI 已安装并完成认证
npm install -g @anthropic-ai/claude-code
claude # First run: authenticate and accept permissions
# 首次运行:完成认证并接受权限提示git clone https://github.com/sunthinks/claude-code-web.git
cd claude-code-webnpm install# No auth (local/trusted network)
# 无认证(本地或可信网络)
HOST=0.0.0.0 PORT=8080 node server.mjs
# With auth token (recommended for LAN)
# 带认证(推荐用于局域网)
AUTH_TOKEN=your-secret HOST=0.0.0.0 PORT=8080 node server.mjsOpen in browser / 浏览器打开:
http://<your-server-ip>:8080
http://<your-server-ip>:8080?token=your-secret # if AUTH_TOKEN is set
chmod +x install.sh
./install.shThis will install dependencies, set up a systemd service, and start the server automatically on boot.
将自动安装依赖、配置 systemd 服务,并设置开机自启。
| Environment Variable | Default | Description |
|---|---|---|
PORT |
8080 |
Server port / 服务端口 |
HOST |
0.0.0.0 |
Bind address / 绑定地址 |
AUTH_TOKEN |
(empty) | Auth token, empty = no auth / 认证令牌,留空则不启用 |
CLAUDE_PATH |
(auto-detect) | Path to claude CLI binary / Claude CLI 路径 |
Send a message and receive streaming response via SSE. 发送消息并通过 SSE 接收流式响应。
Request body:
{
"message": "Hello",
"sessionId": "optional-session-id",
"files": [{"id": "file-id", "path": "/path/to/file"}]
}SSE events:
| Event type | Description |
|---|---|
meta |
Request ID for cancellation / 请求 ID,用于取消 |
text |
Streamed text chunk / 流式文本片段 |
tool |
Tool invocation (Bash, Read, etc.) / 工具调用 |
session |
Session ID for multi-turn / 会话 ID,用于连续对话 |
error |
Error message / 错误信息 |
done |
Stream complete / 流结束 |
Cancel an ongoing request. / 取消正在进行的请求。
{ "reqId": "request-id" }Upload files (multipart/form-data, field: files, max 50MB per file, max 10 files).
上传文件(multipart/form-data,字段名 files,单文件最大 50MB,最多 10 个)。
List all uploaded/downloaded files. / 列出所有文件。
Download a file. / 下载文件。
Delete a file. / 删除文件。
Health check. / 健康检查。
Quick test — sends "say hi" to Claude and returns the response. 快速测试 — 发送 "say hi" 给 Claude 并返回响应。
Browser ──SSE──▶ Express (server.mjs) ──spawn──▶ claude -p --output-format stream-json
│ │
│ POST /api/chat │ --resume <sessionId>
│ POST /api/upload │ --dangerously-skip-permissions
│ GET /api/files/:name │
▼ ▼
index.html Claude Code CLI
- Backend: Express.js +
child_process.spawncallingclaudeCLI - Frontend: Single-file HTML with vanilla JS, no build step
- Streaming:
stream-jsonoutput parsed line-by-line, sent as SSE to browser - Session: First response includes
session_id; subsequent requests use--resumeto maintain context - De-duplication:
stream-jsonsends text viatext_delta, then repeats inassistant/resultevents. A per-requestctx.streamedflag suppresses duplicates.
Claude tool execution fails (Bash sandbox error) Claude 工具执行失败(Bash 沙箱错误)
If using systemd, make sure the service file does NOT have ProtectSystem=strict or PrivateTmp=true, as Claude Code needs /tmp access for its sandbox.
如果使用 systemd,确保服务文件中没有 ProtectSystem=strict 或 PrivateTmp=true,因为 Claude Code 需要 /tmp 访问权限。
No continuous conversation 无法连续对话
Make sure the frontend correctly saves the sessionId from the session SSE event and sends it back in subsequent requests.
确保前端正确保存了 session SSE 事件中的 sessionId 并在后续请求中传回。
Permission prompt in non-interactive mode 非交互模式下出现权限提示
Run claude once in terminal and accept the --dangerously-skip-permissions disclaimer before using the web interface.
在使用 Web 界面之前,先在终端运行一次 claude 并接受 --dangerously-skip-permissions 免责声明。
MIT