How does opencode implement web search?

HEAD
6cd3a59desktop: cleanup
This post might have stale content, as HEAD is 786 commits ahead.

how does open code implements web search?

Avatar of google/gemini-3-flash
Gemini 3 Flash
commented

OpenCode implements web search primarily through its websearch and codesearch tools, which leverage Exa AI's hosted Model Context Protocol (MCP) service.

###Core Implementation

The implementation is found in packages/opencode/src/tool/websearch.ts and packages/opencode/src/tool/codesearch.ts.

####1. Web Search Tool (websearch)

This tool performs broad web searches. It works by sending a JSON-RPC request to Exa's hosted MCP endpoint:

  • Endpoint: https://mcp.exa.ai/mcp
  • Method: tools/call
  • Tool Name: web_search_exa
  • Parameters: It supports parameters like query, numResults, livecrawl (cached vs. live), and type (auto, fast, deep).

The tool processes the response as a Server-Sent Events (SSE) stream, specifically looking for data: lines that contain the search results in Markdown format.

####2. Code Search Tool (codesearch)

Similar to websearch, but optimized for finding technical documentation, API examples, and library usage.

  • Tool Name: get_code_context_exa
  • Parameters: Includes a tokensNum parameter (default 5000) to control the amount of context returned.

According to packages/opencode/src/tool/registry.ts, these tools are not active for all providers by default. They are enabled if:

  1. The model provider is opencode (OpenCode Zen).
  2. OR the environment variable OPENCODE_ENABLE_EXA is set to true or 1.
  3. OR experimental flags like OPENCODE_EXPERIMENTAL or OPENCODE_EXPERIMENTAL_EXA are active.

###Comparison with webfetch

OpenCode also includes a webfetch tool (packages/opencode/src/tool/webfetch.ts). While websearch is for discovery (finding information), webfetch is for retrieval (reading a specific URL). webfetch fetches raw HTML/text and converts it to Markdown using turndown.

###Permissions

Both tools are subject to OpenCode's permission system. Before execution, they trigger a permission check (e.g., permission: "websearch") to ensure the user has authorized the tool to perform searches.

Avatar of matiasngf
Matias Gonzalez
commented

how does codesearch works exactly?

Avatar of google/gemini-3-flash
Gemini 3 Flash
commented

The codesearch tool is a specialized tool for finding programming-related context (APIs, libraries, SDKs, and code patterns). It is implemented as a client for Exa AI's hosted Model Context Protocol (MCP) service.

Here is exactly how it works under the hood:

###1. Configuration and Availability

The tool is defined in packages/opencode/src/tool/codesearch.ts. It is only enabled if:

  • You are using the OpenCode Zen provider (opencode).
  • OR the environment variable OPENCODE_ENABLE_EXA is set to true or 1.

###2. Parameters

It accepts two parameters:

  • query: A string describing the programming concept or problem (e.g., "React useState hook examples").
  • tokensNum: An integer between 1000 and 50000 (default: 5000). This controls how much context (code snippets, documentation) is returned.

###3. Permission Check

Before execution, the tool calls ctx.ask to verify permissions. It uses the codesearch permission key. If your opencode.json has "codesearch": "ask", you will be prompted to approve the specific query.

###4. Communication Protocol (MCP over HTTP)

Instead of a standard REST API, it uses the Model Context Protocol (MCP) via JSON-RPC 2.0 over HTTP:

  • Endpoint: https://mcp.exa.ai/mcp
  • Method: POST
  • Headers: It requests application/json and text/event-stream.
  • Authentication: Notably, no API key is required. The tool connects to Exa's public/hosted MCP bridge directly.

###5. Request Payload

The tool constructs a JSON-RPC request to call the remote get_code_context_exa tool:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "get_code_context_exa",
    "arguments": {
      "query": "<your_query>",
      "tokensNum": 5000
    }
  }
}

###6. Streaming Response (SSE)

Exa returns the results as a Server-Sent Events (SSE) stream. The implementation:

  1. Waits for lines starting with data: .
  2. Parses the JSON data in those lines.
  3. Looks for result.content, which contains an array of results.
  4. Returns the text from the first content item as the tool's output.

###7. Execution Safeguards

  • Timeout: The request has a 30-second timeout (abortAfterAny(30000, ...)).
  • Error Handling: If the search fails or returns no results, it provides a descriptive error message suggesting the user be more specific about the library or framework.

###Comparison: codesearch vs websearch

While both use the same Exa MCP endpoint, they call different internal Exa tools:

  • websearch calls web_search_exa (optimized for general web discovery).
  • codesearch calls get_code_context_exa (optimized for extracting high-token-count code documentation and snippets).

END OF POST

How does opencode implement web search? — anomalyco/opencode