Nothing in the repo could serve the shape this fix is about: every preset registers a unique name, and the SDK's `registerTool` rejects a repeat. So the only reproduction was a unit test — there was no way to smoke the real app against a server that returns duplicates. Adds `ServerConfig.duplicateToolNames` (a list of registered tool names) to the composable test server, plumbed through the JSON config, and a showcase config `duplicate-tool-names-http.json`. The named tools are emitted a second time in `tools/list` with the same `name` and a "(duplicate)" title. The repeats are appended after the whole list rather than placed beside their twin. That is both the realistic shape (two tool sources concatenated) and what makes the defect observable: React matches a leading run of same-key children first, so a head-adjacent duplicate happens to line up and the bug hides. Only a separated pair collides in the keyed map and orphans a row — verified both ways against the prod bundle. The `tools/list` override is shared with the existing pagination handler (which already hand-builds the list); with no `maxPageSize` it returns a single unbounded page. Duplication happens before pagination, so a duplicated pair can straddle a page boundary the way a real server's would. Also adds a ToolControls test for this appended ordering, distinct from the reporter's interleaved fixture, and documents the config in the README showcase table. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SW1p8E2uiyyLx4RKwrwSrt
17 lines
335 B
JSON
17 lines
335 B
JSON
{
|
|
"serverInfo": {
|
|
"name": "duplicate-tool-names",
|
|
"version": "1.0.0"
|
|
},
|
|
"tools": [
|
|
{ "preset": "get_weather" },
|
|
{ "preset": "get_temp" },
|
|
{ "preset": "echo" },
|
|
{ "preset": "add" }
|
|
],
|
|
"duplicateToolNames": ["get_weather", "echo"],
|
|
"transport": {
|
|
"type": "streamable-http",
|
|
"port": 3142
|
|
}
|
|
}
|