1. What “timeouts” usually mean under Claude Code CLI

When people say the Claude Code CLI “times out,” they compress three different clocks into one complaint. The first clock is package installation: npm or your package manager opens many parallel connections to a registry, follows redirects, and sometimes downloads prebuilt binaries from release CDNs. The second clock is authentication and account handshakes that still touch Anthropic-shaped hosts even when you think you are only chatting locally. The third clock is the model itself—streaming HTTP requests that stay open, retry on idle kills, and punish unstable exits more than a one-shot image download.

Each clock fails in a different way. Install failures often look like stuck progress bars with no friendly HTTP code because tar layer downloads died mid-stream. Auth failures can surface as repeated “sign in” loops when OAuth or token refresh crosses a different geographic exit than the browser session that originally authorized you. Model failures may print clear Anthropic API errors, but they can also masquerade as generic network resets when a middle node drops long-lived HTTP/2 streams.

Your job before editing YAML is to decide which clock you are hearing. If installs fail but a trivial curl https://api.anthropic.com from the same shell succeeds, you may still be looking at missing coverage for registry.npmjs.org or GitHub’s objects.githubusercontent.com, not the model endpoint. If everything fails only inside a sandboxed IDE terminal, inheritance—not hostnames—is the first suspect.

Keep a written timeline. Note whether the pain began after a subscription refresh, a corporate network change, or an OS update. Those correlates matter because provider rules can reorder silently, and Wi‑Fi that “worked in the coffee shop” may have introduced split-horizon DNS that breaks SaaS names while leaving generic browsing acceptable.

2. Three layers: delivery, GitHub edges, Anthropic control plane

Model the traffic as layers rather than a single “AI toggle.” Layer one is package delivery: registry metadata, tarball hosts, optional mirrors, and integrity checks. Layer two is anything that looks like GitHub—not only github.com HTML, but release assets, raw.githubusercontent.com fetches, and traffic from the GitHub CLI if you use gh to manage tokens or fetch tools. Layer three is Anthropic: api.anthropic.com for programmatic calls, console or account hosts if the CLI opens device login flows, and sibling subdomains your Network panel actually shows during the failure window.

Layers split in real life when a ruleset sends “domestic CDN” traffic to DIRECT while SaaS API calls use PROXY. That can be efficient for ordinary sites and catastrophic for reproducible installs: half of your npm graph rides one policy while the tarball server rides another. The UI still prints errors that sound like npm bugs.

Document each layer with captures from your Mihomo-compatible client rather than nostalgia. Host graphs rotate; copying a stale forum list into YAML without verifying guarantees another round of “Clash broke randomly” Slack messages next month.

If you are new to split routing vocabulary, compare this framing with our OpenAI Codex console and API split article—the discipline is the same even though the suffixes differ.

3. Symptoms that separate npm stalls from Anthropic API stalls

npm timeout shaped issues cluster around install and update verbs. You see partial extraction, checksum complaints after a long wait, or metadata fetches that succeed only when you retry at 3 a.m. local time when your ISP is less congested. That pattern still deserves routing scrutiny: cheap bandwidth does not fix a hostname that your rules accidentally starve.

GitHub dependency issues often show up when a package vendor ships platform binaries from GitHub Releases. The registry request completes, then the postinstall step reaches for a URL on github.com or a GitHub CDN label and sits until the TCP session gives up. If your log alternates PROXY for npm and DIRECT for GitHub with inconsistent reachability, you have found the bug without opening a single support ticket.

Anthropic API stalls are more conversational: first token arrives late, streams reset, or the CLI prints auth errors that clear when you run the same command on a different network. When those symptoms track with specific exits but not with specific code changes, treat policy coherence as the independent variable before you blame model load.

Mixed symptoms—install works on Monday, model calls fail on Tuesday—often trace to auto-selecting nodes that change jurisdiction between sessions. Stabilize routing first; only then tune concurrency knobs inside the CLI.

4. Why system proxy alone often starves Node and npm

Many developers enable system proxy in a desktop Clash GUI and assume every child process inherits it. Browsers usually comply. Terminals are less obedient: shells launched from an IDE may not see the same environment as Terminal.app, and background daemons may never read OS proxy tables at all.

Node’s networking stack follows the process environment. If HTTPS_PROXY is unset, Node typically attempts a direct connection even when Windows or macOS advertises a system proxy for “user” apps. That behavioral gap is why a Claude Code CLI install appears “broken on this laptop” while Slack and Chrome feel fine.

The fix is not always TUN, but the diagnosis is always visibility. Open your client’s live connection view, run a minimal install, and ask whether the rows that appear match the shell you think you are using. If nothing shows up for npm while CPU spins, you are not routing that process—end of story until you inject proxy variables or switch modes.

