modelcontextprotocol/servers · error · ValueError

Unknown tool: {name}

Error message

Unknown tool: {name}

What it means

The time server's call_tool match (server.py:188-209) has a case _ at line 208-209 raising ValueError('Unknown tool: {name}') for any name other than get_current_time or convert_time. As with 44-47, this is caught and re-wrapped by error 49 before reaching the client.

Source

Thrown at src/time/src/mcp_server_time/server.py:209

                    if not timezone:
                        raise ValueError("Missing required argument: timezone")

                    result = time_server.get_current_time(timezone)

                case TimeTools.CONVERT_TIME.value:
                    if not all(
                        k in arguments
                        for k in ["source_timezone", "time", "target_timezone"]
                    ):
                        raise ValueError("Missing required arguments")

                    result = time_server.convert_time(
                        arguments["source_timezone"],
                        arguments["time"],
                        arguments["target_timezone"],
                    )
                case _:
                    raise ValueError(f"Unknown tool: {name}")

            return [
                TextContent(type="text", text=json.dumps(result.model_dump(), indent=2))
            ]

        except Exception as e:
            raise ValueError(f"Error processing mcp-server-time query: {str(e)}")

    options = server.create_initialization_options()
    async with stdio_server() as (read_stream, write_stream):
        await server.run(read_stream, write_stream, options)

View on GitHub (pinned to 76d64c822f)

Solutions

  1. Use only names advertised by list_tools (get_current_time, convert_time).
  2. Align client and server versions.
  3. Fix the typo; double-check routing if multiple MCP servers are connected.

Example fix

// before
//   session.call_tool("get_time", ...)    -> Unknown tool
// after
//   session.call_tool("get_current_time", ...)
Defensive patterns

Strategy: validation

Validate before calling

known = {t.name for t in (await session.list_tools()).tools}
if name not in known:
    raise ValueError(f"{name!r} not offered by time server; choose from {sorted(known)}")
await session.call_tool(name, arguments)

Type guard

async def is_known_tool(session, name: str) -> bool:
    return name in {t.name for t in (await session.list_tools()).tools}

Try / catch

try:
    await session.call_tool(name, arguments)
except Exception as e:
    if "Unknown tool" in str(e):
        # refresh list_tools and retry with a corrected name
        ...
    raise

Prevention

When it happens

Trigger: Invoking a tool name the time server does not offer: a typo ('get_time'), an older/newer name, or a name that belongs to a different MCP server.

Common situations: Client hardcoded a stale tool name; version skew between client and mcp-server-time; a tool name intended for the git server routed here by mistake.

Related errors


AI-assisted analysis of modelcontextprotocol/servers@76d64c822f (2026-08-12). Data as JSON: /api/errors/b32fa906d8fb3ca4. Report an issue: GitHub.