Class: Hitch::MCP::Internal::SDKAdapter
- Inherits:
-
Object
- Object
- Hitch::MCP::Internal::SDKAdapter
- Defined in:
- app/models/hitch/mcp/internal/sdk_adapter.rb,
app/models/hitch/mcp/internal/sdk_adapter/response_normalizer.rb
Constant Summary collapse
- STRUCTURAL_PARAMS =
{ "server/discover" => [], "tools/list" => %w[cursor], "tools/call" => %w[name arguments] }.freeze
- SDK_REQUEST_ID =
"hitch_request"
Class Method Summary collapse
-
.build_sdk_tool(name:, description:, input_schema:, output_schema: nil, annotations: nil) ⇒ Object
Builds the SDK-facing tool wrapper once per registry snapshot — ::MCP::Tool.define compiles the JSON schemas eagerly, which is the cost this memoization exists to stop paying per tool per request.
- .call(**arguments) ⇒ Object
- .validate_tool_name!(name) ⇒ Object
Instance Method Summary collapse
- #call ⇒ Object
-
#initialize(verified_request:, tools:, context:, server_info:) ⇒ SDKAdapter
constructor
A new instance of SDKAdapter.
Constructor Details
#initialize(verified_request:, tools:, context:, server_info:) ⇒ SDKAdapter
Returns a new instance of SDKAdapter.
50 51 52 53 54 55 56 |
# File 'app/models/hitch/mcp/internal/sdk_adapter.rb', line 50 def initialize(verified_request:, tools:, context:, server_info:) @request = frozen_hash!(verified_request) @tools = tools.dup.freeze @context = context @server_info = frozen_hash!(server_info) @tool_responses = [] end |
Class Method Details
.build_sdk_tool(name:, description:, input_schema:, output_schema: nil, annotations: nil) ⇒ Object
Builds the SDK-facing tool wrapper once per registry snapshot — ::MCP::Tool.define compiles the JSON schemas eagerly, which is the cost this memoization exists to stop paying per tool per request. The block closes over nothing request-scoped: each request routes through the dispatcher its own ::MCP::Server carries in server_context, so a shared wrapper can never see another request's principal.
28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'app/models/hitch/mcp/internal/sdk_adapter.rb', line 28 def build_sdk_tool(name:, description:, input_schema:, output_schema: nil, annotations: nil) name = validate_tool_name!(name) ::MCP::Tool.define( name: name, description: description, input_schema: input_schema, output_schema: output_schema, annotations: annotations ) do |server_context:, **arguments| server_context.fetch(:hitch_dispatch).call(name, server_context, arguments) end end |
.call(**arguments) ⇒ Object
17 18 19 |
# File 'app/models/hitch/mcp/internal/sdk_adapter.rb', line 17 def call(**arguments) new(**arguments).call end |
.validate_tool_name!(name) ⇒ Object
41 42 43 44 45 46 47 |
# File 'app/models/hitch/mcp/internal/sdk_adapter.rb', line 41 def validate_tool_name!(name) return name if Protocol.tool_name?(name) raise ArgumentError, "tool name must be 1-#{Protocol::MAX_TOOL_NAME_LENGTH} ASCII letters, digits, " \ "underscore, dot, or dash" end |
Instance Method Details
#call ⇒ Object
58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'app/models/hitch/mcp/internal/sdk_adapter.rb', line 58 def call return method_not_found unless Protocol::METHODS.include?(request_method) return invalid_params if reserved_server_context? response = build_server.handle(structural_request) ResponseNormalizer.call( response: response, method: request_method, server_info: server_info, request_id: read(request, "id"), tool_response: @tool_responses.last ) end |