For POSIX shells, our terminal proxy environment guide for curl, git, and npm walks export patterns and common foot-guns. Treat that page as the companion lab when you need clean baselines outside the IDE.

Windows adds another wrinkle: some terminals respect WinINET settings while developer tools read WinHTTP differently. If you observe divergence between cmd.exe and PowerShell inside the same machine, capture both connection logs before you declare victory on either path.

5. npm registry, tarballs, and mirrors under Clash

Begin with what npm actually touches. Typical installs contact registry.npmjs.org for metadata, then follow URLs embedded in package manifests—sometimes another registry host, sometimes GitHub releases, sometimes S3-like storage fronts that share little with the marketing domain you mentally associate with npm.

Your Clash split routing therefore needs coherent treatment for anything that appears while reproducing an install—not a vibes-based guess at “JavaScript sites.” That is why log-first workflows win. Filter connections for npm or sort by process when your client supports it, then list every distinct hostname with the policy attached.

For teams that deliberately use mirrors, mirrors do not erase the routing problem—they relocate it. A corporate mirror may sit on-premises and demand DIRECT, while global defaults send everything else via tunnel. Verify that mirror hostnames resolve where you intend and that TLS inspection appliances are not pinning certificates differently from the upstream registry.

npm can also be told about proxies explicitly:

# Example shells — substitute your mixed/HTTP port
export HTTPS_PROXY=http://127.0.0.1:7890
export HTTP_PROXY=http://127.0.0.1:7890
npm config set proxy http://127.0.0.1:7890
npm config set https-proxy http://127.0.0.1:7890

Undo those settings when you return to trusted networks; long-lived global npm proxy flags are a common source of “everything worked until I went home.”

Also watch corporate SSL bumping. npm throws intimidating TLS errors when a middlebox presents a rewritten chain. Clash routing cannot fix interception that breaks pinning; that requires trusting the enterprise root or shifting installs to networks without inspection.

6. GitHub, gh, and release assets

Even if your day-to-day browsing rarely visits GitHub, your toolchain probably does. Postinstall scripts download artifacts; language servers fetch blobs; release automation pulls installers. Failures concentrated after “downloading optional dependency” banners should make you suspicious of GitHub-shaped rows in the Mihomo table.

The GitHub CLI inherits the same truth as npm: respect for proxy varies with environment. If gh auth login opens a browser that succeeds yet subsequent API calls stall, compare policy paths for OAuth callbacks versus REST calls. Disjoint exits produce the classic “authorized but broken” feeling.

When you write rules, prefer explicit suffix coverage for the hosts you actually observed during failure reproduction, then widen cautiously. Broad DOMAIN-KEYWORD,github lines are powerful and easy to overfit into unrelated traffic. Our Cursor MCP and GitHub SSE routing article discusses transport-level behaviors that pair well with this hostname-first approach.

If you self-host runners or use Actions caches, remember that CI environments are not copies of your laptop. Fixes validated on a developer machine still need parallel checks where the CLI actually runs in production.

7. Anthropic endpoints beyond “one API hostname”

Once installs succeed, Anthropic API traffic still benefits from intentional grouping. Programmatic calls usually center on api.anthropic.com, but account flows may touch console or identity-adjacent subdomains and static delivery edges. Splitting “only the API” away from related hosts is a recipe for fragile sessions that look like flaky model behavior.

Streaming responses punish nodes that recycle connections aggressively. If your provider’s auto selector flaps between countries mid-stream, the client may report a timeout even when each individual hop looked healthy for a few seconds. Coherent policy groups matter more than peak synthetic speed tests for long interactive sessions.

Keep OAuth or device-login flows visually aligned with the same exit you expect for sustained model traffic unless compliance demands otherwise. The browser may hide subtle differences until the CLI tries to reuse tokens across environments.

When diagnosing, correlate timestamps between your CLI logs and Mihomo rows. Matching UTC windows tell you whether a failure aligns with TLS handshake retries versus HTTP 429 rate responses—different remedies.

8. DNS, fake-ip, and resolver disagreements

Clash’s fake-ip mode couples fast answers with rule evaluation. When resolvers and the rule engine disagree about what a hostname means, you can see intermittent TLS failures that feel like “npm is moody” or “Anthropic throttles me” even though the root cause lives entirely in DNS.

Investigate upstream DNS reliability first. Satellite links, captive portals, and aggressive parental filters all introduce NXDOMAIN quirks for international SaaS. Fix that before debating node lists.

Targeted nameserver-policy style directives—field names vary by Mihomo builds—can pin suffixes like npmjs.org, github.com, or anthropic.com to resolvers that behave predictably on your network. Always cross-check keys against the documentation for the exact core version you ship; stale snippets from three releases ago are how YAML becomes superstition.

