把 v2rayN 本机代理 同时打通到 Windows 系统、命令行工具、Codex、Claude Code 与浏览器。
日常只记三个命令:po 开启、ph 取消、psw 查看。
浏览器走代理不代表 CLI 也走代理。本教程把代理写到三处入口: Windows 系统代理(浏览器)、用户级环境变量(CLI)、 工具自身配置(Git / npm / pnpm / Codex / Claude),并用一个脚本统一管理。
同时写入 Windows 环境变量、系统代理、Git/npm/yarn/pnpm、Codex 的 config.toml 与 Claude 的 settings.json,所有路径统一指向 10808。
清理环境变量、关闭系统代理、移除工具链代理、剥离 Codex 托管块、清空 Claude env 字段。直连状态可重复幂等执行。
输出当前环境变量、注册表中的系统代理、Git / npm / pnpm 代理、Codex 配置路径与 Claude 的 env 字段,判断到底在哪一层生效。
不同程序读取代理的方式不一样,所以要在每一层都把代理写清楚,而不是只开一个系统代理就指望全覆盖。
| 体系 | 影响对象 | 典型场景 | 脚本管理 |
|---|---|---|---|
| WinINET 系统代理 | 当前用户图形应用 | Edge / Chrome / 部分 Electron | outside ✅ / home ❌ |
| 用户级环境变量 | 命令行与跨平台工具 | curl / git / npm / node / python / Codex 子进程 | outside ✅ / home ❌ |
| 工具自身配置 | 单个工具 | git config / npm config / Codex TOML | outside ✅ / home ❌ |
| Codex shell_environment_policy | Codex 启动的子进程 | ~/.codex/config.toml 管理块 |
outside ✅ / home ❌ |
| Claude Code env | Claude Code 会话 | ~/.claude/settings.json 的 env 字段 |
outside ✅ / home ❌ |
使用 mixed 端口 127.0.0.1:10808,同时接受 HTTP 与 SOCKS5。
注:https_proxy=http://... 不是写错,而是用 HTTP 代理协议为 HTTPS 建立 CONNECT 隧道。
%USERPROFILE%\Documents\PowerShell\proxy-switch.ps1%USERPROFILE%\Documents\PowerShell\Microsoft.PowerShell_profile.ps1%USERPROFILE%\.codex\config.toml%USERPROFILE%\.claude\settings.jsonCodex 通过 shell_environment_policy 给子进程注入代理;Claude Code 通过 settings.json 的 env 字段注入会话代理。
# >>> proxy-switch managed shell_environment_policy
[shell_environment_policy]
inherit = "core"
[shell_environment_policy.set]
http_proxy = "http://127.0.0.1:10808"
https_proxy = "http://127.0.0.1:10808"
HTTP_PROXY = "http://127.0.0.1:10808"
HTTPS_PROXY = "http://127.0.0.1:10808"
all_proxy = "socks5://127.0.0.1:10808"
ALL_PROXY = "socks5://127.0.0.1:10808"
no_proxy = "localhost,127.0.0.1,::1"
NO_PROXY = "localhost,127.0.0.1,::1"
# <<< proxy-switch managed shell_environment_policy
{
"$schema": "https://json.schemastore.org/claude-code-settings.json",
"env": {
"HTTP_PROXY": "http://127.0.0.1:10808",
"HTTPS_PROXY": "http://127.0.0.1:10808",
"NO_PROXY": "localhost,127.0.0.1"
}
}
config.toml 不要手工反复改:执行 po / ph 会在标记块之间自动写入或剥离,并生成 config.toml.bak 备份。HTTP_PROXY / HTTPS_PROXY / NO_PROXY 三个大写键,不写入 SOCKS、不写入小写键。po 写入 env 字段,ph 整体移除该字段,每次写入前生成 settings.json.bak 备份。脚本接收 -Mode 参数(home / outside / status)。outside 同时写入环境变量、系统代理、工具链代理、Codex 托管块与 Claude env 字段;home 全部清理;status 只读输出。
Env + WinINET + Git/npm/yarn/pnpm + Codex TOML + Claude settings.json 全部指向 10808,并刷新 WinINet 让浏览器立即生效。
清空 Env、关闭 WinINET、卸载工具链代理、剥离 Codex 托管块、移除 Claude env。config.toml 与 settings.json 自动备份。
分区打印当前 Env / 注册表 / Git / npm / pnpm / Codex / Claude 状态,便于排障。
param(
[ValidateSet("home", "outside", "status")]
[string]$Mode = "status"
)
# ============================================================
# proxy-switch.ps1
# 说明:
# home = 取消本机显式代理
# outside = 开启本机 v2rayN 127.0.0.1:10808 代理
# status = 查看当前代理状态
# ============================================================
$LocalHttp = "http://127.0.0.1:10808"
$LocalSocks = "socks5://127.0.0.1:10808"
$LocalSystemProxy = "127.0.0.1:10808"
$NoProxy = "localhost,127.0.0.1,::1"
$ClaudeNoProxy = "localhost,127.0.0.1"
$CodexConfig = Join-Path $env:USERPROFILE ".codex\config.toml"
function Update-InternetSettings {
try {
Add-Type -Namespace WinINet -Name NativeMethods -MemberDefinition @"
[System.Runtime.InteropServices.DllImport("wininet.dll", SetLastError = true)]
public static extern bool InternetSetOption(System.IntPtr hInternet, int dwOption, System.IntPtr lpBuffer, int dwBufferLength);
"@ -ErrorAction SilentlyContinue
[WinINet.NativeMethods]::InternetSetOption([IntPtr]::Zero, 39, [IntPtr]::Zero, 0) | Out-Null
[WinINet.NativeMethods]::InternetSetOption([IntPtr]::Zero, 37, [IntPtr]::Zero, 0) | Out-Null
} catch {
Write-Host "WinINet refresh skipped." -ForegroundColor DarkYellow
}
}
function Set-ProxyEnv {
param(
[string]$HttpProxy,
[string]$SocksProxy
)
$pairs = @(
@("http_proxy", $HttpProxy),
@("https_proxy", $HttpProxy),
@("HTTP_PROXY", $HttpProxy),
@("HTTPS_PROXY", $HttpProxy),
@("all_proxy", $SocksProxy),
@("ALL_PROXY", $SocksProxy),
@("no_proxy", $NoProxy),
@("NO_PROXY", $NoProxy)
)
foreach ($pair in $pairs) {
$name = $pair[0]
$value = $pair[1]
[Environment]::SetEnvironmentVariable($name, $value, "User")
Set-Item -Path "Env:\$name" -Value $value
}
}
function Clear-ProxyEnv {
$names = @(
"http_proxy",
"https_proxy",
"HTTP_PROXY",
"HTTPS_PROXY",
"all_proxy",
"ALL_PROXY",
"no_proxy",
"NO_PROXY"
)
foreach ($name in $names) {
[Environment]::SetEnvironmentVariable($name, $null, "User")
Remove-Item "Env:\$name" -ErrorAction SilentlyContinue
}
}
function Enable-SystemProxy {
param([string]$ProxyServer)
$path = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings"
Set-ItemProperty -Path $path -Name ProxyEnable -Value 1
Set-ItemProperty -Path $path -Name ProxyServer -Value $ProxyServer
Update-InternetSettings
}
function Disable-SystemProxy {
$path = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings"
Set-ItemProperty -Path $path -Name ProxyEnable -Value 0
Remove-ItemProperty -Path $path -Name ProxyServer -ErrorAction SilentlyContinue
Update-InternetSettings
}
function Set-ToolProxy {
param(
[string]$HttpProxy,
[string]$SocksProxy
)
if (Get-Command git -ErrorAction SilentlyContinue) {
git config --global http.proxy $SocksProxy
git config --global https.proxy $SocksProxy
}
if (Get-Command npm -ErrorAction SilentlyContinue) {
npm config set proxy $HttpProxy 2>$null
npm config set https-proxy $HttpProxy 2>$null
}
if (Get-Command yarn -ErrorAction SilentlyContinue) {
yarn config set proxy $HttpProxy 2>$null
yarn config set https-proxy $HttpProxy 2>$null
}
if (Get-Command pnpm -ErrorAction SilentlyContinue) {
pnpm config set proxy $HttpProxy 2>$null
pnpm config set https-proxy $HttpProxy 2>$null
}
}
function Clear-ToolProxy {
if (Get-Command git -ErrorAction SilentlyContinue) {
git config --global --unset http.proxy 2>$null
git config --global --unset https.proxy 2>$null
}
if (Get-Command npm -ErrorAction SilentlyContinue) {
npm config delete proxy 2>$null
npm config delete https-proxy 2>$null
}
if (Get-Command yarn -ErrorAction SilentlyContinue) {
yarn config delete proxy 2>$null
yarn config delete https-proxy 2>$null
}
if (Get-Command pnpm -ErrorAction SilentlyContinue) {
pnpm config delete proxy 2>$null
pnpm config delete https-proxy 2>$null
}
}
function Get-CodexConfigPath {
$codexDir = Join-Path $env:USERPROFILE ".codex"
New-Item -ItemType Directory -Force -Path $codexDir | Out-Null
return (Join-Path $codexDir "config.toml")
}
function Get-ClaudeSettingsPath {
$claudeDir = Join-Path $env:USERPROFILE ".claude"
New-Item -ItemType Directory -Force -Path $claudeDir | Out-Null
return (Join-Path $claudeDir "settings.json")
}
function Remove-ProxySwitchManagedBlock {
param([string]$Content)
if ([string]::IsNullOrWhiteSpace($Content)) {
return ""
}
$pattern = '(?ms)^\s*# >>> proxy-switch managed shell_environment_policy\s*\r?\n.*?^\s*# <<< proxy-switch managed shell_environment_policy\s*\r?\n?'
return ($Content -replace $pattern, '').TrimEnd()
}
function Remove-ShellEnvironmentPolicySections {
param([string]$Content)
if ([string]::IsNullOrWhiteSpace($Content)) {
return ""
}
$lines = $Content -split "`r?`n"
$out = New-Object System.Collections.Generic.List[string]
$skip = $false
foreach ($line in $lines) {
if ($line -match '^\s*\[(shell_environment_policy|shell_environment_policy\.set)\]\s*$') {
$skip = $true
continue
}
if ($skip -and $line -match '^\s*\[.+\]\s*$') {
$skip = $false
$out.Add($line)
continue
}
if (-not $skip) {
$out.Add($line)
}
}
return (($out -join "`r`n").TrimEnd())
}
function Write-CodexConfig {
param([string]$Content)
$config = Get-CodexConfigPath
if (Test-Path $config) {
Copy-Item $config "$config.bak" -Force
}
Set-Content -Path $config -Value $Content -Encoding UTF8
Write-Host "Codex config updated:" -ForegroundColor Green
Write-Host $config -ForegroundColor Cyan
}
function Read-ClaudeSettings {
$settingsPath = Get-ClaudeSettingsPath
if (!(Test-Path $settingsPath)) {
return [ordered]@{
'$schema' = "https://json.schemastore.org/claude-code-settings.json"
}
}
$raw = Get-Content $settingsPath -Raw
if ([string]::IsNullOrWhiteSpace($raw)) {
return [ordered]@{
'$schema' = "https://json.schemastore.org/claude-code-settings.json"
}
}
return ($raw | ConvertFrom-Json -AsHashtable)
}
function Write-ClaudeSettings {
param([object]$Settings)
$settingsPath = Get-ClaudeSettingsPath
if (Test-Path $settingsPath) {
Copy-Item $settingsPath "$settingsPath.bak" -Force
}
$json = $Settings | ConvertTo-Json -Depth 100
Set-Content -Path $settingsPath -Value $json -Encoding UTF8
Write-Host "Claude settings updated:" -ForegroundColor Green
Write-Host $settingsPath -ForegroundColor Cyan
}
function Set-ClaudeProxy {
param([string]$HttpProxy)
$settings = Read-ClaudeSettings
if (!$settings.Contains("env")) {
$settings["env"] = [ordered]@{}
}
if ($null -eq $settings["env"]) {
$settings["env"] = [ordered]@{}
}
if ($settings["env"] -isnot [System.Collections.IDictionary]) {
$settings["env"] = [ordered]@{}
}
$envSettings = $settings["env"]
foreach ($name in @("HTTP_PROXY", "HTTPS_PROXY", "http_proxy", "https_proxy", "ALL_PROXY", "all_proxy", "NO_PROXY", "no_proxy")) {
if ($envSettings.Contains($name)) {
$envSettings.Remove($name)
}
}
$pairs = @(
@("HTTP_PROXY", $HttpProxy),
@("HTTPS_PROXY", $HttpProxy),
@("NO_PROXY", $ClaudeNoProxy)
)
foreach ($pair in $pairs) {
$name = $pair[0]
$value = $pair[1]
if ($envSettings.Contains($name)) {
$envSettings[$name] = $value
} else {
$envSettings[$name] = $value
}
}
Write-ClaudeSettings -Settings $settings
}
function Clear-ClaudeProxy {
$settingsPath = Get-ClaudeSettingsPath
if (!(Test-Path $settingsPath)) {
Write-Host "Claude settings does not exist, skipped:" -ForegroundColor Yellow
Write-Host $settingsPath -ForegroundColor Cyan
return
}
$settings = Read-ClaudeSettings
if ($settings.Contains("env")) {
$settings.Remove("env")
}
Write-ClaudeSettings -Settings $settings
}
function Set-CodexProxy {
param(
[string]$HttpProxy,
[string]$SocksProxy
)
$config = Get-CodexConfigPath
if (Test-Path $config) {
$content = Get-Content $config -Raw
} else {
$content = ""
}
$content = Remove-ProxySwitchManagedBlock -Content $content
$content = Remove-ShellEnvironmentPolicySections -Content $content
$block = @"
# >>> proxy-switch managed shell_environment_policy
[shell_environment_policy]
inherit = "core"
[shell_environment_policy.set]
http_proxy = "$HttpProxy"
https_proxy = "$HttpProxy"
HTTP_PROXY = "$HttpProxy"
HTTPS_PROXY = "$HttpProxy"
all_proxy = "$SocksProxy"
ALL_PROXY = "$SocksProxy"
no_proxy = "$NoProxy"
NO_PROXY = "$NoProxy"
# <<< proxy-switch managed shell_environment_policy
"@
$newContent = ($content.TrimEnd() + "`r`n" + $block).TrimStart()
Write-CodexConfig -Content $newContent
}
function Clear-CodexProxy {
$config = Get-CodexConfigPath
if (!(Test-Path $config)) {
Write-Host "Codex config does not exist, skipped:" -ForegroundColor Yellow
Write-Host $config -ForegroundColor Cyan
return
}
$content = Get-Content $config -Raw
$content = Remove-ProxySwitchManagedBlock -Content $content
$content = Remove-ShellEnvironmentPolicySections -Content $content
$newContent = $content.Trim()
Write-CodexConfig -Content $newContent
}
function Show-ProxyStatus {
$path = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings"
$reg = Get-ItemProperty -Path $path
Write-Host ""
Write-Host "========== Windows 用户环境变量 ==========" -ForegroundColor Cyan
Write-Host "http_proxy = $env:http_proxy"
Write-Host "https_proxy = $env:https_proxy"
Write-Host "all_proxy = $env:all_proxy"
Write-Host ""
Write-Host "========== Windows 系统代理 ==========" -ForegroundColor Cyan
Write-Host "ProxyEnable = $($reg.ProxyEnable)"
Write-Host "ProxyServer = $($reg.ProxyServer)"
Write-Host ""
Write-Host "========== Git ==========" -ForegroundColor Cyan
if (Get-Command git -ErrorAction SilentlyContinue) {
Write-Host "git http.proxy = $(git config --global --get http.proxy)"
Write-Host "git https.proxy = $(git config --global --get https.proxy)"
} else {
Write-Host "git not found"
}
Write-Host ""
Write-Host "========== npm ==========" -ForegroundColor Cyan
if (Get-Command npm -ErrorAction SilentlyContinue) {
Write-Host "npm proxy = $(npm config get proxy)"
Write-Host "npm https-proxy = $(npm config get https-proxy)"
} else {
Write-Host "npm not found"
}
Write-Host ""
Write-Host "========== pnpm ==========" -ForegroundColor Cyan
if (Get-Command pnpm -ErrorAction SilentlyContinue) {
Write-Host "pnpm proxy = $(pnpm config get proxy)"
Write-Host "pnpm https-proxy = $(pnpm config get https-proxy)"
} else {
Write-Host "pnpm not found"
}
Write-Host ""
Write-Host "========== Codex ==========" -ForegroundColor Cyan
Write-Host "config = $(Get-CodexConfigPath)"
Write-Host ""
Write-Host "========== Claude ==========" -ForegroundColor Cyan
$claudeSettingsPath = Get-ClaudeSettingsPath
Write-Host "settings = $claudeSettingsPath"
if (Test-Path $claudeSettingsPath) {
try {
$claudeSettings = Read-ClaudeSettings
if ($claudeSettings.Contains("env") -and $null -ne $claudeSettings["env"]) {
$claudeEnv = $claudeSettings["env"]
Write-Host "HTTP_PROXY = $($claudeEnv["HTTP_PROXY"])"
Write-Host "HTTPS_PROXY = $($claudeEnv["HTTPS_PROXY"])"
Write-Host "NO_PROXY = $($claudeEnv["NO_PROXY"])"
} else {
Write-Host "env = <not set>"
}
} catch {
Write-Host "settings.json could not be parsed." -ForegroundColor Red
}
} else {
Write-Host "settings.json not found"
}
}
function Switch-Home {
Clear-ProxyEnv
Disable-SystemProxy
Clear-ToolProxy
Clear-CodexProxy
Clear-ClaudeProxy
Write-Host ""
Write-Host "已切换到 HOME 模式:已取消本机显式代理。" -ForegroundColor Green
Write-Host "本机环境变量、Windows 系统代理、Git/npm/yarn/pnpm、Codex/Claude 代理配置均已清除。" -ForegroundColor Yellow
Write-Host "建议重启 Codex App 和 Claude Code,让新配置完全生效。" -ForegroundColor Yellow
}
function Switch-Outside {
Set-ProxyEnv -HttpProxy $LocalHttp -SocksProxy $LocalSocks
Enable-SystemProxy -ProxyServer $LocalSystemProxy
Set-ToolProxy -HttpProxy $LocalHttp -SocksProxy $LocalSocks
Set-CodexProxy -HttpProxy $LocalHttp -SocksProxy $LocalSocks
Set-ClaudeProxy -HttpProxy $LocalHttp
Write-Host ""
Write-Host "已切换到 OUTSIDE 模式:本机 v2rayN mixed 代理 127.0.0.1:10808。" -ForegroundColor Green
Write-Host "Windows 环境变量、Windows 系统代理、Git/npm/yarn/pnpm、Codex/Claude 均已指向 127.0.0.1:10808。" -ForegroundColor Yellow
Write-Host "请确认 v2rayN 正在运行,并且 mixed 端口是 10808。" -ForegroundColor Yellow
Write-Host "Claude Code 仅写入 HTTP/HTTPS 代理,不写入 SOCKS 代理。" -ForegroundColor Yellow
Write-Host "建议重启 Codex App 和 Claude Code,让新配置完全生效。" -ForegroundColor Yellow
}
switch ($Mode) {
"home" {
Switch-Home
}
"outside" {
Switch-Outside
}
"status" {
Show-ProxyStatus
}
}
config.toml.bak 与 settings.json.bak(同目录,覆盖式备份,无时间戳);Codex 管理块由 # >>> proxy-switch managed 与 # <<< proxy-switch managed 标记,po / ph 均可重复幂等执行。Profile 把 proxy-switch.ps1 包装成 px 函数,再为三种模式提供别名。脚本是在子 PowerShell 进程中执行的,所以执行后 Sync-CurrentProxyEnv 会把用户级环境变量同步回当前窗口。
OUTSIDE:开启代理。
HOME:取消代理。
STATUS:查看当前状态。
统一入口:px h/o/s。
# ============================================================
# PowerShell Profile for Dan
# 作用:
# 提供代理切换快捷命令
#
# 依赖脚本:
# C:\Users\Dan\Documents\PowerShell\proxy-switch.ps1
#
# 快捷命令:
# px h / ph -> HOME 模式:清除本机显式代理
# px o / po -> OUTSIDE 模式:开启本机 v2rayN 127.0.0.1:10808
# px s / psw -> 查看当前代理状态
#
# 说明:
# proxy-switch.ps1 会在子 PowerShell 进程里执行。
# 子进程可以修改 Windows 用户级环境变量,
# 但不会自动刷新当前 PowerShell 窗口的 $env:。
#
# 所以这里额外加入 Sync-CurrentProxyEnv,
# 每次执行 px / ph / po / psw 后,
# 自动把当前窗口的环境变量同步到最新状态。
# ============================================================
$global:ProxySwitchScript = "C:\Users\Dan\Documents\PowerShell\proxy-switch.ps1"
function Sync-CurrentProxyEnv {
$names = @(
"http_proxy",
"https_proxy",
"HTTP_PROXY",
"HTTPS_PROXY",
"all_proxy",
"ALL_PROXY",
"no_proxy",
"NO_PROXY"
)
foreach ($name in $names) {
$value = [Environment]::GetEnvironmentVariable($name, "User")
if ([string]::IsNullOrEmpty($value)) {
Remove-Item "Env:\$name" -ErrorAction SilentlyContinue
} else {
Set-Item "Env:\$name" $value
}
}
}
function px {
param(
[Parameter(Position = 0)]
[ValidateSet("home", "h", "outside", "out", "o", "status", "s")]
[string]$Mode = "status"
)
if (!(Test-Path $global:ProxySwitchScript)) {
Write-Host ""
Write-Host "proxy-switch.ps1 not found:" -ForegroundColor Red
Write-Host $global:ProxySwitchScript -ForegroundColor Yellow
Write-Host ""
return
}
switch ($Mode) {
"h" { $realMode = "home" }
"home" { $realMode = "home" }
"o" { $realMode = "outside" }
"out" { $realMode = "outside" }
"outside" { $realMode = "outside" }
"s" { $realMode = "status" }
"status" { $realMode = "status" }
}
Write-Host ""
Write-Host "Running proxy-switch mode: $realMode" -ForegroundColor Cyan
Write-Host ""
pwsh.exe -NoProfile -ExecutionPolicy Bypass -File $global:ProxySwitchScript -Mode $realMode
# 同步当前 PowerShell 窗口的代理环境变量
Sync-CurrentProxyEnv
}
function ph {
px home
}
function po {
px outside
}
function psw {
px status
}
function proxy-help {
Write-Host ""
Write-Host "Proxy Switch Commands" -ForegroundColor Cyan
Write-Host "--------------------------------"
Write-Host "ph -> home mode, clear local explicit proxy"
Write-Host "po -> outside mode, local v2rayN 127.0.0.1:10808"
Write-Host "psw -> show proxy status"
Write-Host ""
Write-Host "px h -> same as ph"
Write-Host "px o -> same as po"
Write-Host "px s -> same as psw"
Write-Host ""
Write-Host "After switching, current PowerShell env is synced automatically." -ForegroundColor Yellow
Write-Host ""
}
proxy-switch.ps1 放到 PowerShell 目录po / ph / psw 验证notepad "C:\Users\Dan\Documents\PowerShell\proxy-switch.ps1"
$PROFILE
notepad $PROFILE
. $PROFILE
po # 开启代理(OUTSIDE)
ph # 取消代理(HOME)
psw # 查看状态(STATUS)
# 等价写法
px o
px h
px s
pwsh -ExecutionPolicy Bypass -File "C:\Users\Dan\Documents\PowerShell\proxy-switch.ps1" -Mode outside
pwsh -ExecutionPolicy Bypass -File "C:\Users\Dan\Documents\PowerShell\proxy-switch.ps1" -Mode home
pwsh -ExecutionPolicy Bypass -File "C:\Users\Dan\Documents\PowerShell\proxy-switch.ps1" -Mode status
po、ph、psw。执行后当前 PowerShell 窗口的 $env: 会自动同步,不必手动重开终端。不要凭感觉判断代理有没有生效。链路问题大多出现在三处:v2rayN 自己没起来、终端没读到环境变量、工具没有读环境变量。
echo $env:http_proxy
echo $env:https_proxy
echo $env:all_proxy
netstat -ano | findstr 10808
Get-ItemProperty "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings" |
Select-Object ProxyEnable, ProxyServer
git config --global --get http.proxy
npm config get proxy
pnpm config get proxy
Get-Content "$env:USERPROFILE\.claude\settings.json"
curl.exe -I https://api.openai.com
echo $env:http_proxy、v2rayN 是否运行、10808 是否监听、config.toml 是否有托管块,然后重启 Codex App。settings.json 是否包含 env 字段及 HTTP_PROXY / HTTPS_PROXY / NO_PROXY 三个键,确认后重启 Claude Code。git config --global --get http.proxy、npm config get proxy,再检查环境变量。HTTP/1.1 200 Connection established 说明 HTTPS 隧道已经通过代理建立。后续 401 / 403 / 404 不一定代表代理没生效,更可能是凭据或 URL 问题。config.toml 或 settings.json 后建议重启 Codex App 与 Claude Code,否则它们仍在用旧配置启动子进程 / 会话。