Review found `127.0.0.2` routed through the proxy. The bypass list carries four literal loopback entries because that is all a consumer reading an environment can match, and `proxyForUrl` matched only those — leaving the rest of `127.0.0.0/8`, `0.0.0.0`, and the IPv4-mapped spellings routed through a proxy that could then reach them. Loopback is now recognised structurally, which a list entry cannot express; the published entries stay for the environment readers. The same review case exposed a wider one. `web_fetch` skips its address checks on a proxied hop, because the proxy resolves the origin — but a literal needs no resolution, so the skip bought nothing and let a proxy on this machine reach every private range those checks refuse, `169.254.169.254` included. A literal the checks would refuse now takes the validated path, where the existing refusal already covers it. Tests that proved a tunnelled hop used a loopback origin, which no policy can route through a proxy any more. They name a host only the proxy can answer for instead — closer to what a proxied request actually looks like. The user guide promised the proxy carried every outbound request including telemetry. It carries neither on an older Node, nor anything a model-authored script sends, so the promise is narrowed and the exceptions listed. A password in a proxy URL reaching every tool DSH runs is documented there too: it is how the variable already behaves, and worth knowing before putting one in.
description, kind
| description | kind |
|---|---|
| Package map for the web access capability family: the search/fetch service, its provider backends, and the model-facing tools that consume them. | package-group |
web/ — web access capability family
English | 中文
Summary
The web/ group gives the harness web access — searching the web and fetching URLs — through one provider-neutral service (ctx.web) and the backends and tools that use it. A deployment mounts one or more backends — Exa, Perplexity, or DeepSeek for search, anonymous HTTP(S) for fetch — and the service picks a usable provider per operation, so the model-facing tools stay stable while backends come and go. Six packages split the family: the web/ service that owns provider selection and errors, three search backends, one fetch backend, and tool-web/, which exposes web_search and web_fetch to the model. The group owns web access only: no browsing or extraction, no per-URL policy, and each backend keeps its own resource caps. Search and fetch deliberately share one service so selection, cancellation, errors, and configuration have a single owner.
Table of Contents
Packages
Six packages play the web roles; the subsystem reference owns the exhaustive vocabulary and contracts.
| Package | Role | ctx key |
|---|---|---|
web/ |
Search/fetch service: search and fetch URLs through interchangeable backends, one selection and error policy | ctx.web |
web-search-exa/ |
Searches the web through Exa | registers on ctx.web |
web-search-perplexity/ |
Searches the web through Perplexity | registers on ctx.web |
web-search-deepseek/ |
Searches the web through DeepSeek native search | registers on ctx.web |
web-fetch-http/ |
Fetches public HTTP(S) pages anonymously | registers on ctx.web |
tool-web/ |
Exposes web_search and web_fetch to the model |
registers on ctx.tools |
Related documentation
Start with the subsystem reference for the shared vocabulary, then the design decision behind the single provider-selection service.
- Web subsystem — the search/fetch requests and results, provider availability,
WebError, and public-address enforcement. - Web capability seam decision — why search and fetch share one provider-selection service.
Dev Note
Working context for maintainers — click to expand
None.