Bare-name tool alias silently re-registers on a 3rd+ collision, only the 2nd logs a warning
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 84/100
Research direction
Start in src/mcphub/init.py at ToolUniverse.load_tools() and trace the bare-alias collision handling. Run the three-server reproduction from the issue to observe the alias table and warnings. Done means a name that collides across three or more servers is never silently restored as a bare alias, with behavior matching one of the expected outcomes.
Written by the indexing model from the issue text.
Description
Background
ToolUniverse.load_tools() (src/mcphub/__init__.py) registers a bare
(unqualified) alias for each discovered tool name, so callers can do
tu.run("status") instead of tu.run("iot.status"). When a second server
exposes the same bare name, the collision is detected, a warning is logged,
and the alias is removed (self._alias.pop(t.name, None)) so the ambiguous
name stops resolving.
Removing the alias also erases all memory that the name was ever ambiguous.
If a third (or any later) server also happens to expose that same bare
name, the registration check sees the name is absent from self._alias again
and silently re-adds it, pointing at whichever server loaded last. No warning
fires on this second-and-later collision, only on the very first one. A
caller invoking the bare name afterward gets routed to one of 3+ legitimate
servers with no indication anything is ambiguous.
With the 6 MCP servers currently shipped (iot, utilities, fmsr, wo, tsfm,
vibration) I did not find a live 3-way name collision, so today this is a
latent defect rather than an observed production failure, but it would bite
silently the moment a third server (including a user-added one) reuses a
bare name already used by two others.
Steps to Reproduce
Ran against a real ToolUniverse instance and the real load_tools() code
path; only _connect and _worker.list are stubbed out so the repro doesn't
need three live stdio MCP server processes.
import logging, sys
sys.path.insert(0, "src")
from mcphub import ToolUniverse
logging.basicConfig(level=logging.WARNING)
class FakeTool:
def __init__(self, name):
self.name = name
self.description = ""
self.inputSchema = {}
class FakeListResult:
def __init__(self, tools):
self.tools = tools
FAKE_SERVERS = {
"server1": [FakeTool("status")],
"server2": [FakeTool("status")],
"server3": [FakeTool("status")],
}
tu = ToolUniverse(servers={k: [] for k in FAKE_SERVERS})
tu._connect = lambda name: None # skip real stdio connect
tu._worker.list = lambda name: FakeListResult(FAKE_SERVERS[name])
count = tu.load_tools(servers=list(FAKE_SERVERS))
print("tools registered:", count)
print("alias table:", tu._alias)
tu.close()
Run with:
python -m pip install mcp
python repro.py
Observed
WARNING:mcphub:Ambiguous tool name 'status'; use 'server2.status'.
tools registered: 3
alias table: {'status': 'server3.status'}
Only one warning is logged (for the 2nd collision, server2 vs server1). The
3rd collision (server3) silently re-registers the bare alias with no warning
at all, and status now resolves to server3.status as if it had never been
ambiguous.
Expected
Either no bare alias for status after any collision, or a warning on every
collision (2nd, 3rd, ...), not just the first.
Environment
- Repo HEAD:
248204c4cce9f9e3c3f3234e466f6694a080f6f7 - Python 3.12.14,
python:3.12-slimDocker image mcpclient package (latest from PyPI at repro time)
Reproduced end to end in a clean container against current main. Happy to
send a PR if useful; the fix looks like replacing the pop-then-forget pattern
with a separate set of names known to be ambiguous that's never cleared, and
warning on every collision.
- Dominant language
- Python
- Stars
- 2.3k
- Forks
- 325
- Avg merge
- 16h 33m
- Merged PRs (30d)
- 14
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from IBM/AssetOpsBench
-
Difficulty 5/5 Over a week Newbie friendliness 38/100
IBM/AssetOpsBench#530 · 1 reaction ·
-
Difficulty 5/5 Over a week Newbie friendliness 25/100
IBM/AssetOpsBench#527 · 2 comments ·
-
Difficulty 5/5 Over a week Newbie friendliness 25/100
IBM/AssetOpsBench#524 · 1 reaction ·
-
IBM/AssetOpsBench#523 · 1 assignee ·
-
IBM/AssetOpsBench#522 · 2 comments · 1 assignee ·
All issues in IBM/AssetOpsBench
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
enhancement
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 74/100