TUI wrapper for Claude Code with hot-swappable API backend support.
Goal: Switch between API providers instantly — configure once, swap with Ctrl+B, no restarts or config edits required.
Only Anthropic API-compatible backends are supported.
- Hot-Swap Backends — Switch providers mid-session with
Ctrl+B - Agent Routing — Route subagents and teammates to separate backends
- Thinking Block Filtering — Automatically filters previous backend's thinking blocks on switch
- Adaptive Thinking Conversion — Converts adaptive thinking for non-Anthropic backends (
thinking_compat) - Model Mapping — Remap model names per backend
- Transparent Proxy — Routes all Claude Code API requests through active backend
- WebUI — Browser-based backend management, no config editing needed
- Debug Logging — Configurable request/response logging
One-line install (recommended):
curl -fsSL https://raw.githubusercontent.com/tonylaysg/anycode/main/install.sh | bashThe installer will:
- Auto-detect your platform (Linux/macOS, x86_64/aarch64)
- Download the prebuilt binary or build from source
- Walk you through WebUI access and password setup
- Add the binary to your PATH
Build from source:
# Requires Rust (https://rustup.rs)
cargo install --path .- Run
anycode— this starts the TUI with Claude Code embedded - Configure backends via WebUI at
http://127.0.0.1:47191 - Press
Ctrl+Bto switch backends at any time
To wrap GitHub Copilot CLI instead of Claude Code, launch via the
anycopilot symlink (created automatically by install.sh):
anycopilot # starts TUI with `copilot` embeddedanycode and anycopilot are the same binary — mode is selected by the
invoked name (argv[0]). They read separate [claude] / [copilot] profiles
from ~/.config/anycode/config.toml.
Copilot BYOK mode (no GitHub login required).
anycopilotinjectsCOPILOT_OFFLINE=trueandCOPILOT_PROVIDER_*env vars so the upstream Copilot CLI bypasses the GitHub OAuth device flow and talks directly to anycode's local proxy. You only need a working backend (DeepSeek, OpenRouter, Anthropic, etc.) — nogh auth login, no Copilot subscription. Pick the wire protocol per backend in the WebUI (wire_api):
anthropic(default) — for Anthropic endpoints or OpenAI-compatible backends that accept the Anthropic/v1/messagesshape.openai— for native OpenAI-compatible backends (/v1/chat/completions). Works with DeepSeek, OpenRouter, LiteLLM, vLLM, Ollama's OpenAI adapter, etc.The proxy also exposes
GET /v1/models(auto-probes/v1/models→/models; override per backend viamodels_path), so Copilot CLI's/modelslash command sees every model the active backend advertises.
anycode Start TUI (Claude Code mode)
anycopilot Start TUI (Copilot CLI mode, via symlink)
anycode --backend <name> Start with specific backend
anycode status Show running instance status
anycode logs [-n 50] [-f] View or follow debug logs
anycode stop Stop running instance
anycode reset Reset cached Claude Code auth state
anycode webui Start WebUI configuration server (foreground)
anycode webui --daemon Start WebUI in background
anycode webui --stop Stop the WebUI daemon
anycode bind [local|lan|public] Change WebUI access mode
anycode passwd Set WebUI login credentials
anycode uninstall Uninstall (keeps config, removes anycopilot symlink)
anycode uninstall --purge Uninstall and remove all config
| Key | Action |
|---|---|
Ctrl+B |
Backend switcher popup |
Ctrl+H |
Backend switch history |
Ctrl+E |
Settings dialog |
Ctrl+R |
Restart Claude Code (preserves session) |
Ctrl+Q |
Quit |
1-9 |
Quick-select backend (in switcher) |
Config file: ~/.config/anycode/config.toml
Minimal:
[defaults]
active = "anthropic"
[[backends]]
name = "anthropic"
display_name = "Anthropic"
base_url = "https://api.anthropic.com"
auth_type = "passthrough"
[[backends]]
name = "alternative"
display_name = "Alternative Provider"
base_url = "https://your-provider.com/api"
auth_type = "bearer"
api_key = "your-api-key"Full example:
[defaults]
active = "anthropic"
timeout_seconds = 300
connect_timeout_seconds = 5
idle_timeout_seconds = 60
[proxy]
bind_addr = "127.0.0.1:47190"
base_url = "http://127.0.0.1:47190"
[webui]
bind_addr = "127.0.0.1:47191"
# username = "admin"
# password = "yourpassword"
[terminal]
scrollback_lines = 10000
[debug_logging]
level = "verbose" # off | basic | verbose | full
destination = "file" # stderr | file | both
file_path = "~/.config/anycode/logs/debug.log"
format = "console" # console | json
[[backends]]
name = "anthropic"
display_name = "Anthropic"
base_url = "https://api.anthropic.com"
auth_type = "passthrough"
[[backends]]
name = "alternative"
display_name = "Alternative Provider"
base_url = "https://your-provider.com/api"
auth_type = "bearer"
api_key = "your-api-key"
thinking_compat = true # Convert adaptive->enabled thinking
thinking_budget_tokens = 10000
model_opus = "custom-opus"
model_sonnet = "custom-sonnet"
model_haiku = "custom-haiku"
[agents]
teammate_backend = "alternative"
subagent_backend = "alternative"Authentication types:
| Type | Header sent | Use case |
|---|---|---|
passthrough |
Forwards original headers | Anthropic OAuth, custom auth |
api_key |
x-api-key: <value> |
Anthropic API key |
bearer |
Authorization: Bearer <value> |
Most third-party providers |
Map Anthropic model families to provider-specific names:
[[backends]]
name = "my-provider"
base_url = "https://api.example.com"
auth_type = "bearer"
api_key = "key"
model_opus = "provider-large" # claude-opus-* -> provider-large
model_sonnet = "provider-medium" # claude-sonnet-* -> provider-medium
model_haiku = "provider-small" # claude-haiku-* -> provider-smallResponses are reverse-mapped so Claude Code always sees consistent model names.
[agents]
teammate_backend = "alternative"
subagent_backend = "alternative"- Main agent uses the active backend (switchable via
Ctrl+B) - Subagents are pinned per-session via CC hooks
- Teammates are routed via tmux shim
Filtering (always active): When switching backends mid-session, thinking blocks from the old backend are automatically removed. Each provider's thinking blocks contain cryptographic signatures that other providers reject.
Conversion (thinking_compat): Claude Code uses adaptive thinking, which non-Anthropic backends don't support. Set thinking_compat = true to convert it to the explicit enabled format:
[[backends]]
name = "alternative"
base_url = "https://your-provider.com/api"
auth_type = "bearer"
api_key = "key"
thinking_compat = true
thinking_budget_tokens = 10000Claude Code 的 TUI 包装器,支持一键热切换 API 后端。
目标: 随时切换 API 服务商,只需配置一次,按 Ctrl+B 切换,无需重启或修改配置文件。
仅支持兼容 Anthropic API 格式的后端。
- 热切换后端 — 按
Ctrl+B即时切换服务商,无需重启 - Agent 路由 — 将子 Agent 和 Teammate 分配到不同后端
- 思考块过滤 — 切换后端时自动过滤旧后端的 thinking block
- Adaptive Thinking 转换 — 非 Anthropic 后端自动转换 thinking 格式(
thinking_compat) - 模型名映射 — 每个后端可独立配置模型名映射
- 透明代理 — 所有 API 请求自动路由到当前后端
- WebUI 管理界面 — 浏览器在线管理后端配置,无需手动编辑文件
- 调试日志 — 可配置详细程度的请求/响应日志
一键安装(推荐):
curl -fsSL https://raw.githubusercontent.com/tonylaysg/anycode/main/install.sh | bash安装程序会自动:
- 检测系统平台(Linux/macOS,x86_64/aarch64)
- 下载预编译二进制包(若不可用则从源码编译)
- 引导配置 WebUI 访问权限及账号密码
- 自动将二进制文件添加到 PATH
从源码编译:
# 需要 Rust (https://rustup.rs)
cargo install --path .- 运行
anycode— 启动 TUI,内嵌 Claude Code - 访问
http://127.0.0.1:47191通过 WebUI 配置后端 - 随时按
Ctrl+B切换后端
若想让 anycode 包装 GitHub Copilot CLI 而非 Claude Code,请通过
install.sh 自动创建的 anycopilot 符号链接启动:
anycopilot # 启动 TUI,内嵌 `copilot`anycode 和 anycopilot 是同一个二进制,根据调用名(argv[0])选择模式,
分别读取 ~/.config/anycode/config.toml 中的 [claude] / [copilot] 两个独立配置段。
Copilot BYOK 模式(无需 GitHub 登录)。
anycopilot启动时注入COPILOT_OFFLINE=true和COPILOT_PROVIDER_*一组环境变量,让上游的 Copilot CLI 跳过 GitHub OAuth 设备授权流程,直接与本地 anycode 代理通信。 你只需要一个可用的后端(DeepSeek、OpenRouter、Anthropic 等),完全不 需要执行gh auth login,也不需要 Copilot 订阅。在 WebUI 中按后端 选择wire_api:
anthropic(默认)—— Anthropic 官方端点,或能接受 Anthropic/v1/messages形态的 OpenAI 兼容后端。openai—— 原生 OpenAI 兼容后端(/v1/chat/completions)。DeepSeek、 OpenRouter、LiteLLM、vLLM、Ollama 的 OpenAI 适配器等均可。代理同时暴露
GET /v1/models(自动探测/v1/models→/models, 可用models_path指定自定义路径),这样 Copilot CLI 的/model斜杠命令就能看到后端公开的全部模型。
anycode 启动 TUI(Claude Code 模式)
anycopilot 启动 TUI(Copilot CLI 模式,符号链接)
anycode --backend <名称> 指定初始后端启动
anycode status 查看运行状态
anycode logs [-n 50] [-f] 查看 / 实时追踪日志
anycode stop 停止运行中的实例
anycode reset 重置 Claude Code 认证缓存
anycode webui 启动 WebUI 配置服务(前台)
anycode webui --daemon 后台模式启动 WebUI
anycode webui --stop 停止后台 WebUI 守护进程
anycode bind [local|lan|public] 更改 WebUI 访问模式
anycode passwd 设置 WebUI 登录密码
anycode uninstall 卸载(保留配置文件,同时移除 anycopilot 符号链接)
anycode uninstall --purge 完全卸载(含配置文件)
| 快捷键 | 功能 |
|---|---|
Ctrl+B |
打开后端切换弹窗 |
Ctrl+H |
查看后端切换历史 |
Ctrl+E |
打开设置对话框 |
Ctrl+R |
重启 Claude Code(保留会话) |
Ctrl+Q |
退出 |
1-9 |
在切换弹窗中快速选择后端 |
配置文件位置:~/.config/anycode/config.toml
最简配置:
[defaults]
active = "anthropic"
[[backends]]
name = "anthropic"
display_name = "Anthropic(官方)"
base_url = "https://api.anthropic.com"
auth_type = "passthrough"
[[backends]]
name = "alternative"
display_name = "其他服务商"
base_url = "https://your-provider.com/api"
auth_type = "bearer"
api_key = "your-api-key"完整配置示例:
[defaults]
active = "anthropic"
timeout_seconds = 300
connect_timeout_seconds = 5
idle_timeout_seconds = 60
[proxy]
bind_addr = "127.0.0.1:47190"
base_url = "http://127.0.0.1:47190"
[webui]
bind_addr = "127.0.0.1:47191"
# username = "admin"
# password = "yourpassword"
[terminal]
scrollback_lines = 10000
[debug_logging]
level = "verbose" # off | basic | verbose | full
destination = "file" # stderr | file | both
file_path = "~/.config/anycode/logs/debug.log"
format = "console" # console | json
[[backends]]
name = "anthropic"
display_name = "Anthropic(官方)"
base_url = "https://api.anthropic.com"
auth_type = "passthrough"
[[backends]]
name = "alternative"
display_name = "其他服务商"
base_url = "https://your-provider.com/api"
auth_type = "bearer"
api_key = "your-api-key"
thinking_compat = true # 转换 adaptive thinking 格式
thinking_budget_tokens = 10000
model_opus = "custom-opus"
model_sonnet = "custom-sonnet"
model_haiku = "custom-haiku"
[agents]
teammate_backend = "alternative"
subagent_backend = "alternative"认证类型说明:
| 类型 | 发送的 Header | 适用场景 |
|---|---|---|
passthrough |
透传原始 Header | Anthropic OAuth、自定义认证 |
api_key |
x-api-key: <value> |
Anthropic API Key |
bearer |
Authorization: Bearer <value> |
大多数第三方服务商 |
将 Anthropic 模型族名映射到服务商自定义名称:
[[backends]]
name = "my-provider"
base_url = "https://api.example.com"
auth_type = "bearer"
api_key = "key"
model_opus = "provider-large" # claude-opus-* -> provider-large
model_sonnet = "provider-medium" # claude-sonnet-* -> provider-medium
model_haiku = "provider-small" # claude-haiku-* -> provider-small响应中会自动反向映射,Claude Code 始终看到一致的模型名。
[agents]
teammate_backend = "alternative"
subagent_backend = "alternative"- 主 Agent 使用当前活跃后端(可通过
Ctrl+B切换) - 子 Agent 通过 CC hooks 按会话绑定到指定后端
- Teammate Agent 通过 tmux shim 路由
过滤(始终启用): 切换后端时,上一个后端产生的 thinking block 会被自动过滤。每个服务商的 thinking block 包含加密签名,换到其他服务商后会导致 400 错误。
格式转换(thinking_compat): Claude Code 使用 adaptive thinking 格式,非 Anthropic 后端不支持。设置 thinking_compat = true 可自动转换为 enabled 格式:
[[backends]]
name = "alternative"
base_url = "https://your-provider.com/api"
auth_type = "bearer"
api_key = "key"
thinking_compat = true
thinking_budget_tokens = 10000Apache 2.0