Transparent TLS proxy for Claude Code on Windows.
It keeps Claude Code talking to api.anthropic.com at the client side, while transparently forwarding the real traffic to a local or external Anthropic-compatible backend such as EvoRouter or MiniMax.
This is useful because Claude Code contains a first-party host check around api.anthropic.com. When you point ANTHROPIC_BASE_URL directly at a third-party gateway, some client-side capabilities can be silently degraded. This project preserves the first-party path while still letting you control the real upstream.
This project was also informed by the ideas discussed in this article: 使用第三方代理 Claude Code 的注意了,你的 tool_use 被优化没了
Claude Code
-> https://api.anthropic.com
-> hosts hijack to 127.0.0.1
-> evo-tls-proxy terminates TLS locally
-> forwards to your real backend
- local EvoRouter: http://127.0.0.1:4010
- external gateway: https://api.minimaxi.com/anthropic
- Claude Code
v2.1.79works through the transparent proxy path - Main chat requests are forwarded as
POST /v1/messages?beta=true - Current Claude Code builds send the main auth header as
Authorization: Bearer ... - Background
POST /api/event_logging/batchrequests are handled locally by the proxy with204 - ToolSearch behavior is restored more closely to the first-party
api.anthropic.compath than when directly usingANTHROPIC_BASE_URL=http://localhost:4010
- Windows
- Node.js installed
- Administrator rights for editing the hosts file
- Claude Code
- A backend that accepts Anthropic-compatible requests
evo-tls-proxy/
├── enable.bat / enable.ps1
├── disable.bat / disable.ps1
├── start-proxy-visible.bat
├── generate-cert.js
├── tls-proxy.js
├── tls-proxy.config.json
├── test-proxy.js
└── certs/
Edit tls-proxy.config.json.
Default local EvoRouter configuration:
{
"listenPort": 443,
"targetUrl": "",
"targetHost": "127.0.0.1",
"targetPort": 4010,
"certsDir": "./certs"
}External Anthropic-compatible gateway example:
{
"listenPort": 443,
"targetUrl": "https://api.minimaxi.com/anthropic",
"targetHost": "127.0.0.1",
"targetPort": 4010,
"certsDir": "./certs"
}Rules:
- If
targetUrlis empty, the proxy usestargetHost+targetPort - If
targetUrlis set, it takes precedence - If
targetUrlincludes a base path such as/anthropic, the proxy preserves and appends the incoming Claude path correctly
Recommended Claude Code environment snippet:
{
"env": {
"ANTHROPIC_BASE_URL": "https://api.anthropic.com",
"ANTHROPIC_AUTH_TOKEN": "sk-ant-...",
"NO_PROXY": "127.0.0.1,localhost,api.anthropic.com,.anthropic.com"
}
}Important notes:
- Use
https://api.anthropic.com, nothttps://api.anthropic.com/v1 - If your system has
HTTP_PROXYorHTTPS_PROXY,NO_PROXYmust includeapi.anthropic.com - Without that
NO_PROXYentry, traffic may bypass the local hosts mapping and never hit this proxy
- Configure
tls-proxy.config.jsonfor your target backend. - Run
enable.bat. This generates certificates if needed, updateshosts, setsNODE_EXTRA_CA_CERTS, and then launchesstart-proxy-visible.bat. - If the proxy window does not appear automatically, start it manually with
start-proxy-visible.bat. On the current tested setup, launching this.batdirectly gives the best Windows Terminal behavior. - Make sure your real backend is running.
For local mode, EvoRouter should be listening on
127.0.0.1:4010. - Fully restart Claude Code.
- Send a test message and watch the proxy window.
enable.batConfigures the system side, then attempts to launch the visible proxy window.enable.ps1Performs the privileged setup steps and keeps the setup window open for review.start-proxy-visible.batStarts the visible proxy window directly. You can run this manually if you want to start or restart only the proxy process.disable.batRemoves the hosts entry, restoresNODE_EXTRA_CA_CERTS, and stops the proxy process.
This split is intentional. In the tested environment, the visible proxy window behaves best when it is ultimately launched from start-proxy-visible.bat.
You can test the TLS path without Claude Code:
node .\test-proxy.jsIf the proxy and backend are healthy, you should see a 200 response.
Typical successful flow:
[TLS] Handshake success from 127.0.0.1:9871 SNI=api.anthropic.com
[#1] -> POST /v1/messages?beta=true [Claude Code]
[#1] -> Upstream POST http://127.0.0.1:4010/v1/messages?beta=true
[#1] <- 200
Background event logging is intentionally handled locally:
[#2] -> POST /api/event_logging/batch [Claude Code]
[#2] <- Local 204 for /api/event_logging/batch
We ran an A/B comparison:
- Direct third-party path:
ANTHROPIC_BASE_URL=http://localhost:4010 - Transparent proxy path:
ANTHROPIC_BASE_URL=https://api.anthropic.complus hosts hijack
Observed result:
- Direct localhost mode still works for normal chat
- Transparent proxy mode behaves more like the first-party path during codebase exploration
- Claude becomes more likely to enter a fuller search/explore workflow instead of only doing shallow keyword probing
Supporting evidence from Claude logs:
- Third-party direct path can show:
ToolSearch:optimistic disabled: ... is not a first-party Anthropic host - First-party path can show:
ToolSearch:optimistic ... result=true
This is not a formal benchmark, but it is the practical reason this project exists.
Claude Code has also shipped a fix described roughly as:
Fixed API 400 errors when using
ANTHROPIC_BASE_URLwith a third-party gateway - tool search now correctly detects proxy endpoints and disablestool_referenceblocks
That fix is useful, but it does not make the transparent proxy approach obsolete.
What it means in practice:
- Claude Code now behaves more safely when it detects a third-party gateway
- It avoids some incompatible request shapes that could previously cause
400errors - But this is still a third-party code path with feature-aware downgrade behavior
What this project is trying to preserve is different:
- Keep Claude Code on the first-party
api.anthropic.comclient path - Avoid falling into the third-party gateway detection branch in the first place
- Preserve behavior that is closer to the official host path instead of only making the downgraded third-party path less error-prone
So the official fix improves third-party compatibility, while evo-tls-proxy still targets a different goal: preserving as much first-party client behavior as possible.
POST /v1/messages/count_tokens?beta=trueis not fully handled in every backend setup yet- For some backends this may timeout, while the main
/v1/messagesrequest still succeeds - Classic Windows console behavior can differ depending on how the proxy window is launched
- The tested release target is Claude Code
v2.1.79; future client versions may change request behavior
- This project installs a local CA certificate for interception of
api.anthropic.com - While enabled, any local process on the machine that resolves
api.anthropic.comthrough the modified hosts file will be redirected to this proxy - Keep the generated
certs/directory private - Do not commit
hosts.bakor private cert material
Before publishing or sharing:
- Confirm
tls-proxy.config.jsonis set to generic defaults, not your personal upstream - Keep
certs/out of git - Keep
hosts.bakout of git - Document your recommended Claude Code settings clearly
- Test both local backend mode and any external gateway mode you claim to support
ISC. See LICENSE.