# Admin proxy options: app/agent switches and an explicit proxy address

The sidebar user menu gains an admin-only "Proxy options" entry opening a settings dialog — server-global, stored in a new `server_settings` table and served by `GET/PUT /api/admin/settings` — implementing (and then extending) the long-specced 出网与系统代理 design so that using a proxy needs no environment variable at all.

- Two independent switches share one address:
  - **Application uses the proxy** (default on) — the server's own outbound traffic (LLM requests, the update check, image fetches). Node's built-in fetch ignores proxy variables, so the server routes all of its own traffic through an undici global dispatcher installed once at the entry. On with an address = that address for both http and https; on without = the `HTTP_PROXY` / `HTTPS_PROXY` environment variables (both spellings); off = always direct.
  - **Agent environment uses the proxy** (default on) — command-subprocess env policy. On with an address = inject `HTTP_PROXY`/`HTTPS_PROXY` (both spellings) plus the merged `NO_PROXY`, overriding inherited values; on without = pass the host environment through; off = strip the proxy variables (`NO_PROXY` kept). The SDK seam is `proxyEnv?: () => ProxyEnvPolicy | null` (strip / inject / null passthrough; absent = unchanged standalone behavior, subagents inherit).
- The proxy address accepts `http://host[:port]`, `https://host[:port]`, or bare `host[:port]` (normalized to `http://…`); anything else is `400 invalid_proxy_url`; empty clears back to "follow the system proxy". The dialog is a form with an explicit Save button (no-op with a toast when nothing changed); validation errors render inline.
- In every on-state the effective `NO_PROXY` always includes `localhost,127.0.0.1,::1`, keeping loopback traffic — readiness probes, SSE, workspace previews — off any proxy. Toggling applies to new connections immediately; no restart. The CLI-hosted server (`penguin web`) inherits the same coverage.
- Desktop: the shell resolves the OS proxy at launch (Electron `resolveProxy`; PAC `PROXY`/`HTTPS` results, SOCKS deliberately skipped — undici speaks HTTP(S) proxies only) and injects it into the embedded server's environment without overriding explicitly configured values — so on desktop, "follow the system proxy" really means the OS proxy settings.
- The interim single `useSystemProxy` switch (never released) is read once as the fallback default for both new switches when their keys are absent.
