Repository navigation
Description
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
- Launch Inspector Web 2.1.0 and connect to a server returning the synthetic
tool list above. - Open the Tools tab.
- Enter
getin the Search tools field. - 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 aToolControlsregression test with
duplicate names where filtering bygetmust 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
ToolControlssuite: 17/17 passed. - Formatting, ESLint, TypeScript, and production Web build passed.
- The repository-wide parallel unit run reached 3,776/3,778 passing; two
existinguseServerswatcher tests failed withEMFILE: too many open files, watchunder 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
cliffhall commentedon Aug 10, 2026
Reproduced on
v2/main(a09f2dc).Added the report's synthetic fixture as a
ToolControlsregression test — six tools withget_record,duplicate_tool, andunrelated_tooleach appearing twice — typedgetinto Search tools, and asserted only the twoget_recordrows survive.It fails, exactly as described:
So a
duplicate_toolrow stays mounted after the filter narrows toget, confirming the client-side reconciliation defect rather than anything server-side. Cause iskey={tool.name}on both the main list and the SEP-2243 excluded list inclients/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/listreturns or to the name/title search behavior.test: add a duplicate-tool-names test server for the #1957 repro
fix: address Copilot review round 3 — typed consts, null admission, p…
fix(web): reset a tool form by row identity, not by tool name
fix: key resource list rows by position so duplicate URIs cannot collide
feat(web): sort the Tools list by displayed label (modelcontextprotoc…