Class: Phronomy::Tools::Mcp

Inherits:
Agent::Context::Capability::Base show all
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:

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.

Examples:

web_search = Phronomy::Tools::Mcp.from_server(
  "stdio://./mcp-server",
  tool_name: "search_web"
)
agent_class.tools(web_search)

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Agent::Context::Capability::Base

#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?, retry_on, retry_policies, scope, tool_name

Constructor Details

#initializeMcp

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.



290
291
292
293
294
# File 'lib/phronomy/tools/mcp.rb', line 290

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.

Parameters:

  • server_uri (String)

    URI of the MCP server.

  • tool_name (String)

    the tool name as registered in the MCP server

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

    additional HTTP headers forwarded to discovery and execution

Returns:

  • (Mcp)

    configured tool instance



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.message}"
  ensure
    close_transport_safely(transport)
  end

  build_tool_class(tool_name, server_uri, tool_def, headers: headers).new
end

Instance Method Details

#closevoid

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.



315
316
317
# File 'lib/phronomy/tools/mcp.rb', line 315

def close
  @mcp_call_mutex.synchronize { invalidate_mcp_client! }
end

#execute(cancellation_token: nil, **args) ⇒ String, ...

Executes the remote MCP tool.

Parameters:

Returns:

  • (String, Array, Hash)


300
301
302
303
304
305
# File 'lib/phronomy/tools/mcp.rb', line 300

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