Skip to content

Unknown methods return -32602 Invalid params instead of -32601 Method not found #3193

Description

@borisowvalia

A server built on this SDK answers every unknown JSON-RPC method with -32602 Invalid request parameters, where JSON-RPC 2.0 requires -32601 Method not found.

Why it matters

Catalogue scanners probe for optional capabilities and read the error code to decide whether a method is unsupported or genuinely malformed. Smithery, scanning our production server, logged:

Warning: Failed to list triggers: MCP error -32602: Invalid request parameters

-32602 reads as "you called it wrong", so the sensible client behaviour is to retry with different parameters — but no parameters will ever work, because the method does not exist. -32601 is the answer that lets a client move on.

Reproduction

Against any server on this SDK, after initialize + notifications/initialized:

{"jsonrpc":"2.0","id":9,"method":"totally/bogus"}

Response:

{"jsonrpc":"2.0","id":9,"error":{"code":-32602,"message":"Invalid request parameters","data":""}}

Same code for triggers/list, completions/complete and logging/setLevel on a server that declares none of those capabilities — the four are indistinguishable from a genuine schema violation.

Cause

In mcp/shared/session.py, self._receive_request_type.model_validate(...) raises for a method outside the request union, and the surrounding except Exception maps everything to INVALID_PARAMS:

except Exception as e:
    # For request validation errors, send a proper JSON-RPC error
    # response instead of crashing the server
    logging.warning(f"Failed to validate request: {e}")
    error_response = JSONRPCError(
        ...
        error=ErrorData(code=INVALID_PARAMS, message="Invalid request parameters", data=""),
    )

The comment is accurate for its original purpose — the union is just doing double duty as a method registry, so "method I do not have" and "parameters I cannot parse" arrive at the same handler.

Suggested fix

Distinguish the two before building the error: if message.message.root.method is not among the known request methods, answer METHOD_NOT_FOUND and keep INVALID_PARAMS for a known method that fails validation. Populating data with the validation error would also help — it is currently an empty string, so the response carries no diagnostic at all.

Happy to open a PR if the approach looks right.

Observed on mcp 1.27.1, Python 3.14.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions