Class: MCP::RequestEnvelope

Inherits:
Object
  • Object
show all
Defined in:
lib/mcp/request_envelope.rb

Overview

The per-request _meta envelope of the stateless "modern" lifecycle (MCP 2026-07-28, SEP-2575). The modern lifecycle has no initialize handshake: every request identifies its protocol version, client, and client capabilities through reserved _meta keys, and the server validates each request independently. Servers MUST NOT infer capabilities from prior requests, which is why the envelope is a per-request value object rather than session state.

https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2575

Constant Summary collapse

PROTOCOL_VERSION_META_KEY =
"io.modelcontextprotocol/protocolVersion"
CLIENT_INFO_META_KEY =
"io.modelcontextprotocol/clientInfo"
CLIENT_CAPABILITIES_META_KEY =
"io.modelcontextprotocol/clientCapabilities"
LOG_LEVEL_META_KEY =

Optional per-request log level, replacing the logging/setLevel RPC in the modern lifecycle. Deprecated as of 2026-07-28 (SEP-2577) but still part of the wire format.

"io.modelcontextprotocol/logLevel"
REQUIRED_META_KEYS =
[
  PROTOCOL_VERSION_META_KEY,
  CLIENT_INFO_META_KEY,
  CLIENT_CAPABILITIES_META_KEY,
].freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(protocol_version:, client_info:, client_capabilities:, log_level: nil) ⇒ RequestEnvelope

Returns a new instance of RequestEnvelope.



87
88
89
90
91
92
93
# File 'lib/mcp/request_envelope.rb', line 87

def initialize(protocol_version:, client_info:, client_capabilities:, log_level: nil)
  @protocol_version = protocol_version
  @client_info = client_info
  @client_capabilities = client_capabilities
  @log_level = log_level
  freeze
end

Instance Attribute Details

#client_capabilitiesObject (readonly)

Returns the value of attribute client_capabilities.



85
86
87
# File 'lib/mcp/request_envelope.rb', line 85

def client_capabilities
  @client_capabilities
end

#client_infoObject (readonly)

Returns the value of attribute client_info.



85
86
87
# File 'lib/mcp/request_envelope.rb', line 85

def client_info
  @client_info
end

#log_levelObject (readonly)

Returns the value of attribute log_level.



85
86
87
# File 'lib/mcp/request_envelope.rb', line 85

def log_level
  @log_level
end

#protocol_versionObject (readonly)

Returns the value of attribute protocol_version.



85
86
87
# File 'lib/mcp/request_envelope.rb', line 85

def protocol_version
  @protocol_version
end

Class Method Details

.modern?(params) ⇒ Boolean

A request is classified as modern only when the full REQUIRED triple is present, matching the TypeScript SDK's RequestMetaEnvelopeSchema and the Python SDK's _has_modern_envelope. A partial triple is treated as legacy so existing _meta usage (progressToken, trace context) keeps flowing through the legacy path.

Returns:

  • (Boolean)


31
32
33
34
35
36
# File 'lib/mcp/request_envelope.rb', line 31

def modern?(params)
  meta = extract_meta(params)
  return false unless meta.is_a?(Hash)

  REQUIRED_META_KEYS.all? { |key| !read(meta, key).nil? }
end

.parse!(params, request: nil) ⇒ Object

Parses and validates the envelope. request is only used to enrich the raised error; callers dispatching notifications can omit it.



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/mcp/request_envelope.rb', line 40

def parse!(params, request: nil)
  meta = extract_meta(params)
  meta = {} unless meta.is_a?(Hash)

  protocol_version = read(meta, PROTOCOL_VERSION_META_KEY)
  client_info = read(meta, CLIENT_INFO_META_KEY)
  client_capabilities = read(meta, CLIENT_CAPABILITIES_META_KEY)

  unless protocol_version.is_a?(String) && client_info.is_a?(Hash) && client_capabilities.is_a?(Hash)
    raise Server::RequestHandlerError.new(
      "Invalid Request: modern requests require `#{REQUIRED_META_KEYS.join("`, `")}` in `_meta`",
      request,
      error_type: :invalid_request,
    )
  end

  unless Configuration.modern_protocol_version?(protocol_version)
    raise Server::UnsupportedProtocolVersionError.new(protocol_version, request)
  end

  new(
    protocol_version: protocol_version,
    client_info: client_info,
    client_capabilities: client_capabilities,
    log_level: read(meta, LOG_LEVEL_META_KEY),
  )
end