Analyzed web search tool commit and config.
UnderstandExamined Codex tool specifications and enums.
UnderstandConfirmed only web search is server-side tool.
Verifyhave a look at this commit: https://github.com/mitsuhiko/pi-mono/commit/2b7e67873a88ef1ef76c40c988b1b218f4c55c14
Anthropic server-side web-search tool docs
The web search tool gives Claude direct access to real-time web content, allowing it to answer questions with up-to-date information beyond its knowledge cutoff. Claude automatically cites sources from search results as part of its answer.
Please reach out through our [feedback form](https://forms.gle/sWjBtsrNEY2oKGuE8) to share your experience with the web search tool.Web search is available on:
claude-sonnet-4-5-20250929)claude-sonnet-4-20250514)claude-3-7-sonnet-20250219)claude-haiku-4-5-20251001)claude-3-5-haiku-latest)claude-opus-4-5-20251101)claude-opus-4-1-20250805)claude-opus-4-20250514)When you add the web search tool to your API request:
Provide the web search tool in your API request:
```bash Shell curl https://api.anthropic.com/v1/messages \ --header "x-api-key: $ANTHROPIC_API_KEY" \ --header "anthropic-version: 2023-06-01" \ --header "content-type: application/json" \ --data '{ "model": "claude-sonnet-4-5", "max_tokens": 1024, "messages": [ { "role": "user", "content": "What is the weather in NYC?" } ], "tools": [{ "type": "web_search_20250305", "name": "web_search", "max_uses": 5 }] }' ```import anthropic
client = anthropic.Anthropic()
response = client.messages.create( model="claude-sonnet-4-5", max_tokens=[REDACTED] messages=[ { "role": "user", "content": "What's the weather in NYC?" } ], tools=[{ "type": "web_search_20250305", "name": "web_search", "max_uses": 5 }])print(response)import { Anthropic } from '@anthropic-ai/sdk';
const anthropic = new Anthropic();
async function main() { const response = await anthropic.messages.create({ model: "claude-sonnet-4-5", max_tokens: 1024, messages: [ { role: "user", content: "What's the weather in NYC?" } ], tools: [{ type: "web_search_20250305", name: "web_search", max_uses: 5 }] });
console.log(response);}
main().catch(console.error);The web search tool supports the following parameters:
{ "type": "web_search_20250305", "name": "web_search",
// Optional: Limit the number of searches per request "max_uses": 5,
// Optional: Only include results from these domains "allowed_domains": ["example.com", "trusteddomain.org"],
// Optional: Never include results from these domains "blocked_domains": ["untrustedsource.com"],
// Optional: Localize search results "user_location": { "type": "approximate", "city": "San Francisco", "region": "California", "country": "US", "timezone": "America/Los_Angeles" }}The max_uses parameter limits the number of searches performed. If Claude attempts more searches than allowed, the web_search_tool_result will be an error with the max_uses_exceeded error code.
When using domain filters:
example.com instead of https://example.com)example.com covers docs.example.com)docs.example.com returns only results from that subdomain, not from example.com or api.example.com)example.com/blog matches example.com/blog/post-1)allowed_domains or blocked_domains, but not both in the same request.Wildcard support:
*) is allowed per domain entry, and it must appear after the domain part (in the path)example.com/*, example.com/*/articles*.example.com, ex*.com, example.com/*/news/*Invalid domain formats will return an invalid_tool_input tool error.
The user_location parameter allows you to localize search results based on a user's location.
type: The type of location (must be approximate)city: The city nameregion: The region or statecountry: The countrytimezone: The IANA timezone ID.Here's an example response structure:
{ "role": "assistant", "content": [ // 1. Claude's decision to search { "type": "text", "text": "I'll search for when Claude Shannon was born." }, // 2. The search query used { "type": "server_tool_use", "id": "srvtoolu_01WYG3ziw53XMcoyKL4XcZmE", "name": "web_search", "input": { "query": "claude shannon birth date" } }, // 3. Search results { "type": "web_search_tool_result", "tool_use_id": "srvtoolu_01WYG3ziw53XMcoyKL4XcZmE", "content": [ { "type": "web_search_result", "url": "https://en.wikipedia.org/wiki/Claude_Shannon", "title": "Claude Shannon - Wikipedia", "encrypted_content": "EqgfCioIARgBIiQ3YTAwMjY1Mi1mZjM5LTQ1NGUtODgxNC1kNjNjNTk1ZWI3Y...", "page_age": "April 30, 2025" } ] }, { "text": "Based on the search results, ", "type": "text" }, // 4. Claude's response with citations { "text": "Claude Shannon was born on April 30, 1916, in Petoskey, Michigan", "type": "text", "citations": [ { "type": "web_search_result_location", "url": "https://en.wikipedia.org/wiki/Claude_Shannon", "title": "Claude Shannon - Wikipedia", "encrypted_index": "Eo8BCioIAhgBIiQyYjQ0OWJmZi1lNm..", "cited_text": "Claude Elwood Shannon (April 30, 1916 – February 24, 2001) was an American mathematician, electrical engineer, computer scientist, cryptographer and i..." } ] } ], "id": "msg_a930390d3a", "usage": { "input_tokens": 6039, "output_tokens": 931, "server_tool_use": { "web_search_requests": 1 } }, "stop_reason": "end_turn"}Search results include:
url: The URL of the source pagetitle: The title of the source pagepage_age: When the site was last updatedencrypted_content: Encrypted content that must be passed back in multi-turn conversations for citationsCitations are always enabled for web search, and each web_search_result_location includes:
url: The URL of the cited sourcetitle: The title of the cited sourceencrypted_index: A reference that must be passed back for multi-turn conversations.cited_text: Up to 150 characters of the cited contentThe web search citation fields cited_text, title, and url do not count towards input or output token usage.
When the web search tool encounters an error (such as hitting rate limits), the Claude API still returns a 200 (success) response. The error is represented within the response body using the following structure:
{ "type": "web_search_tool_result", "tool_use_id": "servertoolu_a93jad", "content": { "type": "web_search_tool_result_error", "error_code": "max_uses_exceeded" }}These are the possible error codes:
too_many_requests: Rate limit exceededinvalid_input: Invalid search query parametermax_uses_exceeded: Maximum web search tool uses exceededquery_too_long: Query exceeds maximum lengthunavailable: An internal error occurredpause_turn stop reasonThe response may include a pause_turn stop reason, which indicates that the API paused a long-running turn. You may provide the response back as-is in a subsequent request to let Claude continue its turn, or modify the content if you wish to interrupt the conversation.
Web search works with prompt caching. To enable prompt caching, add at least one cache_control breakpoint in your request. The system will automatically cache up until the last web_search_tool_result block when executing the tool.
For multi-turn conversations, set a cache_control breakpoint on or after the last web_search_tool_result block to reuse cached content.
For example, to use prompt caching with web search for a multi-turn conversation:
```python import anthropicclient = anthropic.Anthropic()
messages = [ { "role": "user", "content": "What's the current weather in San Francisco today?" } ]
response1 = client.messages.create( model="claude-sonnet-4-5", max_tokens=[REDACTED] messages=messages, tools=[{ "type": "web_search_20250305", "name": "web_search", "user_location": { "type": "approximate", "city": "San Francisco", "region": "California", "country": "US", "timezone": "America/Los_Angeles" } }] )
messages.append({ "role": "assistant", "content": response1.content })
messages.append({ "role": "user", "content": "Should I expect rain later this week?", "cache_control": {"type": "ephemeral"} # Cache up to this point })
response2 = client.messages.create( model="claude-sonnet-4-5", max_tokens=[REDACTED] messages=messages, tools=[{ "type": "web_search_20250305", "name": "web_search", "user_location": { "type": "approximate", "city": "San Francisco", "region": "California", "country": "US", "timezone": "America/Los_Angeles" } }] )
print(f"Cache read tokens: {response2.usage.get('cache_read_input_tokens', 0)}")
</CodeGroup>
## Streaming
With streaming enabled, you'll receive search events as part of the stream. There will be a pause while the search executes:
```javascriptevent: message_startdata: {"type": "message_start", "message": {"id": "msg_abc123", "type": "message"}}
event: content_block_startdata: {"type": "content_block_start", "index": 0, "content_block": {"type": "text", "text": ""}}
// Claude's decision to search
event: content_block_startdata: {"type": "content_block_start", "index": 1, "content_block": {"type": "server_tool_use", "id": "srvtoolu_xyz789", "name": "web_search"}}
// Search query streamedevent: content_block_deltadata: {"type": "content_block_delta", "index": 1, "delta": {"type": "input_json_delta", "partial_json": "{\"query\":\"latest quantum computing breakthroughs 2025\"}"}}
// Pause while search executes
// Search results streamedevent: content_block_startdata: {"type": "content_block_start", "index": 2, "content_block": {"type": "web_search_tool_result", "tool_use_id": "srvtoolu_xyz789", "content": [{"type": "web_search_result", "title": "Quantum Computing Breakthroughs in 2025", "url": "https://example.com"}]}}
// Claude's response with citations (omitted in this example)You can include the web search tool in the Messages Batches API. Web search tool calls through the Messages Batches API are priced the same as those in regular Messages API requests.
Web search usage is charged in addition to token usage:
"usage": { "input_tokens": 105, "output_tokens": 6039, "cache_read_input_tokens": 7123, "cache_creation_input_tokens": 7345, "server_tool_use": { "web_search_requests": 1 }}Web search is available on the Claude API for ** +424 lines0 per 1,000 searches**, plus standard token costs for search-generated content. Web search results retrieved throughout a conversation are counted as input tokens, in search iterations executed during a single turn and in subsequent conversation turns.
Each web search counts as one use, regardless of the number of results returned. If an error occurs during web search, the web search will not be billed.
clone the openai/codex repo and see how they do websearch
i propose we formalize this properly. passing a tool called web_search sucks. this should be encoded via StreamOptions (and hence SimplifiedStreamOptions) in some way. providers are free to ignore it. we might want to add additional server-side tools in the future.
that's for "how to enable this in both pi-ai and pi-coding-agent". the next issue is how we combine this with tools specified by the provider. it appears for anthropic, we add a web_search tool if enabled. this can clash with user provided tools, so user provided tools need to be renamed in that case before being passed to anthropic. we already do some kind of renaming in the anthropic provider (for the anthropic endpoint). when sending to the llm endpoint the server side web search must be called web_search, while any user provided tool with name web_search must be called user_web_search. when persisting to the pi-ai context, we need to rename the server side tool calls (and results if they contain the tool name) from web_search to something that uniquely identifies it as a server side web_search. when the context is later serialized for the provider again, we need to do the name swapping again for old tool calls/results.
finally, we also need to deal with the tool result. from what i can gather in the anthropic docs, they return a content signature along with other shit. i suppose since tool results are free form anyways for the most part, that's fine. however, coding-agent @packages/coding-agent/src/modes/interactive/components/tool-execution.ts may have to accomodate that somehow?
Planning repo cloning and commit inspection
Preparing to clone the relevant repos as the user requested and inspect the specified commit to analyze their websearch implementation before reporting findings.
Deciding to clone both repos for commit inspection
Planning to clone both repos into temporary directories to examine the commit directly using git commands, ensuring compliance by using bash for file operations and read tool for file contents as required.
>lsStarting codebase exploration
>mkdir -p /tmp/pi-review && cd /tmp/pi-review && git clone https://github.com/openai/codex.gitSearching Codex for web search references
>cd /tmp/pi-review/codex && rg -n "web_search|websearch|search"Listing source files
I'm listing files in codex-rs/core/src to locate web search-related modules for deeper inspection.
>cd /tmp/pi-review/codex && ls codex-rs/core/srcChecking the web_search.rs file
Planning config inspection and repo cloning
I'm preparing to locate how web_search_mode is enabled by inspecting config files like config/mod.rs and tools/spec.rs, planning to use targeted partial reads with offsets. I'll clone the repo to access commit diffs and relevant files safely.
>cd /tmp/pi-review && git clone https://github.com/mitsuhiko/pi-mono.git mitsu-pi-monoShowing latest commit
I'm displaying the details of the most recent commit to review changes and context.
>cd /tmp/pi-review/mitsu-pi-mono && git show 2b7e67873a88ef1ef76c40c988b1b218f4c55c14Planning targeted code inspection
I'm focusing on the web_search tool usage in the codebase, pinpointing relevant sections in core/src/tools/spec.rs by searching for WebSearchMode to read those segments selectively.
>cd /tmp/pi-review/codex && rg -n "WebSearchMode|web_search" codex-rs/core/src/tools/spec.rsPlanning partial file read
I'm preparing to read the tools/spec file starting at offset 1360.
Locating web_search_mode config
I'm searching for web_search_mode definitions in the config module to understand how it's set up and whether it needs separation for the CLI. I'll inspect the relevant block around line 900.
Locating web search mode config
I'm checking around line 1230 in config/mod.rs to understand the web search mode setup, using a read with offset to pinpoint relevant details.
Investigating web_search usage in client_common.rs
I'm checking the client_common.rs file around the web_search comment to understand its role and whether it fits the OpenAI tools spec or client context.
Identifying web_search config and headers
I'm noting that the tool spec includes web_search and there's a config named web_search_mode plus a header x-oai-web-search-eligible, potentially handled in the client code around codex-rs/core/src/client.rs. Next, I'll explore that file to confirm usage and integration points.
Analyzing web search integration
I'm assessing the recent commit adding the web_search tool and how the codex repo implements web search via WebSearchMode and tool specs. The user proposes formalizing this in StreamOptions and renaming; I'll prepare an analysis of the current commit and codex approach to provide informed feedback and suggest next steps.
Analyzing tool injection and renaming
Codex seems to merge the web_search tool by injecting it into the tool spec list without renaming, also setting a header for eligibility; the pi-mono commit introduces a new web_search tool and proposes StreamOptions changes. Next step is verifying naming and injection details in the current repo for clear analysis and referencing relevant files.
Planning to review tool execution code
The commit adds the web_search tool using a special name and flags like isWebSearchTool; next, I'll check the coding-agent's tool execution code to clarify how it runs tools, focusing on the specified file.
Checking existing Anthropics provider rename
I'm inspecting the current Anthropics provider code to see if there's an existing renaming approach for OAuth or similar tools that informs how to handle the server-side web-search tool.
Proposing web search integration approach
Planning to formalize web search support by adding a webSearch option in stream settings to control provider injection. Also considering name mapping to avoid user tool conflicts, with internal renaming and context/message transformations to handle tool calls and results consistently. Next, I'll analyze existing transformMessages in the AI providers for integration details.
Planning line numbering approach
I'll use rg -n to find relevant code sections with line numbers for citations since reading files directly doesn't show line numbers and using nl may be disallowed; this ensures proper line references for commit and codex details.
Confirming line number references via rg
I'll gather exact line numbers for key tokens in codex and mitsu files using rg -n to provide precise file and line citations for tool specs, config, client code, and commit additions, ensuring all references are supported by explicit line info.
>cd /tmp/pi-review/mitsu-pi-mono && rg -n "WEB_SEARCH_TOOL_NAME|web_search_20250305|web_search" packages/ai/src/utils/web-search.ts packages/ai/src/providers/anthropic.ts packages/ai/src/providers/openai-responses-shared.ts packages/ai/src/providers/openai-codex-responses.tsInvestigating missing file in repo
I'm verifying whether the file exists in the target commit or branch since cloning after the commit should include it, considering possible branch differences affecting file presence.
>cd /tmp/pi-review/mitsu-pi-mono && ls packages/ai/src/utilsClarifying file reading via git show
I'm verifying that using git show <commit>:path to read committed files is distinct from using cat or sed and aligns with allowed commands since it accesses file content directly from Git objects rather than the working tree.
Planning referencing strategy for websearch commit
I'm deciding to summarize how Codex handles websearch via config and tool spec without full file reading, using rg -n to get precise line numbers for key patterns instead of reading committed files directly.
>cd /tmp/pi-review/codex && rg -n "WebSearchMode::Cached" codex-rs/core/src/tools/spec.rsLocating WebSearchMode and ToolSpec lines
I'm identifying exact line numbers for WebSearchMode handling and ToolSpec definition to reference them precisely in codex-rs/core source files.
>cd /tmp/pi-review/codex && rg -n "WebSearch" codex-rs/core/src/client_common.rsSearching header usage
I'm searching for the line number of the x-oai-web-search-eligible header in client.rs to locate its definition or usage.
>cd /tmp/pi-review/codex && rg -n "WEB_SEARCH_ELIGIBLE_HEADER|web_search" codex-rs/core/src/client.rsLocating config web_search
I'm searching for the web_search config in config/mod.rs using line numbers to pinpoint its definition.
>cd /tmp/pi-review/codex && rg -n "web_search" codex-rs/core/src/config/mod.rsPlanning git checkout for file inspection
I'll checkout the specific commit in the mitsu repo worktree to access the needed files, then use the read tool to inspect them since the files aren't in the current tree.
>cd /tmp/pi-review/mitsu-pi-mono && git checkout 2b7e67873a88ef1ef76c40c988b1b218f4c55c14Planning line number extraction
I'll rely on ripgrep in mitsu to obtain line numbers from relevant files instead of reading the file contents directly.
>cd /tmp/pi-review/mitsu-pi-mono && rg -n "WEB_SEARCH_TOOL_NAME|WEB_SEARCH_TOOL_DESCRIPTION|web_search_20250305" packages/ai/src/utils/web-search.ts packages/ai/src/providers/anthropic.tsPlanning line number extraction
I'll use ripgrep to get line numbers for OpenAI Codex and OpenAI web search responses to aid precise referencing.
>cd /tmp/pi-review/mitsu-pi-mono && rg -n "web_search" packages/ai/src/providers/openai-responses-shared.ts packages/ai/src/providers/openai-codex-responses.tsLocating buildHeaders usage
I'm searching for line numbers of buildHeaders in openai-codex-responses, focusing on x-oai-web-search-eligible to pinpoint its exact location for reference.
>cd /tmp/pi-review/mitsu-pi-mono && rg -n "web_search" packages/ai/src/providers/openai-codex-responses.tsSearching for web search usage patterns
>cd /tmp/pi-review/mitsu-pi-mono && rg -n "webSearch" packages/ai/src/providers/openai-codex-responses.tsProposing formal web-search tool integration
Planning to formalize web-search tool support by adding a typed serverTools.webSearch option in StreamOptions with provider-specific fields and rename rules, plus internal naming to avoid collisions and convenience mappings from CLI tool flags.
Summarizing web-search tool handling and formalization proposal
Reviewed OpenAI Codex and mitsu commit approaches: Codex treats web search as a config-driven non-function tool with WebSearchMode and sets a request header, while mitsu adds a dummy web_search tool detected by providers. Proposed formalization adds serverTools.webSearch in StreamOptions with provider-specific fields and internal renaming (__server_web_search) to avoid collisions. Noted Anthropic’s server tool responses use content blocks like server_tool_use and web_search_tool_result which need new parsing to fully support. Suggested coding-agent treat server tool results as generic tool output without local execution. Included references to relevant source files and lines for context and invite clarification or next steps.
Findings from codex and the commit, plus how this maps to your proposal.
Codex web search shape
web_search that resolves to a WebSearchMode enum. It is not modeled as a user tool. See codex-rs/core/src/config/mod.rs:920 and codex-rs/core/src/config/mod.rs:1230.ToolSpec::WebSearch with optional external_web_access. That decides cached versus live search. See codex-rs/core/src/client_common.rs:177 and codex-rs/core/src/tools/spec.rs:1383.x-oai-web-search-eligible based on the resolved mode. See codex-rs/core/src/client.rs:70 and codex-rs/core/src/client.rs:704.What the commit does
/tmp/pi-review/mitsu-pi-mono/packages/ai/src/utils/web-search.ts:3.type: "web_search_20250305" when that tool is present. See /tmp/pi-review/mitsu-pi-mono/packages/ai/src/providers/anthropic.ts:698.{ type: "web_search" }. See /tmp/pi-review/mitsu-pi-mono/packages/ai/src/providers/openai-responses-shared.ts:268.x-oai-web-search-eligible based on that tool. See /tmp/pi-review/mitsu-pi-mono/packages/ai/src/providers/openai-codex-responses.ts:446.Proposal fit and gaps
StreamOptions.webSearch or StreamOptions.serverTools would be a cleaner API than a fake tool. I suggest a provider agnostic shape like:
webSearch?: { enabled: boolean; mode?: "cached" | "live"; maxUses?; allowedDomains?; blockedDomains?; userLocation? }mode to external_web_access and still send the eligibility header. Anthropic can ignore mode and map the rest to web_search_20250305.web_search. Any user tool called web_search has to be renamed in the outbound payload and then mapped back when persisting and replaying context.
server_web_search and map to web_search only at the provider boundary. That prevents collisions and reduces special casing.convertMessages and the streaming event mapping.server_tool_use and web_search_tool_result content blocks. The current Anthropic stream handler only processes tool_use. Without changes, the web search call and result may not roundtrip into ToolCall and ToolResult messages. That is a functional gap that needs addressing when you formalize this.packages/coding-agent/src/modes/interactive/components/tool-execution.ts currently renders tool outputs generically. If you store server web search results as standard tool results, it will display them fine. If you keep them as assistant content blocks, no change is needed. Consider a custom renderer if you want to hide encrypted fields or show citations, but it is optional.If you want, I can draft a concrete API shape for StreamOptions and a mapping plan for Anthropic and OpenAI.
does the codex codebase have any other server side tool support?
Clarifying server-side tools
Only web_search is a server-defined tool in codex; other tools like local_shell and view_image are local/function tools. The references are in the code's ToolSpec enum, where WebSearch is the sole non-function server tool.
I only see web search as a server-side tool in codex. The only non function, non local tool in the tool spec enum is ToolSpec::WebSearch, and the request headers include x-oai-web-search-eligible. Everything else is either function tools or local shell tooling. See codex-rs/core/src/client_common.rs:171 and codex-rs/core/src/tools/spec.rs:1383.
import anthropic
client = anthropic.Anthropic()
response = client.messages.create( model="claude-sonnet-4-5", max_tokens=[REDACTED] messages=[ { "role": "user", "content": "What's the weather in NYC?" } ], tools=[{ "type": "web_search_20250305", "name": "web_search", "max_uses": 5 }])print(response)import { Anthropic } from '@anthropic-ai/sdk';
const anthropic = new Anthropic();
async function main() { const response = await anthropic.messages.create({ model: "claude-sonnet-4-5", max_tokens: 1024, messages: [ { role: "user", content: "What's the weather in NYC?" } ], tools: [{ type: "web_search_20250305", name: "web_search", max_uses: 5 }] });
console.log(response);}
main().catch(console.error);{ "type": "web_search_20250305", "name": "web_search",
// Optional: Limit the number of searches per request "max_uses": 5,
// Optional: Only include results from these domains "allowed_domains": ["example.com", "trusteddomain.org"],
// Optional: Never include results from these domains "blocked_domains": ["untrustedsource.com"],
// Optional: Localize search results "user_location": { "type": "approximate", "city": "San Francisco", "region": "California", "country": "US", "timezone": "America/Los_Angeles" }}{ "role": "assistant", "content": [ // 1. Claude's decision to search { "type": "text", "text": "I'll search for when Claude Shannon was born." }, // 2. The search query used { "type": "server_tool_use", "id": "srvtoolu_01WYG3ziw53XMcoyKL4XcZmE", "name": "web_search", "input": { "query": "claude shannon birth date" } }, // 3. Search results { "type": "web_search_tool_result", "tool_use_id": "srvtoolu_01WYG3ziw53XMcoyKL4XcZmE", "content": [ { "type": "web_search_result", "url": "https://en.wikipedia.org/wiki/Claude_Shannon", "title": "Claude Shannon - Wikipedia", "encrypted_content": "EqgfCioIARgBIiQ3YTAwMjY1Mi1mZjM5LTQ1NGUtODgxNC1kNjNjNTk1ZWI3Y...", "page_age": "April 30, 2025" } ] }, { "text": "Based on the search results, ", "type": "text" }, // 4. Claude's response with citations { "text": "Claude Shannon was born on April 30, 1916, in Petoskey, Michigan", "type": "text", "citations": [ { "type": "web_search_result_location", "url": "https://en.wikipedia.org/wiki/Claude_Shannon", "title": "Claude Shannon - Wikipedia", "encrypted_index": "Eo8BCioIAhgBIiQyYjQ0OWJmZi1lNm..", "cited_text": "Claude Elwood Shannon (April 30, 1916 – February 24, 2001) was an American mathematician, electrical engineer, computer scientist, cryptographer and i..." } ] } ], "id": "msg_a930390d3a", "usage": { "input_tokens": 6039, "output_tokens": 931, "server_tool_use": { "web_search_requests": 1 } }, "stop_reason": "end_turn"}{ "type": "web_search_tool_result", "tool_use_id": "servertoolu_a93jad", "content": { "type": "web_search_tool_result_error", "error_code": "max_uses_exceeded" }}
</CodeGroup>
## Streaming
With streaming enabled, you'll receive search events as part of the stream. There will be a pause while the search executes:
```javascriptevent: message_startdata: {"type": "message_start", "message": {"id": "msg_abc123", "type": "message"}}
event: content_block_startdata: {"type": "content_block_start", "index": 0, "content_block": {"type": "text", "text": ""}}
// Claude's decision to search
event: content_block_startdata: {"type": "content_block_start", "index": 1, "content_block": {"type": "server_tool_use", "id": "srvtoolu_xyz789", "name": "web_search"}}
// Search query streamedevent: content_block_deltadata: {"type": "content_block_delta", "index": 1, "delta": {"type": "input_json_delta", "partial_json": "{\"query\":\"latest quantum computing breakthroughs 2025\"}"}}
// Pause while search executes
// Search results streamedevent: content_block_startdata: {"type": "content_block_start", "index": 2, "content_block": {"type": "web_search_tool_result", "tool_use_id": "srvtoolu_xyz789", "content": [{"type": "web_search_result", "title": "Quantum Computing Breakthroughs in 2025", "url": "https://example.com"}]}}
// Claude's response with citations (omitted in this example)"usage": { "input_tokens": 105, "output_tokens": 6039, "cache_read_input_tokens": 7123, "cache_creation_input_tokens": 7345, "server_tool_use": { "web_search_requests": 1 }}