Skip to main content

Overview

Agents can search the web and fetch pages in real time using Anthropic’s server toolsweb_search and web_fetch. These are not custom ToolDefinition tools like connector tools; they run server-side within the Anthropic API and return results (including citations) as part of the streamed response. Web tools are workspace-scoped: an admin enables them per workspace and configures an allow-list of domains the agent can access.

Workspace configuration

Three fields on the workspaces table control web access:
FieldTypeDefaultDescription
web_search_enabledbooleantrueEnables the web_search server tool
web_fetch_enabledbooleantrueEnables the web_fetch server tool
web_allowed_domainsstring[]['help.sap.com']Domain allow-list (e.g. ['help.sap.com', '*.wikipedia.org'])
Both a toggle and at least one domain are required. If web_search_enabled is true but web_allowed_domains is empty or null, the tool is not added to the request. This prevents accidental unrestricted web access.

Domain validation

Domains are validated by validateWebDomains() in src/routes/workspaces.ts on create and update. Rules:
  • No scheme prefix — use sap.com, not https://sap.com
  • ASCII characters only
  • Wildcard subdomains supported — *.example.com matches any subdomain
  • Must match domain format: alphanumeric segments separated by dots, optional *. prefix
Domain restrictions are enforced server-side by the Anthropic API, not by our code. The allowed_domains array is passed directly in the server tool configuration.

Settings UI

Workspace admins configure web access in Settings → Web Access. Each workspace has:
  • Web Search checkbox — toggles web_search_enabled
  • Web Fetch checkbox — toggles web_fetch_enabled
  • Allowed Domains textarea — one domain per line (e.g. en.wikipedia.org, help.sap.com)

Server tool configuration

Web tools are built separately as serverTools and then merged into the tools array sent to Anthropic. In src/agents/agent.ts:
const serverTools = [];

if (this.webSearchEnabled && hasWebDomains) {
  serverTools.push({
    type: 'web_search_20250305',
    name: 'web_search',
    max_uses: 5,
    allowed_domains: this.webAllowedDomains,
  });
}

if (this.webFetchEnabled && hasWebDomains) {
  serverTools.push({
    type: 'web_fetch_20250910',
    name: 'web_fetch',
    max_uses: 10,
    allowed_domains: this.webAllowedDomains,
  });
}
ToolAPI typeMax uses per turnPurpose
web_searchweb_search_202503055Search the web, returns ranked results
web_fetchweb_fetch_2025091010Fetch and read a specific URL
web_fetch requires the beta header anthropic-beta: web-fetch-2025-09-10 in the request options. This is added automatically when serverTools includes a web_fetch entry.

Config refresh

Web configuration is not persisted to Durable Object storage. Instead, the agent holds webSearchEnabled, webFetchEnabled, and webAllowedDomains as in-memory fields that are refreshed from the incoming request payload on every:
  • POST /agents/:id/message — message request
  • POST /agents/:id/approve — approval request
This means workspace admins can toggle web access or update domains without restarting the agent — changes take effect on the next message.

Streaming and tool results

Web tool results arrive as special content block types during streaming:

Web search results

When Claude uses web_search, the stream emits a web_search_tool_result content block containing an array of web_search_result entries (each with url, title, page_age). The agent extracts these and broadcasts a tool_update WebSocket message so the frontend can display them in the ToolCard.

Web fetch results

When Claude uses web_fetch, the stream emits a web_fetch_tool_result content block with url and content title. These are similarly broadcast as tool_update messages.

No approval required

Web tools are read-only and execute automatically — they do not go through the approval flow.

Citations

When Claude’s response references information from web search or fetch results, the API includes citations on text content blocks. Each citation has:
interface Citation {
  type: string;       // e.g. 'web_search_result'
  url?: string;
  title?: string;
  cited_text?: string;
}

Extraction

In processResponse(), citations are extracted from each text block and collected across all text blocks in a response. They are stored on the Message object as citations?: Citation[].

Frontend rendering

MessageBubble.tsx renders a CitationList component below the message text when citations are present:
  • Citations are deduplicated by URL — if the same source is cited multiple times, it appears once
  • Displayed as a “Sources” section with numbered links ([1], [2], …)
  • Links open in a new tab (target="_blank", rel="noopener noreferrer")
  • Falls back to displaying the raw URL when no title is available

System prompt

When web tools are active, a conditional section is appended to the agent’s system prompt:
# Web Search and Web Fetch

You have access to real-time web search and page fetching, restricted to
approved domains for this workspace. Use web search when:
- The user asks about current events, recent updates, or time-sensitive information
- You need to verify SAP documentation, OSS notes, or community solutions
- Looking up error codes, patches, or known issues

Use web fetch when the user provides a URL or when search results contain
a page you need to read in full.

Always cite your sources — citations are included automatically from search results.
This section only appears when at least one web tool is enabled and domains are configured.

Key differences from SAP tools

AspectSAP toolsWeb tools
DefinitionToolDefinition interface in tool-definitions.tsAnthropic server tool protocol
ExecutionClient-side via execute() functionServer-side within Anthropic API
RegistrationsapTools record + buildSapTools()serverTools array on API request
ApprovalWrite tools require approvalAlways auto-execute (read-only)
Domain controlN/Aallowed_domains enforced by API
ResultsReturned as tool execution outputStreamed as special content blocks
CitationsN/AAutomatically included on text blocks