Compare answers from inside Clash and outside it when split-horizon DNS is suspected. Two different IP families for the same label guarantee pain once HTTP/2 coalescing enters the picture.

IPv6 adds parallel paths. If AAAA attempts bypass your tunnel while IPv4 traverses Clash, the failure mode depends on whichever stack the runtime tried first—a nasty nondeterministic flavor of timeout. Temporary dual-stack experiments are valid diagnostics if logs show asymmetric success.

9. Putting rules where broad lists cannot steal them

Subscription lists love broad GEOIP and “domestic CDN” shortcuts. They are not evil; they are just upstream of your exceptions if you insert them too early. Place explicit DOMAIN-SUFFIX lines for the hosts you care about before catch-alls return DIRECT for labels that overlap your developer stack.

Rename PROXY below to whichever policy label your profile actually uses:

# Example fragments — verify against your live Mihomo log
rules:
  - DOMAIN-SUFFIX,npmjs.org,PROXY
  - DOMAIN-SUFFIX,nodejs.org,PROXY
  - DOMAIN-SUFFIX,github.com,PROXY
  - DOMAIN-SUFFIX,githubusercontent.com,PROXY
  - DOMAIN-SUFFIX,anthropic.com,PROXY

Prefer suffix rules over keyword rules when precision allows. Keywords are blunt instruments: fast to paste, painful to audit when troubleshooting months later.

After widening coverage, reconcile duplicates. Multiple overlapping lines seldom break routing by themselves, but they obscure precedence when you are tired and skimming thousands of lines at midnight.

If you must keep strict split-tunneling for compliance, document the exception list with business justification. Future config merges will otherwise “optimize” your careful exceptions away.

10. When to escalate from system proxy to TUN

TUN mode pushes interception closer to the routing table, which catches stubborn binaries that ignore application-level proxy settings. It is not mandatory for every developer, but it is the honest next lever when evidence shows processes never appear in your connection log.

TUN introduces new classes of conflicts: stacked VPNs, corporate always-on clients, and hypervisors that fight for interface priority. If enabling TUN breaks something else, capture that trade-off explicitly rather than toggling blindly.

Walk through our Clash TUN mode guide if the concept is unfamiliar, then repeat your npm and CLI tests with identical rule files so you isolate mode effects from unrelated edits.

Containers and WSL deserve bridge planning. Testing with host-native terminals while production jobs run inside Linux VMs yields false negatives. Pair this page with our WSL2 host proxy playbook when your reproducer straddles Windows and Linux.

11. Verification: make failures boring and repeatable

After each change, run a triad of checks: a minimal npm metadata fetch, a GitHub asset download that mirrors your real install path, and a short Anthropic API call using the same shell that launches Claude Code CLI. If any leg fails, return to the connection table before touching remote server selection.

Capture “good” and “bad” log slices. Diffing policy columns between states is faster than trusting memory after long incident nights.

When IDE-integrated terminals misbehave but bare shells work, compare environment blocks. Sometimes a well-meaning NO_PROXY entry torpedoes SaaS hostnames you actually need to tunnel.

Finally, note software updates. Core bumps can alter DNS defaults; IDE updates can reset proxy inheritance. Version your working YAML in git like any other infrastructure artifact.

12. FAQ: quick decisions under pressure

Why does the browser work while npm hangs? Different processes, different proxy awareness. Align HTTPS_PROXY or enable TUN, then re-check logs.

Do I need separate groups for Anthropic and GitHub? Only if you have a concrete reason—compliance, billing, or experimental exits. Otherwise coherent groups reduce session glue bugs.

Can I blame Anthropic first? Sometimes yes—check vendor status—but collect host-level evidence locally before you escalate externally. Support tickets move faster with timestamps and log excerpts.

What about QUIC-only paths? Mixed stacks occasionally push traffic over protocols your capture tool labels differently. If you suspect protocol surprises, replicate tests with narrowly scoped clients and annotate transport types in notes.

13. Close with logs, not vibes

Claude Code CLI adoption in 2026 rewards developers who treat the toolchain like distributed systems debugging. npm timeout reports often mean incomplete coverage for registry and tarball edges, not weak hardware. GitHub-hosted artifacts punish split policies that alternate DIRECT and PROXY across related hostnames. Anthropic API calls need stable exits and coherent DNS—not heroic guessing from a traceroute meme.

Compared with juggling multiple single-purpose VPN clients that hide traffic from you, a maintained Mihomo-powered desktop experience keeps per-host policy visible and makes subscription churn less scary when CDNs shift. → Download Clash for free and experience the difference

Back to blog