Skip to content

initialize and resources/subscribe accept params with missing required fields #450

Description

@cclabadmin

Describe the bug

The initialize and resources/subscribe handlers accept requests in which fields required by the 2025-11-25 schema are absent. Missing hash keys evaluate to nil, and these handlers continue processing without validating the individual required fields.

The schema defines:

InitializeRequestParams:  required = [capabilities, clientInfo, protocolVersion]
SubscribeRequestParams:   required = [uri]

Environment tested:

  • Stable release: v0.23.0 (95feef2)
  • Transports: stdio, stateful HTTP

To Reproduce

  1. Start a Ruby SDK MCP server with resource subscriptions enabled and complete initialization.
  2. Send a resources/subscribe request with no uri:
{"jsonrpc":"2.0","id":1001,"method":"resources/subscribe","params":{}}
  1. Observe that the server returns {"result":{}}.

Separately, send the following as the first request to a fresh server instance:

{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}

The server returns a successful initialize result using the server's default protocol version and capabilities, even though clientInfo, capabilities, and protocolVersion are all absent.

Expected behavior

Both requests should be rejected with -32602 Invalid params. An initialize request with required fields omitted should not fall back to the server's default protocol version, and a resources/subscribe request without uri should not return a successful result.

Additional context

In lib/mcp/server.rb, the init method checks whether params is truthy but does not validate individual required fields:

def init(params, session: nil)
  # ...
  if params
    if session
      session.store_client_info(client: params[:clientInfo], capabilities: params[:capabilities])
    else
      @client = params[:clientInfo]
      @client_capabilities = params[:capabilities]
    end
    protocol_version = params[:protocolVersion]
  end

When params is {}, params[:clientInfo] and params[:capabilities] both evaluate to nil, which is stored directly. params[:protocolVersion] is nil, so SUPPORTED_STABLE_PROTOCOL_VERSIONS.include?(nil) is false, and the server falls through to its default version.

For resources/subscribe, the handler is a no-op lambda:

Methods::RESOURCES_SUBSCRIBE => ->(_) { {} },

The default handler ignores its argument, so it does not check whether uri is present before the empty result is returned.

Related issues #349, #351, and #186 cover other initialization, session, or protocol-version behaviors, but I did not find an existing issue covering acceptance of missing schema-required fields.

The completion/complete handler already performs explicit required-field validation through validate_completion_params!, which may provide an existing pattern for these handlers.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions