Skip to content

fix(tools): stop unusable browser tools from crowding out browser_nav… - #5762

Open
MummIndia wants to merge 1 commit into
odysseus-dev:devfrom
MummIndia:fix-browser-tool-selection
Open

fix(tools): stop unusable browser tools from crowding out browser_nav…#5762
MummIndia wants to merge 1 commit into
odysseus-dev:devfrom
MummIndia:fix-browser-tool-selection

Conversation

@MummIndia

@MummIndia MummIndia commented Jul 26, 2026

Copy link
Copy Markdown

Summary

Tool retrieval returns a top-K (8 by default), and @playwright/mcp alone exposes
30 tools. Measured on three typical browsing requests, the agent was handed
browser_drop, browser_handle_dialog, browser_close, browser_console_messages
and the whole xy-mouse family — while browser_navigate, the only tool that opens a
page, was missing in two cases out of three. On "click the login button", six of the
eight slots went to mouse primitives.

Without the tool that opens a page, every other browser tool is dead weight, so the
model answers that it cannot reach the internet. That answer is correct, but it reads
as a refusal or a hallucination, which is what makes it expensive to diagnose: the
browser is installed, the MCP server reports 30 tools, and calling browser_navigate
by hand works fine.

This adds two guards in src/tool_index.py. MCP_INDEX_DENIED keeps 18 unusable
tools out of the retrieval index — pointer primitives (browser_click and
browser_hover work off the accessibility snapshot and need no coordinates),
debugging aids, session plumbing, and browser_run_code_unsafe, which runs arbitrary
JavaScript in the page. They stay connected and callable; they just no longer compete
for a slot. MCP_COMPANIONS pulls browser_navigate and browser_snapshot in
whenever any browser tool is retrieved. Matching is on the bare tool name, after the
server prefix, so neither guard depends on the browser being registered as
builtin_browser — verified with a second prefix.

Target branch

  • This PR targets dev, not main.

Linked Issue

Fixes #5763

Type of Change

  • Bug fix (non-breaking — fixes a confirmed issue)

Checklist

  • I searched open issues and open PRs — this is not a duplicate.
  • This PR targets dev
  • My changes are limited to the scope described above — no unrelated refactors or whitespace changes mixed in.
  • I actually ran the app (docker compose up) and verified the change works end-to-end.

How to Test

  1. Run the app with the built-in browser MCP server connected. Startup logs should
    show MCP server connected: Built-in: Browser (builtin_browser) - 30 tools via stdio.
  2. In agent mode, send: Open https://example.com and summarise the page.
  3. Before the change — check the [tool-rag] Retrieved tools for query: log line.
    mcp__builtin_browser__browser_navigate is absent, while entries such as
    browser_drop, browser_close or browser_console_messages occupy the slots.
    The agent then reports that it cannot access the internet.
  4. After the change — the same log line contains browser_navigate and
    browser_snapshot, and startup reports Indexed 12 MCP tools instead of 30.
  5. The agent completes the request, emitting
    Tool executed: mcp__builtin_browser__browser_navigate -> exit_code=0, then
    follows up with browser_snapshot to read the page.

Measured on three requests after the change: browser_navigate present 3/3, no
denied tool leaking through, and every slot filled with something usable —
navigate, snapshot, find, click, type, press_key, select_option.

Visual / UI changes

None. This PR only touches src/tool_index.py, which has no rendering path — no
HTML, CSS, SVG or static/js/ module is modified.

…igate

Tool retrieval returns a top-K (8 by default), and @playwright/mcp alone
exposes 30 tools. Measured across three typical browsing requests on a
local setup, the agent was handed browser_drop, browser_handle_dialog,
browser_close, browser_console_messages and the whole xy-mouse family --
while browser_navigate was missing in two cases out of three. On "click
the login button", six of the eight slots went to mouse primitives.

Without the tool that opens a page, every other browser tool is dead
weight. So the model answered that it could not reach the internet, and
that answer was correct. It reads as a refusal or a hallucination, which
is what makes it expensive to diagnose: the browser is installed, the
MCP server is connected and reports 30 tools, and calling
browser_navigate by hand works fine.

Two guards:

  MCP_INDEX_DENIED keeps 18 tools out of the index -- pointer primitives
  (browser_click and browser_hover work off the accessibility snapshot
  and need no coordinates), debugging aids, session plumbing, and
  browser_run_code_unsafe, which runs arbitrary JavaScript in the page.
  They stay connected and callable; they just no longer compete for a
  retrieval slot.

  MCP_COMPANIONS pulls browser_navigate and browser_snapshot in whenever
  any browser tool is retrieved. The server prefix comes from the hit
  itself rather than a constant, so the rule holds under any server id --
  verified with a second prefix.

Matching is on the bare tool name, after the server prefix, so neither
guard depends on the browser being registered as builtin_browser.

Measured on the same three queries after the change: browser_navigate
present three times out of three, no denied tool leaking through, and
every slot filled with something that works -- navigate, snapshot, find,
click, type, press_key, select_option. The running app indexes 12 MCP
tools instead of 30, and the agent then completed a real
navigate-then-read task it had previously refused.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@github-actions github-actions Bot added needs work PR description incomplete — please update before review ready for review Description complete — ready for maintainer review and removed needs work PR description incomplete — please update before review labels Jul 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready for review Description complete — ready for maintainer review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Browser MCP tools crowd out browser_navigate in top-K tool retrieval

1 participant