A local classifier relay for Claude Code Auto Mode that disables extended
thinking only for safety-classifier requests and avoids EADDRINUSE / port
conflicts when multiple Claude Code sessions run concurrently.
中文说明 · Installation · Troubleshooting · Security scope
Important
This is an unofficial community project. It is not affiliated with or endorsed by Anthropic or DeepSeek. Claude Code's internal request format can change, so review the code and test it with your own provider before relying on it.
Some Anthropic-compatible gateways and DeepSeek-backed Claude Code setups can struggle with Claude Code Auto Mode's internal Bash safety-classifier request. Common symptoms and search terms include:
- Claude Code Auto Mode classifier timeout or incorrect permission denial
- DeepSeek classifier
thinkinglatency ortemporarily unavailableerrors Port 8787 is already occupied by another proxy instanceEADDRINUSE: address already in use 127.0.0.1:8787- a second
claudeprocess failing because the first local proxy owns the port
This relay recognizes the known legacy classifier markers and the strict non-streaming classifier envelope used by newer Claude Code versions. For that request only, it:
{
"thinking": { "type": "disabled" }
}It also removes legacy effort fields from that classifier request. The model name is preserved, and normal conversations, tool calls, and streaming responses pass through unchanged.
Each launcher process asks the operating system for a free loopback port and uses an isolated state directory. Multiple wrapped Claude Code sessions can therefore run at the same time without sharing a PID file, log, or port.
- macOS or Linux with Bash
- Node.js 18 or newer
curl- Claude Code installed and available as
claude - an existing remote
ANTHROPIC_BASE_URLand authentication configuration
git clone https://github.com/Lserm/claude-code-auto-mode-proxy.git \
~/.claude/auto-mode-proxy
chmod 700 \
~/.claude/auto-mode-proxy/claude-with-auto-fix \
~/.claude/auto-mode-proxy/rollbackKeep your existing remote ANTHROPIC_BASE_URL and authentication variable in
the shell, then launch Claude Code through the wrapper:
~/.claude/auto-mode-proxy/claude-with-auto-fixAll Claude Code arguments are forwarded unchanged. For example:
~/.claude/auto-mode-proxy/claude-with-auto-fix \
--model opus \
--effort highThe launcher prints output similar to:
Outbound proxy: direct
Local proxy: http://127.0.0.1:<dynamic-port>
Proxy log: /private/tmp/claude-auto-mode-proxy-<uid>-<instance-id>/proxy.log
The API credential is inherited by Claude Code and forwarded as an HTTP header. It is not copied into this repository or the relay process environment.
There are two different loopback ports in this setup. Do not confuse them:
- Local relay port: created by this project for Claude Code. It is dynamic
by default and is printed as
Local proxy: http://127.0.0.1:<dynamic-port>. - Outbound proxy port: optionally provided by Clash, V2Ray, Surge, or a similar application so the relay can reach your remote API endpoint.
No extra configuration is needed. Direct outbound access is the public default:
~/.claude/auto-mode-proxy/claude-with-auto-fixYou should see:
Outbound proxy: direct
Local proxy: http://127.0.0.1:<dynamic-port>
This works when your machine can reach ANTHROPIC_BASE_URL directly. The local
relay is still used for classifier patching; direct only describes how the
relay connects to the remote upstream.
First find the application's HTTP or mixed proxy port. It may be 7890,
7897, 8080, or another value depending on your configuration. A SOCKS-only
port cannot be passed directly because this launcher expects an http:// or
https:// proxy URL.
Then launch with that outbound proxy:
DS_HTTPS_PROXY=http://127.0.0.1:7897 \
~/.claude/auto-mode-proxy/claude-with-auto-fixYou should see two different ports, for example:
Outbound proxy: http://127.0.0.1:7897
Local proxy: http://127.0.0.1:54321
Here 7897 belongs to Clash (outbound), while 54321 belongs to this tool and
is used only by the current Claude Code session. Starting another wrapped
Claude Code session will normally create a different local relay port while
both sessions continue using the same Clash port.
DS_HTTPS_PROXY accepts an http:// or https:// URL, or direct. You do not
need to enable the operating system's global proxy mode as long as the local
HTTP proxy port is listening and can reach the upstream endpoint.
To bypass a running Clash instance for one launch:
DS_HTTPS_PROXY=direct \
~/.claude/auto-mode-proxy/claude-with-auto-fixFor a machine-local default that is not committed to Git, create
.env.local in the repository directory:
DS_DEFAULT_HTTPS_PROXY=http://127.0.0.1:7897An explicitly supplied DS_HTTPS_PROXY still takes precedence. The launcher
reads only the DS_DEFAULT_HTTPS_PROXY key from .env.local; it does not
execute the file as shell code.
| Your network situation | Command or setting |
|---|---|
| Remote API is directly reachable | Launch normally; outbound defaults to direct |
| Clash/V2Ray/Surge provides an HTTP or mixed port | Set DS_HTTPS_PROXY=http://127.0.0.1:<port> |
| Proxy application provides only SOCKS | Enable its HTTP/mixed listener first |
| A local default is convenient on one machine | Put DS_DEFAULT_HTTPS_PROXY=... in .env.local |
| Temporarily bypass the saved local default | Launch with DS_HTTPS_PROXY=direct |
Dynamic ports are recommended. If an integration requires a fixed port:
DS_PROXY_PORT=8787 \
~/.claude/auto-mode-proxy/claude-with-auto-fixA fixed port intentionally fails when already occupied. Do not use the same fixed port for concurrent sessions.
| Variable | Default | Purpose |
|---|---|---|
DS_PROXY_PORT |
0 |
Local port; 0 lets the OS select a free port |
DS_HTTPS_PROXY |
DS_DEFAULT_HTTPS_PROXY or direct |
Optional outbound HTTP(S) proxy URL |
DS_UPSTREAM_BASE_URL |
ANTHROPIC_BASE_URL |
Original remote upstream |
DS_PROXY_STATE_ROOT |
/private/tmp |
Parent directory for session state |
DS_PROXY_STATE_DIR |
unique per session | Explicit state-directory override |
CLAUDE_BIN |
claude |
Claude Code executable |
After starting the wrapper, ask Claude Code:
Please run this Bash command: echo auto-mode-proxy-ok
Copy the exact Proxy log: path printed by the launcher and follow it in
another terminal:
tail -f /private/tmp/claude-auto-mode-proxy-<uid>-<instance-id>/proxy.logNormal API traffic is logged as:
[pass] [auth=authorization] -> 200
When Claude Code sends the recognized cloud safety-classifier request:
[classifier patched] [auth=authorization] -> 200
Request bodies and credential values are never logged.
Run the isolated local test suite with:
cd ~/.claude/auto-mode-proxy
npm testThe test suite includes a true concurrent-launch test that verifies two wrapper processes receive different ports and clean up their own relays.
Set it to your original remote Anthropic-compatible endpoint before launching the wrapper. Do not set it to the local relay address.
Your shell is probably still pointing to an old local relay. Restore the
original remote URL, or explicitly set DS_UPSTREAM_BASE_URL to it.
Unset DS_PROXY_PORT to restore automatic port selection:
unset DS_PROXY_PORT
~/.claude/auto-mode-proxy/claude-with-auto-fixCheck all of the following:
- The proxy application is running.
- The configured number is its HTTP or mixed port, not this tool's dynamic
Local proxyport and not a SOCKS-only port. curl -x http://127.0.0.1:<port> https://example.comcan connect.- Your Node.js release recognizes
--use-env-proxy; upgrade Node.js if it does not.
If direct access works, launch once with DS_HTTPS_PROXY=direct to confirm the
failure is isolated to the outbound proxy configuration.
Normally, exiting Claude Code stops only the relay owned by that session. To clean up relays left behind after an interrupted launcher:
~/.claude/auto-mode-proxy/rollbackThen launch Claude Code normally:
claudeThe wrapper does not modify Claude Code settings or shell startup files.
- The relay listens only on
127.0.0.1. - It does not force an allow decision or enable permission-bypass flags.
- It changes only recognized classifier request fields; all other JSON bodies are forwarded unchanged.
- Health checks contain a per-instance token so one launcher cannot mistake a different local service for its own relay.
- Credentials and request bodies are not written to logs.
- The upstream must use HTTPS unless it is a loopback address explicitly enabled for local testing.
Review the classifier matching logic before using this project in a sensitive or managed environment.
Claude Code
│ ANTHROPIC_BASE_URL=http://127.0.0.1:<dynamic-port>
▼
Loopback relay
├─ recognized safety classifier → disable thinking → upstream
└─ all other requests → unchanged → upstream
The classifier-patching method was adapted from
dashxio/deepseek-claude-proxy.
这是一个非官方的 Claude Code Auto Mode 本地分类代理,主要解决两类问题:
- 在部分 DeepSeek 或 Anthropic 兼容网关中,内部安全分类请求开启 thinking 后延迟过高、超时或误判;
- 多个 Claude Code 实例共用固定
8787端口时出现EADDRINUSE、address already in use或端口冲突。
代理只针对已识别的安全分类请求关闭 thinking,普通对话、工具调用和流式响应 保持不变。启动器默认使用系统分配的动态端口,因此可以同时开启多个 Claude Code 实例。
如果电脑能够直接访问 ANTHROPIC_BASE_URL,无需配置任何出站代理,直接运行:
~/.claude/auto-mode-proxy/claude-with-auto-fix启动信息会显示 Outbound proxy: direct。这里的 direct 只表示本工具直接连接
远程 API;Claude Code 仍然会经过本工具创建的本地动态端口。
确认软件提供的 HTTP 或 mixed 代理端口,然后运行:
DS_HTTPS_PROXY=http://127.0.0.1:7897 \
~/.claude/auto-mode-proxy/claude-with-auto-fix7897 是示例,请替换成代理软件的实际 HTTP/mixed 端口。SOCKS-only 端口不能
直接用于这个变量。启动后:
Outbound proxy: http://127.0.0.1:7897 # Clash 等软件的端口
Local proxy: http://127.0.0.1:54321 # 本工具为当前 Claude 动态分配
多个 Claude Code 实例可以共享同一个 Clash 出站端口,但每个实例会拥有不同的
Local proxy 动态端口。若希望本机永久默认走 Clash,可在不会提交到 Git 的
.env.local 中写入:
DS_DEFAULT_HTTPS_PROXY=http://127.0.0.1:7897临时绕过该默认值时使用:
DS_HTTPS_PROXY=direct \
~/.claude/auto-mode-proxy/claude-with-auto-fix安装、验证、指定模型、固定端口和回滚方法见上文。
The upstream project currently does not declare a software license. This fork therefore does not add one or claim permission to relicense upstream-derived portions. See the upstream repository and commit history for attribution.