Module: Kailash::Mcp

Defined in:
lib/kailash/mcp.rb

Overview

MCP (Model Context Protocol) module — Ruby bindings for the canonical MCP types exposed by the underlying kailash_mcp Rust crate.

Four layers ship under this namespace:

  1. Info types (defined in the native extension, mirror Python / Node):

    • Kailash::Mcp::McpToolInfo — tools/list entry
    • Kailash::Mcp::McpResourceInfo — resources/list entry
    • Kailash::Mcp::ServerCapabilities — initialize capability flags
    • Kailash::Mcp::ServerInfo — full initialize payload
  2. Elicitation (gated on the _gvl_release build feature, default ON):

    • Kailash::Mcp::ElicitationSystem — MCP 2025-06-18 server→client elicitation/create round-trips
  3. Server / client / auth surface (Wave-3c W3.5b + F15):

    • Kailash::Mcp::McpServer — catalog-backed MCP server
    • Kailash::Mcp::McpClient — in-memory client (pairs with McpServer)
    • Kailash::Mcp::OAuth2Client — OAuth 2.1 + PKCE client (sync flow-setup + async token redemption; see below)
    • Kailash::Mcp::PermissionManager — fine-grained scope→tool RBAC

Current W3.5b limitation (visible deferral, NOT a silent stub):

  • Tool-callback dispatch — McpServer.register_tool accepts a Ruby block, but the tool invocation path through _ruby_catalog_stub echoes the request and does NOT yet route the Ruby block as the response body. Real Ruby-callback dispatch lands after the cross-binding W0-CALLBACK shard wires async dispatch through the capi callback ABI.

OAuth2Client surface (sync + async, F15 complete):

Sync surfaces (PKCE flow setup + state verification; see registration at bindings/kailash-ruby/ext/kailash/src/mcp_server.rs:1714-1721):

`new`, `client_id`, `token_endpoint`, `build_authorization_request`,
`verify_state`, plus lifecycle (`close`, `closed?`, `inspect`, `to_s`
at `bindings/kailash-ruby/ext/kailash/src/mcp_server.rs:1735-1738`).

Async surfaces (token redemption + revocation, F15; see registration at bindings/kailash-ruby/ext/kailash/src/mcp_server.rs:1722-1734):

`redeem_authorization_code(code, verifier)` — RFC 6749 § 4.1.3
`refresh_token(refresh_token)`              — RFC 6749 § 6
`cache_token(key, token_hash)`              — persist for later retrieval
`get_valid_token(key)`                      — auto-refresh on expiry
`revoke_token(endpoint, token, hint)`       — RFC 7009

Each async method blocks on a per-call tokio runtime (mirrors the capi build_runtime pattern) and releases the GVL so other Ruby threads run concurrently. Token-response Hashes carry the canonical OAuth2 shape (access_token, token_type, expires_in, refresh_token, scope, id_token, expires_at).

  1. Exception hierarchy (also defined by elicitation_system):
    • Kailash::Mcp::RequestCancelled
    • Kailash::Mcp::SchemaValidation
    • Kailash::Mcp::ElicitationTimeout
    • Kailash::Mcp::TransportRebound

Examples

Build a tool descriptor for a tools/list response:

tool = Kailash::Mcp::McpToolInfo.new("search", "Search the web")
tool.to_json
# => '{"name":"search","description":"Search the web","inputSchema":{}}'

Build a resource descriptor with keyword args:

res = Kailash::Mcp::McpResourceInfo.new(
"cfg://settings",
"Settings",
description: "Application settings",
mime_type: "application/json",
)

Block-based server lifecycle:

Kailash::Mcp::McpServer.open(name: "my-server", version: "1.0.0") do |srv|
srv.register_tool(name: "search", description: "Search the web")
srv.register_resource(uri: "doc://1", name: "Doc 1")
# ... use srv ...
end   # srv automatically closed at block exit

Defined Under Namespace

Classes: McpClient, McpServer, OAuth2Client, PermissionManager

Class Method Summary collapse

Class Method Details

.capability_summary(caps) ⇒ Hash{Symbol => Boolean}

Convenience: predicate-only summary of a ServerCapabilities. Returns a Hash with boolean values, useful for logging the server handshake.

caps = Kailash::Mcp::ServerCapabilities.from_json('{"tools":{}}')
Kailash::Mcp.capability_summary(caps)
# => { tools: true, resources: false, prompts: false, elicitation: false }

Parameters:

  • caps (Kailash::Mcp::ServerCapabilities)

Returns:

  • (Hash{Symbol => Boolean})


111
112
113
114
115
116
117
118
# File 'lib/kailash/mcp.rb', line 111

def self.capability_summary(caps)
  {
    tools: caps.has_tools?,
    resources: caps.has_resources?,
    prompts: caps.has_prompts?,
    elicitation: caps.has_elicitation?,
  }
end

.resource(uri:, name:, description: nil, mime_type: nil) ⇒ Kailash::Mcp::McpResourceInfo

Keyword-arg convenience constructor for McpResourceInfo. The native McpResourceInfo.new now accepts keyword args directly; this helper is preserved for back-compat with code written against the previous API and as a documented entry point for the keyword form.

Parameters:

  • uri (String) —

    resource URI (required)

  • name (String) —

    human-readable name (required)

  • description (String, nil) (defaults to: nil) —

    optional description

  • mime_type (String, nil) (defaults to: nil) —

    optional MIME type

Returns:

  • (Kailash::Mcp::McpResourceInfo)


98
99
100
# File 'lib/kailash/mcp.rb', line 98

def self.resource(uri:, name:, description: nil, mime_type: nil)
  McpResourceInfo.new(uri, name, description: description, mime_type: mime_type)
end