Class: Phronomy::Tools::Mcp
- Inherits:
-
Agent::Context::Capability::Base
- Object
- RubyLLM::Tool
- Agent::Context::Capability::Base
- Phronomy::Tools::Mcp
- Defined in:
- lib/phronomy/tools/mcp.rb
Overview
A Phronomy::Agent::Context::Capability::Base subclass that wraps a tool exposed by an external MCP (Model Context Protocol) server.
Uses the official MCP Ruby SDK v1.x for transport handling, which provides the MCP initialize handshake, HTTP/SSE parsing, and request cancellation.
Supports two transport schemes:
- "stdio://<command>" — spawns a child process via MCP::Client::Stdio.
- "http://<url>" / "https://<url>" — connects via MCP::Client::HTTP.
Each generated tool instance owns one MCP client. Calls, reconnects, and explicit close operations are serialized because the SDK's stdio transport does not support concurrent response readers.
Class Method Summary collapse
-
.from_server(server_uri, tool_name:, headers: {}) ⇒ Mcp
Build a Mcp instance by querying a running MCP server for the tool definition identified by
tool_name.
Instance Method Summary collapse
- #approval_metadata ⇒ Object
-
#close ⇒ void
Closes the currently connected client synchronously.
-
#execute(cancellation_token: nil, **args) ⇒ String, ...
Executes the remote MCP tool.
-
#initialize ⇒ Mcp
constructor
private
A new instance of Mcp.
-
#tool_origin ⇒ Object
MCP Tools fail closed by default and identify their remote origin.
Methods inherited from Agent::Context::Capability::Base
approval_facts, #call, #call_async, execution_mode, max_result_size, #name, on_error, on_schema_error, param, param_enums, param_schemas, #params_schema, redact_params, requires_approval, #requires_approval, #requires_approval?, tool_name
Constructor Details
#initialize ⇒ Mcp
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns a new instance of Mcp.
315 316 317 318 319 |
# File 'lib/phronomy/tools/mcp.rb', line 315 def initialize @mcp_call_mutex = Mutex.new @mcp_client = nil build_and_connect_client! end |
Class Method Details
.from_server(server_uri, tool_name:, headers: {}) ⇒ Mcp
Build a Mcp instance by querying a running MCP server for the
tool definition identified by tool_name.
additionalProperties omitted from the remote schema is accepted, but
Phronomy still exposes and accepts only parameters declared in properties.
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/phronomy/tools/mcp.rb', line 65 def from_server(server_uri, tool_name:, headers: {}) transport = nil begin transport = build_transport(server_uri, headers: headers) client = MCP::Client.new(transport: transport) client.connect tool_def = extract_tool_def(client, tool_name.to_s, server_uri) rescue ArgumentError, Phronomy::ToolError raise rescue => e raise Phronomy::ToolError, "MCP connection failed: #{e.}" ensure close_transport_safely(transport) end build_tool_class(tool_name, server_uri, tool_def, headers: headers).new end |
Instance Method Details
#approval_metadata ⇒ Object
295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 |
# File 'lib/phronomy/tools/mcp.rb', line 295 def scheme, rest = self.class.instance_variable_get(:@mcp_server_uri).to_s.split("://", 2) server_origin = case scheme when "http", "https" uri = URI.parse("#{scheme}://#{rest}") default_port = (scheme == "https") ? 443 : 80 suffix = (uri.port == default_port) ? "" : ":#{uri.port}" "#{scheme}://#{uri.host}#{suffix}" when "stdio" command = Shellwords.split(rest.to_s).first "stdio://#{command}" else scheme.to_s end {transport: scheme&.to_sym, server_origin: server_origin} rescue URI::InvalidURIError {transport: :unknown, server_origin: "unknown"} end |
#close ⇒ void
This method returns an undefined value.
Closes the currently connected client synchronously. A transport already detached after cancellation is owned by the Runtime cleanup pool and is drained during Runtime shutdown; this method does not wait for that older cleanup operation.
The instance can be used again after close; the next call reconnects.
340 341 342 |
# File 'lib/phronomy/tools/mcp.rb', line 340 def close @mcp_call_mutex.synchronize { invalidate_mcp_client! } end |
#execute(cancellation_token: nil, **args) ⇒ String, ...
Executes the remote MCP tool.
325 326 327 328 329 330 |
# File 'lib/phronomy/tools/mcp.rb', line 325 def execute(cancellation_token: nil, **args) @mcp_call_mutex.synchronize do ensure_mcp_client! perform_mcp_call(cancellation_token: cancellation_token, args: args) end end |
#tool_origin ⇒ Object
MCP Tools fail closed by default and identify their remote origin.
291 292 293 |
# File 'lib/phronomy/tools/mcp.rb', line 291 def tool_origin :mcp end |