fix(server): return METHOD_NOT_FOUND for unregistered spec methods (#3193)

Closed
PR
3mo ago
+17-12

Fixes #3193.

In ServerRunner._on_request, _methods.validate_client_request was previously called before checking self.server.get_request_handler(method). For spec methods (SPEC_CLIENT_METHODS) where no handler was registered on the server, sending malformed or missing parameters triggered parameter validation first, returning -32602 Invalid params instead of -32601 Method not found.

Motivation and Context

Per JSON-RPC 2.0 specification (Section 5.1), calling a method that is not available / served by the server must return -32601 Method not found. Previously, probing an unregistered spec method (such as triggers/list or tools/call on a server without handlers) returned -32602 Invalid params when parameters were missing or malformed.

This change separates the version-surface check from parameter validation:

  1. Upfront Version Gate: Added an upfront check if method in _methods.SPEC_CLIENT_METHODS and (method, version) not in _methods.CLIENT_REQUESTS: so methods invalid at the negotiated version return -32601 Method not found.
  2. Post-Lookup Schema Validation: Moved _methods.validate_client_request down after self.server.get_request_handler(method). Unregistered spec methods now fall through to entry is None (-32601 Method not found), while registered handlers continue to surface-validate parameters (-32602 Invalid params).
  3. Initialize Handshake Untouched: The initialize handshake branch remains 100% untouched.

How Has This Been Tested?

  • Ran unit test suite (uv run pytest tests/server/test_runner.py): 113/113 passed.
  • Updated tests/server/test_runner.py to assert -32601 Method not found for unregistered spec methods and -32602 Invalid params for registered spec methods with invalid parameters.
  • Ran repo-wide test suite (uv run pytest): 5,572 passed.
  • Code formatting and linting verified with uv run ruff check . and uv run ruff format --check ..

Breaking Changes

No breaking changes. Existing registered handler behavior and parameter validation rules are fully preserved.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)