Skip to content

Web: duplicate tool names leave stale rows after search filtering #1957

Closed

Description

@Staticsubh

Which version line?

v2 — current (@modelcontextprotocol/inspector@latest)

Which client?

Web

Inspector version

2.1.0

Node version

v26.4.0

Operating system (and browser, for the web client)

macOS 26.5.2; reproduced in Chromium through Playwright

Transport

Streamable HTTP

MCP server under inspection

Any MCP server whose tools/list result contains duplicate name values. A
minimal synthetic fixture is sufficient; OAuth and protocol-era selection do
not affect the bug.

Example tool sequence:

[
  { "name": "get_record", "title": "Get Record First" },
  { "name": "duplicate_tool", "title": "First Duplicate" },
  { "name": "unrelated_tool", "title": "Unrelated Tool First" },
  { "name": "duplicate_tool", "title": "Second Duplicate" },
  { "name": "get_record", "title": "Get Record Second" },
  { "name": "unrelated_tool", "title": "Unrelated Tool Second" }
]

Steps to reproduce

  1. Launch Inspector Web 2.1.0 and connect to a server returning the synthetic
    tool list above.
  2. Open the Tools tab.
  3. Enter get in the Search tools field.
  4. Observe the rows that remain in the sidebar.

Expected behavior

Only tool rows whose name or title contains get remain visible.

Actual behavior

Unrelated rows can remain visible after filtering. The browser console also
reports duplicate React child keys. ToolControls currently keys each row only
by tool.name; when names repeat, React reconciliation can duplicate or omit
rows instead of removing the filtered rows.

This is a client-side rendering defect. It is separate from server-side
authorization or which tools the server returns from tools/list.

Logs, errors, or screenshots

Sanitized console symptom:

Encountered two children with the same key. Non-unique keys may cause children
to be duplicated and/or omitted.

No production endpoint, authorization header, clinical data, or original
screenshot is included in this public report.

Already prototyped a fix?

Exact prompt used:

In MCP Inspector v2 Web, reproduce tool-search filtering when tools/list
contains duplicate tool names. Add a ToolControls regression test with
duplicate names where filtering by get must remove unrelated rows. Avoid
changing server semantics or deduplicating tools. Make rendered keys unique
and stable for both regular and SEP-2243-excluded rows while preserving the
current name/title search behavior. Run the web validation gate.

Local prototype and verification:

  • Added a synthetic regression that fails before the change because an
    unrelated duplicate-key row remains mounted.
  • Preserved each row's original source position and combined it with the tool
    name for a unique, stable rendering key.
  • Applied the same identity rule to SEP-2243-excluded rows.
  • Focused ToolControls suite: 17/17 passed.
  • Formatting, ESLint, TypeScript, and production Web build passed.
  • The repository-wide parallel unit run reached 3,776/3,778 passing; two
    existing useServers watcher tests failed with EMFILE: too many open files, watch under the local macOS service limit. The focused suite is unaffected.

Before you submit

  • I searched existing issues and this is not a duplicate.
  • This is not a security vulnerability report.

Activity

  1. added this to the v2.3.0 milestone on Aug 10, 2026
  2. added
    v2Issues and PRs for v2
    bugSomething isn't working
    on Aug 10, 2026
  3. modified the milestones: v2.3.0, v2.2.0 on Aug 10, 2026
  4. cliffhall commented on Aug 10, 2026

    @cliffhall
    Member

    Reproduced on v2/main (a09f2dc).

    Added the report's synthetic fixture as a ToolControls regression test — six tools with get_record, duplicate_tool, and unrelated_tool each appearing twice — typed get into Search tools, and asserted only the two get_record rows survive.

    It fails, exactly as described:

    stderr | ToolControls > removes every non-matching row when tool names repeat (#1957)
    Encountered two children with the same key, `get_record`. Keys should be unique so that
    components maintain their identity across updates. Non-unique keys may cause children to
    be duplicated and/or omitted — the behavior is unsupported and could change in a future version.
    
    FAIL  ToolControls > removes every non-matching row when tool names repeat (#1957)
    expected document not to contain element, found <p …>First Duplicate</p> instead
    

    So a duplicate_tool row stays mounted after the filter narrows to get, confirming the client-side reconciliation defect rather than anything server-side. Cause is key={tool.name} on both the main list and the SEP-2243 excluded list in clients/web/src/components/groups/ToolControls/ToolControls.tsx.

    Fix incoming: make each rendered key unique and stable by combining the tool's source position with its name, on both lists — no deduplication and no change to what tools/list returns or to the name/title search behavior.

  5. self-assigned this
    on Aug 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingv2Issues and PRs for v2

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions