rohitg00/ai-engineering-from-scratch · error · LookupError
Method not found: {method}
Error message
Method not found: {method} What it means
The teaching MCP server's _dispatch routes only a fixed method set (initialize, tools/list, tools/call, resources/list, resources/read, prompts/list, prompts/get). Any other method string falls through to raise LookupError, mirroring JSON-RPC error -32601 method-not-found. It means the request reached a valid server but named a method outside its implemented surface.
Source
Thrown at certifications/claude/lessons/11-mcp-server-design-and-integration/code/main.py:304
]
return self._complete(
prompts=prompts, ttlMs=300_000, cacheScope="public"
), []
if method == "prompts/get":
name = params["name"]
if not isinstance(name, str):
raise ValueError("name must be a string")
if name not in self.prompts:
raise ValueError("unknown prompt")
return self._complete(
messages=[
{
"role": "user",
"content": {"type": "text", "text": self.prompts[name]},
}
]
), []
raise LookupError(f"Method not found: {method}")
def _call_tool(
self, params: dict[str, Any], metadata: dict[str, Any]
) -> tuple[dict[str, Any], list[dict[str, Any]]]:
name = params["name"]
if not isinstance(name, str) or not name:
raise ValueError("name must be a non-empty string")
tool = self.tools.get(name)
if tool is None:
raise ValueError("unknown tool")
arguments = tool.validate_arguments(params.get("arguments", {}))
if name == "prepare_review":
return self._prepare_review(params, metadata, arguments), []
token = metadata.get("progressToken")
notifications: list[dict[str, Any]] = []
if token is not None:
if not isinstance(token, (str, int)) or isinstance(token, bool):View on GitHub (pinned to 39ea8a1c6d)
Solutions
- Send only the methods _dispatch implements: initialize, tools/list, tools/call, resources/list, resources/read, prompts/list, prompts/get
- Inspect the initialize result's capabilities object to learn which feature areas the server exposes before calling them
- Catch LookupError in the client and map it to JSON-RPC error code -32601 instead of crashing
Example fix
# before
result = server.exchange("ping", {}) # LookupError
# after
result = server.exchange("tools/list", {}) Defensive patterns
Strategy: try-catch
Validate before calling
SUPPORTED = {"initialize", "tools/list", "tools/call", "resources/list", "resources/read", "prompts/list", "prompts/get"}
if method not in SUPPORTED:
raise ValueError(f"unsupported method: {method}")
result = server.exchange(method, params) Type guard
def is_supported_method(method: object) -> bool:
return isinstance(method, str) and method in {
"initialize", "tools/list", "tools/call",
"resources/list", "resources/read",
"prompts/list", "prompts/get",
} Try / catch
try:
result = server.exchange(method, params)
except LookupError as exc:
respond_error(request_id, -32601, str(exc)) Prevention
- Read the server's initialize response before sending feature-specific requests
- Treat method names as case-sensitive protocol tokens
- Centralize dispatch in one client helper so unsupported methods fail in exactly one place
When it happens
Trigger: Calling exchange() with methods the server never implements: 'ping', 'notifications/initialized', 'completion/complete', 'logging/setLevel', or a case typo like 'tools/List' (dispatch is case-sensitive).
Common situations: Pointing a generic MCP client SDK built against a newer or older spec revision at this lesson server; hand-crafting JSON-RPC requests and misspelling the method; assuming every server supports optional features like ping or completion.
Related errors
AI-assisted analysis of rohitg00/ai-engineering-from-scratch@39ea8a1c6d (2026-08-26).
Data as JSON: /api/errors/659210ebf1b06e54.
Report an issue: GitHub.