Skip to content

web search tool #309

Closed as not planned
Closed as not planned

Description

@adamdotdevin
No description provided.

Activity

  1. garrett-hopper commented on Aug 29, 2025

    @garrett-hopper

    Does this exist now? I see websearch.txt, but no corresponding websearch.ts implementation? (And websearch -> "Search" styling)
    @rekram1-node, can you point me to what closed this?

  2. garrett-hopper commented on Aug 29, 2025

    @garrett-hopper

    The title of the issue and contents of websearch.txt refer to actual search functionality rather than the web fetching supported by that tool.
    Should a different issue be opened?
    Though maybe web search should be left to MCP servers since there are few (if any?) free APIs for it?

  3. rekram1-node commented on Aug 29, 2025

    @rekram1-node
    Collaborator

    Ig you are correct they are different

  4. remorses commented on Sep 9, 2025

    @remorses
    Contributor

    I can open a PR to add websearch tool using Gemini search grounding tool, which can search and fetch pages and make a summary, very similar to how Claude Code works

    This tool would be enabled only for users that logged in with Gemini

    PR welcome?

  5. garrett-hopper commented on Sep 9, 2025

    @garrett-hopper

    Curious if Claude Code's builtin search could be used as well in a similar fashion for those using Anthropic Pro/Max logins. 🤔
    Would probably be ideal to have support for the providers' builtin tools when possible. Groq has builtin Exa search tool (https://console.groq.com/docs/browser-search) for openai/gpt-oss-120b and Tavily for their compound models (https://console.groq.com/docs/web-search). Not sure how difficult it'd be to support any/all of these.

  6. eugene-kim commented on Sep 12, 2025

    @eugene-kim

    @adamdotdevin @thdxr is search something opencode is planning on adding?

  7. trose commented on Sep 22, 2025

    @trose

    I've been using the python lib/cli ddgs with a lightweight local MCP wrapper and it's fantastic so far. Much faster & precise results for agent web searches than the builtin Cursor websearch I was using before. Note that the npm package by the same name is not a direct analog and lacks many of the features. I could take a crack at creating a direct typescript port of the python implementation if y'all were interested in integrating advanced search functionality.

  8. nikaro commented on Dec 23, 2025

    @nikaro

    I can see that currently there are websearch and codesearch tools behind the OPENCODE_ENABLE_EXA flag. It uses the Exa API under the hood.

  9. garrett-hopper commented on Dec 23, 2025

    @garrett-hopper

    Is that OPENCODE_ENABLE_EXA Zen only or can I provide my own Exa API key?

  10. nikaro commented on Dec 24, 2025

    @nikaro

    I've run OPENCODE_ENABLE_EXA=true opencode without API key (and without Zen either) and it worked 🤷
    I did not see anything about setting an API key in the opencode source code.
    I guess there is a free tier or something like that?

  11. 1 remaining item

  12. brennanmceachran commented on Dec 31, 2025

    @brennanmceachran

    I was surprised there was no search, so cooked a quick tool for opencode to use codex w/ search enabled to do some webresearch. I suppose it's a bit like amp's "Librarian" but with a bad ui. Anyway, it's working for me.

    Sharing in case it's helpful for someone else

    //.opencode/tool/webresearch.ts
    import { tool } from "@opencode-ai/plugin";
    
    const QUALITY_PRESETS = {
      fast: {
        effort: "low",
        directive: "Keep it quick; use only the most relevant sources.",
      },
      balanced: {
        effort: "medium",
        directive: "Cover the main angles; resolve contradictions if they appear.",
      },
      deep: {
        effort: "high",
        directive:
          "Follow second-order leads and resolve contradictions until extra sources stop adding value.",
      },
    } as const;
    
    type Quality = keyof typeof QUALITY_PRESETS;
    
    function buildPrompt({
      reason,
      query,
      additionalContext,
      quality,
    }: {
      reason: string;
      query: string;
      additionalContext?: string;
      quality: Quality;
    }) {
      const preset = QUALITY_PRESETS[quality];
      const contextBlock = additionalContext
        ? `Additional context (optional): ${additionalContext}`
        : "Additional context (optional):";
    
      return [
        "Hi, I’m stuck and need help with a research task.",
        "",
        `Reason: ${reason}`,
        `Search queries: ${query}`,
        contextBlock,
        `Depth: ${quality}`,
        "",
        "Please search the web and send back:",
        "- A 2-4 sentence summary",
        "- Key findings or caveats (bullets)",
        "- Sources with full URLs",
        "",
        "If anything is ambiguous, cover the plausible interpretations and state your assumptions instead of asking questions.",
        "Please don’t edit any code or files.",
        preset.directive,
      ].join("\n");
    }
    
    async function runCodex({
      prompt,
      effort,
      timeoutSeconds,
    }: {
      prompt: string;
      effort: string;
      timeoutSeconds?: number;
    }) {
      const args = [
        "exec",
        "--enable",
        "web_search_request",
        "--sandbox",
        "read-only",
        "-c",
        `model_reasoning_effort=${effort}`,
        prompt,
      ];
    
      const proc = Bun.spawn(["codex", ...args], {
        stdout: "pipe",
        stderr: "pipe",
      });
    
      let timeoutId: ReturnType<typeof setTimeout> | undefined;
      if (timeoutSeconds && timeoutSeconds > 0) {
        timeoutId = setTimeout(
          () => {
            proc.kill();
          },
          Math.round(timeoutSeconds * 1000),
        );
      }
    
      const [stdout, stderr] = await Promise.all([
        new Response(proc.stdout).text(),
        new Response(proc.stderr).text(),
      ]);
      const exitCode = await proc.exited;
      if (timeoutId) {
        clearTimeout(timeoutId);
      }
    
      if (exitCode !== 0) {
        const message =
          stderr.trim() || `codex exec failed with exit code ${exitCode}`;
        throw new Error(message);
      }
    
      return stdout.trim();
    }
    
    export default tool({
      description:
        "Run a web search and return a concise summary with source links. Use when you need current, verifiable information or citations.",
      args: {
        reason: tool.schema
          .string()
          .describe(
            "Describe the core reason you’re reaching for web search and the decision or output you’re aiming for.",
          ),
        query: tool.schema
          .string()
          .describe(
            'List the search queries you want run; use new lines or ";" to include multiple angles.',
          ),
        additional_context: tool.schema
          .string()
          .optional()
          .describe(
            "Add constraints or background: versions, product names, prior findings, relevant files/code, or must-include sources.",
          ),
        quality: tool.schema
          .enum(["fast", "balanced", "deep"])
          .describe(
            "Fast = quick scan, balanced = normal depth, deep = thorough with follow-up leads.",
          ),
        timeout: tool.schema
          .number()
          .optional()
          .describe("Optional max seconds to cap the search."),
      },
      async execute(args) {
        const quality = args.quality as Quality;
        const prompt = buildPrompt({
          reason: args.reason,
          query: args.query,
          additionalContext: args.additional_context,
          quality,
        });
    
        const effort = QUALITY_PRESETS[quality].effort;
        return runCodex({
          prompt,
          effort,
          timeoutSeconds: args.timeout,
        });
      },
    });
  13. rakibdev commented on Jan 3, 2026

    @rakibdev

    existing exa search is great. feels more accurate than google search. doesn't even require api key, impressive

  14. scratchmex commented on Jan 5, 2026

    @scratchmex
    Contributor

    I'm hitting 429 when using it and can't debug the request/response because the provider is missing log.debug calls (actually no logging). Would be nice to add them to debug these issues. probably the server response tells something

    It seems that the web search is still not working due to rate limiting (429 error
    
  15. lopi-py commented on Jan 12, 2026

    @lopi-py

    Might be worth to auto enable it if a zen auth was detected?

  16. angristan commented on Jan 18, 2026

    @angristan
    Contributor
  17. lopi-py commented on Jan 18, 2026

    @lopi-py

    I would expect opencode to support the models' native search tool instead of using a 3rd party API, e.g.:

    * https://platform.openai.com/docs/guides/tools-web-search
    
    * https://platform.claude.com/docs/en/agents-and-tools/tool-use/web-search-tool
    

    Do these consume credits if used with API key?

  18. art-shen commented on Jan 19, 2026

    @art-shen

    Do these consume credits if used with API key?

    Of course 😃

    Btw, different web search tools aren’t the same; e.g., some may be blocked from certain websites, and others can differ in their summarization results versus returning the actual raw content – it’d be really nice to have something universal that could fall back through the different available tools, suitable for the specific request. In the ideal case, even using the compatible MCP tools as well.

    I'm using DuckDuckGo search MCP, and it often provides better results and is free. But models from all the different providers tend to forget to try it without my explicit command even after they have failed the request using the default web access tools.

  19. skwde commented on Jan 30, 2026

    @skwde

    @art-shen It would be nice if you could add your DuckDuckGo MCP setup to the opencode docs: https://opencode.ai/docs/mcp-servers/#examples

  20. art-shen commented on Jan 30, 2026

    @art-shen

    @skwde, check it out: #11297

  21. jaded0 commented on Feb 14, 2026

    @jaded0

    I keep getting aggressively rate limited, so I got an api key with exa, but I can't figure out where to put it. I put it in the environment under EXA_API_KEY, I put it in a new mcp server config, nothing works. It's clear to me from reading the docs that the only simple way to get actually reliable web search is to pay opencode for it, despite the fact that I already pay for web search built into my current ai provider.

  22. DeepForget commented on Mar 2, 2026

    @DeepForget

    I keep getting aggressively rate limited, so I got an api key with exa, but I can't figure out where to put it. I put it in the environment under EXA_API_KEY, I put it in a new mcp server config, nothing works. It's clear to me from reading the docs that the only simple way to get actually reliable web search is to pay opencode for it, despite the fact that I already pay for web search built into my current ai provider.

    @jaded0 Image
    if you npm install from source code, then modify here you can use your own api key.

    It is more convenient if opencode can provide an easier way to set different web search tools and use our own api keys to prevent rate limit.

    For now, I guess we can create our custom websearch tool and disable the default one if we want to use a different web search tool like Tavily. Personally, I feel Tavily is better than Exa.

  23. added a commit that references this issue on Apr 7, 2026
  24. github-actions commented on May 2, 2026

    @github-actions
    Contributor

    To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions