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

  1. Call await client.list_tools() and print the available tool names, then use the exact name
  2. Check for casing/typos and whether the fully-qualified mcp__{name}__{tool} form is required
  3. 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

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


AI-assisted analysis of agentscope-ai/agentscope@e90f1c7592 (2026-08-28). Data as JSON: /api/errors/1b0fd61ea077928d. Report an issue: GitHub.