Module: PostHog::MCP::SessionToken Private
- Defined in:
- lib/posthog/mcp/session_token.rb
Overview
This module is part of a private API. You should avoid using this module if possible, as it may be removed or be changed in the future.
Self-encoded session tokens for stateless / multi-pod MCP servers.
A stateless server keeps nothing between requests, so every request would
start a new session and the client identity (only sent at initialize)
would be lost. Clients replay the Mcp-Session-Id header on every request,
so at initialize we mint that header as an unsigned base64url(JSON) token
with short keys (sid, cn, cv, pv).
Constant Summary collapse
- MAX_TOKEN_LENGTH =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
4096- MAX_SESSION_ID_LENGTH =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
128- MAX_CLIENT_FIELD_LENGTH =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
200- BASE64URL_PATTERN =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
/\A[A-Za-z0-9_-]+={0,2}\z/
Class Method Summary collapse
-
.decode(value) ⇒ SessionTokenPayload?
private
Decode an
Mcp-Session-Idvalue. -
.encode(payload) ⇒ String
private
Token for the
Mcp-Session-Idresponse header. -
.read_header(headers) ⇒ Object
private
Read the
mcp-session-idvalue off a headers Hash (case-insensitive keys, array values, trimmed).
Class Method Details
.decode(value) ⇒ SessionTokenPayload?
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Decode an Mcp-Session-Id value. Returns nil for anything that is not one
of our tokens (transport UUIDs, JWTs, garbage) and never raises.
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/posthog/mcp/session_token.rb', line 58 def decode(value) return nil unless value.is_a?(String) && !value.empty? && value.length <= MAX_TOKEN_LENGTH return nil unless BASE64URL_PATTERN.match?(value) parsed = begin JSON.parse(Base64.urlsafe_decode64(value.delete('='))) rescue ArgumentError, JSON::ParserError, EncodingError nil end return nil unless parsed.is_a?(Hash) sid = parsed['sid'] return nil unless sid.is_a?(String) && !sid.empty? && sid.length <= MAX_SESSION_ID_LENGTH payload = SessionTokenPayload.new(session_id: sid) payload.client_name = parsed['cn'][0, MAX_CLIENT_FIELD_LENGTH] if present_string?(parsed['cn']) payload.client_version = parsed['cv'][0, MAX_CLIENT_FIELD_LENGTH] if present_string?(parsed['cv']) payload.protocol_version = parsed['pv'][0, MAX_CLIENT_FIELD_LENGTH] if present_string?(parsed['pv']) payload end |
.encode(payload) ⇒ String
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns token for the Mcp-Session-Id response header.
40 41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/posthog/mcp/session_token.rb', line 40 def encode(payload) payload = SessionTokenPayload.new(**payload) if payload.is_a?(Hash) session_id = payload.session_id unless session_id.is_a?(String) && !session_id.empty? raise ArgumentError, 'encode_session_id requires a non-empty `session_id` (use new_session_id())' end wire = { 'sid' => session_id } wire['cn'] = payload.client_name[0, MAX_CLIENT_FIELD_LENGTH] if present_string?(payload.client_name) wire['cv'] = payload.client_version[0, MAX_CLIENT_FIELD_LENGTH] if present_string?(payload.client_version) wire['pv'] = payload.protocol_version[0, MAX_CLIENT_FIELD_LENGTH] if present_string?(payload.protocol_version) Base64.urlsafe_encode64(JSON.generate(wire), padding: false) end |
.read_header(headers) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Read the mcp-session-id value off a headers Hash (case-insensitive keys,
array values, trimmed). Returns nil when absent or blank.
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/posthog/mcp/session_token.rb', line 81 def read_header(headers) return nil unless headers.respond_to?(:each_pair) value = headers[MCP_SESSION_HEADER] if value.nil? headers.each_pair do |key, candidate| next unless key.is_a?(String) && key.downcase == MCP_SESSION_HEADER value = candidate break end end value = value.first if value.is_a?(Array) return nil unless value.is_a?(String) trimmed = value.strip trimmed.empty? ? nil : trimmed end |