Class: ModelContextProtocol::Server::Router

Inherits:
Object
  • Object
show all
Defined in:
lib/model_context_protocol/server/router.rb

Defined Under Namespace

Classes: InitializeResponse, LoggingSetLevelResponse, MethodNotFoundError, PingResponse

Instance Method Summary collapse

Constructor Details

#initialize(configuration:) ⇒ Router

Returns a new instance of Router.



8
9
10
11
12
# File 'lib/model_context_protocol/server/router.rb', line 8

def initialize(configuration:)
  @handlers = {}
  @configuration = configuration
  map_handlers
end

Instance Method Details

#map(method, &handler) ⇒ Object



14
15
16
# File 'lib/model_context_protocol/server/router.rb', line 14

def map(method, &handler)
  @handlers[method] = handler
end

#route(message, request_store: nil, session_id: nil, transport: nil, stream_id: nil, session_context: {}) ⇒ Object

Route a message to its handler with request tracking support

Parameters:

  • message (Hash)

    the JSON-RPC message

  • request_store (Object) (defaults to: nil)

    the request store for tracking cancellation

  • session_id (String, nil) (defaults to: nil)

    the session ID for HTTP transport

  • transport (Object, nil) (defaults to: nil)

    the transport for sending notifications

  • stream_id (String, nil) (defaults to: nil)

    the specific stream ID for targeted notifications

  • session_context (Hash) (defaults to: {})

    per-request context stored during session initialization

Returns:

  • (Object)

    the handler result, or nil if cancelled

Raises:



27
28
29
30
31
32
33
34
35
36
37
38
39
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
67
# File 'lib/model_context_protocol/server/router.rb', line 27

def route(message, request_store: nil, session_id: nil, transport: nil, stream_id: nil, session_context: {})
  method = message["method"]
  handler = @handlers[method]
  raise MethodNotFoundError, "Method not found: #{method}" unless handler

  jsonrpc_request_id = message["id"]
  progress_token = message.dig("params", "_meta", "progressToken")

  if jsonrpc_request_id && request_store
    request_store.register_request(jsonrpc_request_id, session_id)
  end

  result = nil
  begin
    execute_with_context do
      context = {
        jsonrpc_request_id:,
        request_store:,
        session_id:,
        progress_token:,
        transport:,
        stream_id:,
        session_context:
      }

      Thread.current[:mcp_context] = context

      result = handler.call(message)
    end
  rescue Server::Cancellable::CancellationError
    return nil
  ensure
    if jsonrpc_request_id && request_store
      request_store.unregister_request(jsonrpc_request_id)
    end

    Thread.current[:mcp_context] = nil
  end

  result
end