Class: Otto::MCP::Server
- Inherits:
-
Object
- Object
- Otto::MCP::Server
- Defined in:
- lib/otto/mcp/server.rb
Overview
MCP server implementation providing Model Context Protocol endpoints
Constant Summary collapse
- UNAUTHENTICATED_WARNING =
Warning emitted when the MCP HTTP endpoint is exposed with no token authentication. Unconditional (not gated on Otto.debug): an unauthenticated MCP endpoint lets any caller invoke every registered tool, so it must be visible in normal boot output.
<<~MSG.gsub(/\s+/, ' ').strip.freeze [MCP] HTTP endpoint %s is enabled without authentication: any caller can list and invoke MCP tools and resources. Pass auth_tokens: ['<token>'] to require a bearer token, or allow_unauthenticated: true to acknowledge this intentionally. MSG
Instance Attribute Summary collapse
-
#otto_instance ⇒ Object
readonly
Returns the value of attribute otto_instance.
-
#protocol ⇒ Object
readonly
Returns the value of attribute protocol.
Class Method Summary collapse
-
.normalize_options(opts = {}, scope = :explicit) ⇒ Object
Normalize raw options into the canonical MCP option hash.
Instance Method Summary collapse
-
#enable!(options = {}) ⇒ Object
Enable the MCP server.
- #enabled? ⇒ Boolean
-
#initialize(otto_instance) ⇒ Server
constructor
A new instance of Server.
- #register_mcp_route(route_info) ⇒ Object
Constructor Details
Instance Attribute Details
#otto_instance ⇒ Object (readonly)
Returns the value of attribute otto_instance.
18 19 20 |
# File 'lib/otto/mcp/server.rb', line 18 def otto_instance @otto_instance end |
#protocol ⇒ Object (readonly)
Returns the value of attribute protocol.
18 19 20 |
# File 'lib/otto/mcp/server.rb', line 18 def protocol @protocol end |
Class Method Details
Instance Method Details
#enable!(options = {}) ⇒ Object
Enable the MCP server.
Enabling is one-shot. Each call appends a route, an endpoint-setting proc and the MCP middleware to the Otto instance without removing the previous set, so a second call with a different endpoint would leave the first endpoint routed but guarded by nothing (the auth middleware only matches the newest endpoint). Rather than try to unwind that, a second call raises.
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 88 89 90 91 |
# File 'lib/otto/mcp/server.rb', line 61 def enable!( = {}) if @enabled raise ArgumentError, "MCP server is already enabled on #{@http_endpoint}; pass all MCP options " \ 'in a single Otto.new or enable_mcp! call' end = self.class.() Validator.ensure_available! if [:enable_validation] Otto::Security::RateLimiting.ensure_available! if [:enable_rate_limiting] @enabled = true @http_endpoint = [:http_endpoint] @auth_tokens = [:auth_tokens] @enable_validation = [:enable_validation] @enable_rate_limiting = [:enable_rate_limiting] @allow_unauthenticated = [:allow_unauthenticated] apply_rate_limits() # Configure middleware configure_middleware() # Add MCP endpoint route to Otto add_mcp_endpoint_route warn_if_unauthenticated! Otto.logger.info "[MCP] Server enabled with HTTP endpoint: #{@http_endpoint}" if Otto.debug end |
#enabled? ⇒ Boolean
93 94 95 |
# File 'lib/otto/mcp/server.rb', line 93 def enabled? @enabled end |
#register_mcp_route(route_info) ⇒ Object
97 98 99 100 101 102 103 104 |
# File 'lib/otto/mcp/server.rb', line 97 def register_mcp_route(route_info) case route_info[:type] when :mcp_resource register_resource(route_info) when :mcp_tool register_tool(route_info) end end |