Restrict web search and web fetch domains
Control which sites an agent's web search and web fetch tools can reach, cap fetched content, and localize search results.
To control which sites the agent's web tools can reach, set a domain list on the web_search and web_fetch entries of the agent toolset. Each of these configs entries takes one of two lists:
allowed_domains: The tool can reach only these hosts.blocked_domains: The tool can never reach these hosts.
Each tool carries its own list, so web_search and web_fetch can have different restrictions.
Set domain lists on an agent
The following example creates an agent that limits web_search to two sites and blocks one host for web_fetch. It also sets user_location and max_content_tokens, which Settings describes. The example then prints the configs array from the response.
ant apply agent.md---
name: Research Agent
model: claude-opus-5-5
tools:
- type: agent_toolset_20260401
configs:
- type: web_search
name: web_search
allowed_domains: [docs.example.com, arxiv.org]
user_location:
type: approximate
country: US
timezone: America/Los_Angeles
- type: web_fetch
name: web_fetch
blocked_domains: [ads.example.com]
max_content_tokens: 50000
---ant apply creates the agent and prints its ID, not the configs array.
In the Claude Console, set allowed or blocked domains from the web_search and web_fetch rows of the Built-in tools card on the agent form. Set max_content_tokens and user_location in the Raw view of the agent's configuration.
Settings
In addition to enabled and permission_policy, the web tool entries accept the following settings:
| Setting | Applies to | Description |
|---|---|---|
allowed_domains | web_search, web_fetch | The only hosts the tool can reach. See Domain list rules. |
blocked_domains | web_search, web_fetch | Hosts the tool cannot reach. See Domain list rules. |
max_content_tokens | web_fetch | Caps the amount of fetched page content included in the context. Must be a positive integer. See content limits. |
user_location | web_search | Localizes search results. An object with the same fields as the Messages API user_location parameter. |
For how the SDKs type these entries, see Config entry types in the SDKs.
When a domain is not permitted
web_search omits results that its domain list does not permit. A web_fetch call for a URL that its domain list does not permit returns an error result to the agent. The agent.tool_result event has is_error: true, and its content names the error code url_not_allowed.
Domain list rules
These rules apply to allowed_domains and blocked_domains alike. A request that breaks one is rejected, as Validation errors describes.
- One list per entry: Set either
allowed_domainsorblocked_domainson an entry, not both. - List size: Each list holds 1 to 64 domains, each 1 to 255 characters.
- No empty lists: To apply no restriction, omit the field or send
null. - No duplicates: A domain can appear only once in a list.
www.example.comandexample.comcount as different domains.
What a listed domain matches
A listed domain matches that host and all of its subdomains. example.com covers docs.example.com, but docs.example.com does not cover example.com or api.example.com.
A leading www. is a subdomain like any other, so www.example.com does not cover example.com. List the bare domain to cover both.
Hostnames are compared without regard to case.
Domain format
Each domain is a registrable domain name, or a subdomain of one, written as a plain hostname. It can contain ASCII letters, digits, hyphens, underscores, and dots. A single trailing / is ignored.
| Not accepted | Example | Use instead |
|---|---|---|
| A scheme | https://example.com | example.com |
| A port | example.com:443 | example.com |
| A wildcard | *.example.com | example.com |
A path on a web_fetch domain | example.com/* | example.com |
| An IP address in any form, whether IPv4, IPv6, bracketed, or numeric shorthand | 127.1 | The site's domain name |
| A bare top-level domain or registry suffix | com, co.uk, gov.uk | A full domain such as example.co.uk |
| A single-label name | intranet | A full domain such as example.co.uk |
| Non-ASCII characters, as in an internationalized domain name | The xn-- (Punycode) form |
A domain is also rejected if it contains credentials or whitespace, or if one of its labels begins or ends with a hyphen. localhost and hosts ending in .localhost, .local, .internal, .localdomain, or .invalid are rejected too.
Path suffixes on web search domains
A web_search domain can carry a path suffix, such as example.com/blog. The path cannot contain spaces, ?, #, or any of the characters $ , | ^ !.
Prefer plain hostnames for web_search too. The search provider matches path suffixes as URL patterns rather than as strict host rules.
Validation errors
The API validates these settings when you create an agent or update an agent. It also validates them when you create or update a session that supplies tools.
Format and limit violations are rejected with a 400 invalid_request_error:
| Violation | Error message |
|---|---|
| An entry sets both lists. | Includes Only one of allowed_domains or blocked_domains may be set. |
| A list is empty. | Includes allowed_domains: Empty list of domains is ambiguous. Provide at least one domain or null. |
| A domain breaks a format rule. | Names the domain's list and zero-based position. For example, allowed_domains.0: IP addresses are not supported; provide a plain hostname like "example.com" |
On the same requests, the API also rejects three settings that depend on the search and fetch providers:
- A domain in
allowed_domainsthat Anthropic's crawler is not permitted to access. - A
user_location.countrythat the search provider does not support. The message ends inuser_location.country: not a country the search provider supports. - A
user_location.timezonethat is not a valid IANA name.
When an accepted setting is no longer valid
The session checks the configuration again when it first initializes the tool. If a setting that was accepted earlier is no longer valid at that point, the session emits a session.error event. It then returns to idle without retrying.
To continue the session:
- Fix the setting by updating the session's tools.
- Update the agent as well, so that new sessions start with the corrected configuration.
- Send a new
user.message.
Multiagent and outcome-driven sessions
In a multiagent session, every domain list that applies to a thread is enforced at the same time. An agent in the coordinator's roster is bound by three sets of lists:
- Its own
allowed_domainsandblocked_domains - Those of any agent that called it
- The coordinator's current lists
The settings combine as follows:
| Setting | How it combines |
|---|---|
allowed_domains | The tool can reach a host only if every list covers it. |
blocked_domains | The lists add together. |
max_content_tokens, user_location | Not combined. A thread uses the value from its own tool configuration if set. Otherwise it uses the value from the agent that called it, and otherwise the coordinator's current configuration. |
A roster agent can therefore narrow what a tool reaches but never widen it:
- A roster agent that sets
blocked_domainskeeps the coordinator'sallowed_domainsand blocks those hosts within it. - A roster agent that sets its own
allowed_domainscan reach only the hosts that both its list and the coordinator's list cover.
A {"type": "self"} roster entry has no web settings of its own and follows the coordinator's current settings.
If the combined allowed_domains lists have no domain in common, the tool stays available to that agent but every call fails. Each call returns a url_not_allowed error stating that no domain is permitted. The tool description tells the model the same. To avoid this, keep each roster agent's allowed_domains inside the coordinator's.
The grader in outcome-driven sessions runs without web_search and web_fetch, regardless of these settings.
Change the lists mid-session
You can change the lists on an idle session by updating its tools. The new lists apply to the rest of the session.
In a multiagent session, every thread applies the new lists from its next turn. The update does not change a roster agent's own lists. Those stay as the agent's definition set them when the session was created.
Differences from the Messages API tools
These settings use the same allowed_domains and blocked_domains fields as domain filtering on the Messages API server tools. Managed Agents differs in four ways:
- Each list is capped at 64 domains.
- Domains listed for
web_fetchcannot include a path. - Domains must be ASCII. The Messages API accepts Unicode entries, though it recommends against them.
max_uses,citations, andcache_controlare not available on the toolset.
Next steps
See the built-in tools, enable or disable them, and define custom tools.
Control when agent and MCP tools execute.
Control the sandbox's own outbound network access.
Coordinate multiple agents within a single session.
Was this page helpful?