agentscope-ai/agentscope · error · ValueError
Tool '{name}' not found in MCP server '{self.name}'
Error message
Tool '{name}' not found in MCP server '{self.name}' What it means
get_tool() searches the client's cached tool list (_cached_tools) and raises ValueError when no tool with the given name exists on the MCP server. The cache is populated when tools are listed, so the name must exactly match the server-reported tool name.
Source
Thrown at src/agentscope/mcp/_mcp_client.py:406
RuntimeError: If not connected (for stateful connections).
"""
# Avoid circular import by importing here
from ..tool import MCPTool
# Fetch tools if not cached. Use list_raw_tools() to avoid the
# recursion list_tools() → get_tool() → list_tools().
if self._cached_tools is None:
await self.list_raw_tools()
# Find target tool
target_tool = None
for tool in self._cached_tools:
if tool.name == name:
target_tool = tool
break
if target_tool is None:
raise ValueError(
f"Tool '{name}' not found in MCP server " f"'{self.name}'",
)
# Create MCPTool based on stateful/stateless
if not self.is_stateful:
# Stateless: pass client generator
return MCPTool(
mcp_name=self.name,
tool=target_tool,
client_gen=self._get_client_gen,
timeout=self.execution_timeout,
)
else:
# Stateful: pass session
self._validate_connection()
return MCPTool(
mcp_name=self.name,
tool=target_tool,View on GitHub (pinned to e90f1c7592)
Solutions
- Call await client.list_tools() and print the available tool names, then use the exact name
- Check for casing/typos and whether the fully-qualified mcp__{name}__{tool} form is required
- Verify the server version still exposes the tool and that enable_tools/disable_tools filters are not hiding it
Example fix
// before
tool = await client.get_tool("web_shearch")
// after
tools = await client.list_tools()
print([t.name for t in tools]) # confirm exact name
tool = await client.get_tool("web_search") Defensive patterns
Strategy: validation
Validate before calling
names = {t.name for t in await client.list_tools()}
if tool_name not in names:
raise KeyError(f"{tool_name} not in {sorted(names)}")
tool = await client.get_tool(tool_name) Type guard
def tool_exists(name: str, tools: list) -> bool:
return any(t.name == name for t in tools) Try / catch
try:
tool = await client.get_tool(name)
except ValueError as e:
if "not found" in str(e):
available = [t.name for t in await client.list_tools()]
raise ValueError(f"{name} not in available tools {available}") from e
raise Prevention
- Always list tools and use exact server-reported names
- Log available tool names at startup for quick diagnosis
- Beware enable/disable filters hiding tools from the cache
When it happens
Trigger: client.get_tool("seach") typo; referencing a tool that the server renamed or no longer exposes; calling get_tool before list_tools populated the cache; tool names namespaced differently than expected (mcp__{name}__{tool} vs bare tool name).
Common situations: Typos or wrong casing in tool names; server version changes removing/renaming tools; assuming a tool exists from documentation rather than listing actual tools; forgetting to await connect()/list_tools() first on a stateful client.
Related errors
- {e}
- STDIO MCP does not support ephemeral mode. Use 'shared' or '
- Invalid values for MCP {card.name!r}: {e.message}
- MCP {card.name!r} needs a value for: {', '.join(sorted(missi
- MCP {card.name!r} produced an invalid client: {e}
AI-assisted analysis of agentscope-ai/agentscope@e90f1c7592 (2026-08-28).
Data as JSON: /api/errors/1b0fd61ea077928d.
Report an issue: GitHub.