Claude Code is most useful when it can reach its model service, download required resources, and keep a stable connection while commands run in the terminal. On an unstable or restricted network, the failure may look like an authentication problem, a timeout, or a stalled request even when the API key is correct. Clash Verge can provide the missing network path, but enabling the desktop proxy alone is not always enough: terminal programs may not read the operating system proxy settings.
This guide explains how to pair Claude Code with Clash Verge in a controlled way. It covers the difference between system proxy and terminal proxy variables, the recommended setup order, Windows PowerShell and macOS/Linux commands, TUN mode as an alternative, and a practical checklist for diagnosing connection failures. The examples use the common mixed proxy port 7890; check Clash Verge's actual port before copying any command.
A proxy does not replace an API key, an active Claude Code account, or a valid subscription. Clash Verge only changes the network path. Keep authentication and proxy troubleshooting as two separate checks.
How Claude Code and Clash Verge Connect
Claude Code runs as a command-line application, so its traffic path depends on how the underlying runtime and operating system are configured. When you enable Clash Verge's system proxy, browsers and many desktop applications can discover the proxy automatically. A terminal process started before the proxy was enabled, however, may continue using its own direct connection rules. Tools such as curl, package managers, Git, and JavaScript-based command-line programs commonly require explicit proxy environment variables.
Clash Verge normally exposes a mixed port that accepts both HTTP proxy requests and SOCKS5 connections. The HTTP form is the easiest choice for Claude Code because HTTPS destinations are carried through the HTTP proxy with the CONNECT method. The local traffic flow looks like this:
- Claude Code creates an HTTPS request to its configured service endpoint.
- The terminal process reads
HTTPS_PROXY,HTTP_PROXY, or another supported proxy variable. - The process connects to Clash Verge at
127.0.0.1:7890. - mihomo selects a proxy group and node according to the active mode and rules.
- The selected node establishes the remote connection and returns the response to Claude Code.
The most important distinction is between a desktop proxy and a process proxy. The desktop proxy changes operating system settings. The process proxy changes the environment inherited by a shell and every command launched from that shell. They can be used separately or together, but enabling both does not mean that every program will use the same path.
| Method | What It Changes | Terminal Coverage | Best Use |
|---|---|---|---|
| System Proxy | Operating system HTTP/HTTPS proxy settings | Depends on application support | Browsers and applications that honor system settings |
| Shell Variables | Proxy variables inherited by child processes | Good for Claude Code, curl, Git, and package tools | Focused terminal workflows |
| TUN Mode | IP-level routing through a virtual adapter | Usually broad, including applications that ignore proxy variables | Persistent or hard-to-configure network access |
For a first setup, use shell variables rather than switching immediately to TUN mode. This keeps the change reversible and makes it clear whether the problem belongs to Claude Code, the shell, or Clash Verge. If the terminal still bypasses the proxy after the variables are confirmed, TUN mode is the next logical option.
Prepare Clash Verge Before Running Claude Code
Start Clash Verge and confirm that a profile containing usable proxy nodes is active. A running client without an active profile can still show a local port, but requests may fail because the selected group has no available node. Open the profile or proxy page, choose a working group, and verify that the group is not set to an unavailable node.
If Clash Verge is not installed yet, use the download page to obtain the client for your platform. After installation, complete the initial profile import before testing Claude Code. The following values are common defaults, but they are not universal:
- Mixed port:
7890 - HTTP proxy address:
127.0.0.1:7890 - SOCKS5 address:
127.0.0.1:7890or a separate SOCKS port such as7891 - Local API or controller port: often different from the proxy port; do not use it as a proxy address
Check the actual value under Clash Verge's settings or port section. A common mistake is to copy the external controller address into HTTPS_PROXY. The controller is used to manage Clash through an API; it is not the listener that carries ordinary web traffic.
Next, enable a routing mode that can send the required domains through a working node. Rule mode is normally the most convenient starting point. If your rules do not match the service domains, the request may be sent directly and fail even though the node itself works. Global mode can be useful for a short diagnostic test because it removes most rule-selection ambiguity, but it may proxy unrelated traffic as well.
Before opening Claude Code, test the local listener with a simple request:
curl -I --proxy http://127.0.0.1:7890 https://example.com
A successful HTTP response proves that a process can reach the local Clash port and that Clash can establish at least one outbound connection. It does not prove that Claude Code's service endpoint, account, or API key is valid. If this command reports “connection refused,” correct the port or start Clash Verge. If it hangs, inspect the selected node, proxy group, and Clash logs. If it returns a response quickly, continue with the terminal environment setup.
Set Terminal Proxy Variables Step by Step
Use the HTTP form for both HTTP and HTTPS variables. The URL scheme describes the local proxy protocol, not the destination website. In other words, an HTTPS API request can correctly use http://127.0.0.1:7890 as its proxy URL.
Windows PowerShell
Open a new PowerShell window after Clash Verge is running. Set the variables for the current session with:
$env:HTTP_PROXY="http://127.0.0.1:7890"
$env:HTTPS_PROXY="http://127.0.0.1:7890"
$env:ALL_PROXY="http://127.0.0.1:7890"
$env:NO_PROXY="localhost,127.0.0.1,::1"
curl.exe -I https://example.com
curl.exe is used deliberately because Windows PowerShell can map curl to another command depending on the PowerShell version. The final request should use the proxy variables automatically. To confirm what the current shell contains, run:
Get-ChildItem Env:HTTP_PROXY,Env:HTTPS_PROXY,Env:ALL_PROXY,Env:NO_PROXY
If the test succeeds, start Claude Code from this same PowerShell window. A new terminal window will not inherit variables that were set only for the old session. This is one of the most frequent reasons users report that the proxy works for curl but not for Claude Code: the test and the application were launched from different environments.
To make the variables available to future PowerShell sessions, you can store them as user-level environment variables:
[Environment]::SetEnvironmentVariable("HTTP_PROXY", "http://127.0.0.1:7890", "User")
[Environment]::SetEnvironmentVariable("HTTPS_PROXY", "http://127.0.0.1:7890", "User")
[Environment]::SetEnvironmentVariable("NO_PROXY", "localhost,127.0.0.1,::1", "User")
Close and reopen the terminal after using this persistent method. Do not store an API key in a shared script or paste it into a public project. Proxy variables are normally safe to share, but credentials and tokens are not.
macOS and Linux Shells
In Bash, Zsh, or a compatible shell, export the variables as follows:
export HTTP_PROXY="http://127.0.0.1:7890"
export HTTPS_PROXY="http://127.0.0.1:7890"
export ALL_PROXY="http://127.0.0.1:7890"
export NO_PROXY="localhost,127.0.0.1,::1"
curl -I https://example.com
Some tools read only lowercase names, while others read uppercase names. Setting both forms gives broader compatibility, especially when a package manager or a child process uses a different convention:
export http_proxy="$HTTP_PROXY"
export https_proxy="$HTTPS_PROXY"
export all_proxy="$ALL_PROXY"
export no_proxy="$NO_PROXY"
For a temporary test, place these commands directly in the current shell. For a persistent setup, add them to the appropriate startup file, such as ~/.zshrc for a typical macOS Zsh session or ~/.bashrc for an interactive Bash session. Then reload the file:
source ~/.zshrc
# or
source ~/.bashrc
Do not add proxy exports to a shell startup file on a computer that regularly moves between networks unless you also have a convenient disable method. A stale local proxy address can make every terminal request fail when Clash Verge is closed.
Launch and Test Claude Code
Once the shell request succeeds, launch Claude Code from the same terminal. Begin with a small operation that does not modify files, such as asking it to inspect the current directory or explain a short source file. This separates connection testing from a large coding task.
claude
Watch both the terminal output and Clash Verge's connection log. A request that appears in the log confirms that the process reached the local proxy. If Claude Code reports a successful connection but the response is an authentication error, the proxy path is probably working and the next check should be the account or API configuration. If no connection appears in Clash Verge at all, Claude Code may not have inherited the variables, may use a different variable convention, or may be running inside another environment such as an IDE terminal, container, or remote shell.
Choose Between Shell Proxy and TUN Mode
Shell variables are the most precise option. They affect Claude Code and the commands launched from that shell without forcing unrelated applications through the proxy. They are also easy to disable and are suitable when only one project or one work session needs the connection.
TUN mode works at a lower layer. Mihomo creates a virtual network adapter and routes IP packets through it, so applications do not need to understand HTTP proxy variables. This can help when Claude Code runs from an IDE, a service wrapper, a container integration, or another launcher that does not inherit your interactive shell environment.
| Situation | Preferred Method | Reason |
|---|---|---|
| Only Claude Code needs the proxy | Shell variables | Limited scope and easy rollback |
| Claude Code is launched from an IDE | Shell variables in the IDE terminal, or TUN | Ensures the actual launcher receives the route |
| A tool ignores proxy variables | TUN mode | Captures traffic at the IP layer |
| Several applications need the same route | TUN mode or system proxy | Reduces per-process configuration |
| Local development services must stay direct | Shell variables with NO_PROXY, or careful TUN rules | Prevents localhost traffic from leaving the machine |
To use TUN mode, first make sure the Clash Verge service component or elevated permission required by your platform is installed. Then open the TUN settings, enable the mode, and accept the operating system permission prompt. Keep a clear direct-access rule for local addresses such as 127.0.0.1, localhost, private network ranges, and development domains used by your project.
TUN mode is not automatically better. It can affect package downloads, local virtual machines, Docker networks, database connections, and corporate intranet access. If a local service becomes unreachable after enabling TUN, inspect the routing rules before changing random DNS settings. Disable TUN and return to shell variables if you only need Claude Code to use the proxy.
Diagnose Timeouts, Authentication Errors, and Direct Connections
Start by classifying the failure rather than repeatedly changing the node. The same visible message can have different causes, but the following sequence usually narrows the problem quickly.
| Symptom | Likely Layer | First Check |
|---|---|---|
| Connection refused to 127.0.0.1 | Local proxy listener | Confirm Clash is running and the port is correct |
| curl works with --proxy but Claude Code times out | Process environment or launcher | Print variables in the exact terminal that starts Claude Code |
| Clash log shows no request | Proxy not inherited or unsupported variable | Use the same shell and set uppercase plus lowercase variables |
| Clash log shows a request but node fails | Proxy group or outbound node | Switch node and inspect the connection log |
| Authentication or permission error | Account or API configuration | Verify credentials separately from network settings |
| Local development server stops working | Proxy scope or routing exclusion | Set NO_PROXY and add local direct rules |
Check for conflicting variables before testing again. A lowercase variable may point to an old proxy while the uppercase variable points to the current port. Display them with:
env | grep -i proxy
On PowerShell, use:
Get-ChildItem Env:*proxy*
Another common problem is a SOCKS and HTTP mismatch. If the listener is configured as an HTTP or mixed port, use http://127.0.0.1:7890. If you deliberately use a SOCKS5 port, use a client and runtime that support the SOCKS scheme, such as socks5h://127.0.0.1:7891 where supported. The socks5h form asks the proxy to resolve hostnames, which can avoid local DNS interference, but not every command-line application accepts it. For broad compatibility, the mixed HTTP port is usually simpler.
DNS is another possible source of confusion, especially with direct connections. If the request reaches Clash but the domain cannot be resolved, review the mihomo DNS configuration and the active mode. With TUN mode, fake-IP and DNS hijack settings must be internally consistent. With a simple shell proxy, local DNS may still be used to locate the proxy destination or resolve domains in applications that do not delegate hostname resolution to the proxy.
When a request is slow rather than completely blocked, test a different node and observe latency in Clash Verge. A terminal coding workflow often makes several sequential requests, so a node with intermittent packet loss can feel like an application failure. Avoid judging stability from one successful browser page; run several command-line requests and watch whether the connection repeatedly appears in the Clash log.
Finally, remove the temporary variables when the task is complete if you do not want all future terminal programs to use Clash Verge:
unset HTTP_PROXY HTTPS_PROXY ALL_PROXY NO_PROXY
unset http_proxy https_proxy all_proxy no_proxy
In PowerShell, clear the current session with:
Remove-Item Env:HTTP_PROXY,Env:HTTPS_PROXY,Env:ALL_PROXY,Env:NO_PROXY -ErrorAction SilentlyContinue
Remove-Item Env:http_proxy,Env:https_proxy,Env:all_proxy,Env:no_proxy -ErrorAction SilentlyContinue
The reliable setup pattern is simple: verify the Clash listener, test the listener with curl, set proxy variables in the exact shell that launches Claude Code, and use TUN mode only when process-level configuration is insufficient. This approach keeps the network path visible, limits unwanted traffic changes, and makes each failure point testable instead of treating Claude Code and Clash Verge as one opaque system.