Class: Otto::MCP::Protocol

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

Overview

MCP protocol handler providing Model Context Protocol functionality.

JSON-RPC error code to HTTP status mapping

Code     Meaning                 HTTP
-32700   Parse error             400
-32600   Invalid Request         400
-32601   Method not found        400
-32602   Invalid params          400
-32001   Resource not found      404
-32002   Tool not found          404
-32603   Internal error          500
-32099..-32000  server errors    500

Protocol-level faults (a malformed or unsupported payload against a valid endpoint) are 400, including method-not-found: 404 there would conflate a bad payload with "no such route", which the MCP endpoint handler already returns when MCP is disabled. 404 is reserved for a well-formed request naming an entity that is not registered, and 500 for handler execution faults. Handler exception messages are logged, never returned: -32603 responses carry a fixed message.

Constant Summary collapse

ERROR_STATUS_MAP =
{
  -32_700 => 400, # Parse error
  -32_600 => 400, # Invalid Request
  -32_601 => 400, # Method not found
  -32_602 => 400, # Invalid params
  -32_001 => 404, # Resource not found
  -32_002 => 404, # Tool not found
  -32_603 => 500, # Internal error
}.freeze
SERVER_ERROR_RANGE =

Implementation-defined server error range; anything unmapped inside it is an execution fault.

(-32_099..-32_000)

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(otto_instance) ⇒ Protocol

Returns a new instance of Protocol.



50
51
52
53
# File 'lib/otto/mcp/protocol.rb', line 50

def initialize(otto_instance)
  @otto     = otto_instance
  @registry = Registry.new
end

Instance Attribute Details

#registryObject (readonly)

Returns the value of attribute registry.



48
49
50
# File 'lib/otto/mcp/protocol.rb', line 48

def registry
  @registry
end

Instance Method Details

#handle_request(env) ⇒ Object



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/otto/mcp/protocol.rb', line 55

def handle_request(env)
  request = @otto.request_class.new(env)

  unless request.post? && request.content_type&.include?('application/json')
    return error_response(nil, -32_600, 'Invalid Request', 'Only JSON-RPC POST requests supported')
  end

  begin
    body = request.body.read
    data = JSON.parse(body)
  rescue JSON::ParserError
    return error_response(nil, -32_700, 'Parse error', 'Invalid JSON')
  end

  unless valid_jsonrpc_request?(data)
    return error_response(data['id'], -32_600, 'Invalid Request', 'Missing jsonrpc, method, or id fields')
  end

  case data['method']
  when 'initialize'
    handle_initialize(data)
  when 'resources/list'
    handle_resources_list(data)
  when 'resources/read'
    handle_resources_read(data)
  when 'tools/list'
    handle_tools_list(data)
  when 'tools/call'
    handle_tools_call(data, env)
  else
    error_response(data['id'], -32_601, 'Method not found', "Unknown method: #{data['method']}")
  end
end