Class: MCPClient::Tool
- Inherits:
-
Object
- Object
- MCPClient::Tool
- Includes:
- DeepCopy
- Defined in:
- lib/mcp_client/tool.rb
Overview
Representation of an MCP tool
Instance Attribute Summary collapse
-
#annotations ⇒ Hash?
readonly
Optional annotations describing tool behavior (e.g., readOnly, destructive).
-
#description ⇒ String
readonly
The description of the tool.
-
#icons ⇒ Array<Hash>?
readonly
Optional icons for display in user interfaces (MCP 2025-11-25, SEP-973).
-
#meta ⇒ Object
readonly
Returns the value of attribute meta.
-
#name ⇒ String
readonly
The name of the tool.
-
#output_schema ⇒ Hash?
readonly
Optional JSON schema for structured tool outputs (MCP 2025-06-18).
-
#schema ⇒ Hash
readonly
The JSON schema for the tool inputs.
-
#schema_identity ⇒ Object
readonly
Returns the value of attribute schema_identity.
-
#server ⇒ MCPClient::ServerBase?
readonly
The server this tool belongs to.
-
#task_support ⇒ String?
readonly
Tool-level task negotiation (MCP 2025-11-25): 'forbidden' (default), 'optional', or 'required'; nil when not advertised.
-
#title ⇒ String?
readonly
Optional human-readable name of the tool for display purposes.
Class Method Summary collapse
-
.from_json(data, server: nil) ⇒ MCPClient::Tool
Create a Tool instance from JSON data.
Instance Method Summary collapse
-
#destructive? ⇒ Boolean
Check if the tool is marked as destructive (legacy annotation field).
-
#destructive_hint? ⇒ Boolean
Check the destructiveHint annotation (MCP 2025-11-25) When true, the tool may perform destructive updates.
-
#idempotent_hint? ⇒ Boolean
Check the idempotentHint annotation (MCP 2025-11-25) When true, calling the tool repeatedly with the same arguments has no additional effect.
-
#initialize(name:, description:, schema:, title: nil, output_schema: nil, annotations: nil, server: nil, task_support: nil, icons: nil, meta: nil, output_schema_declared: nil) ⇒ Tool
constructor
Initialize a new Tool.
-
#open_world_hint? ⇒ Boolean
Check the openWorldHint annotation (MCP 2025-11-25) When true, the tool may interact with the "open world" (external entities).
-
#read_only? ⇒ Boolean
Check if the tool is marked as read-only (legacy annotation field).
-
#read_only_hint? ⇒ Boolean
Check the readOnlyHint annotation (MCP 2025-11-25) When true, the tool does not modify its environment.
-
#requires_confirmation? ⇒ Boolean
Check if the tool requires confirmation before execution.
-
#structured_output? ⇒ Boolean
Check if the tool supports structured outputs (MCP 2025-06-18).
-
#supports_task? ⇒ Boolean
Whether task-augmented execution is allowed for this tool (MCP 2025-11-25).
-
#task_forbidden? ⇒ Boolean
Whether task-augmented execution is forbidden (the default when unset).
-
#task_optional? ⇒ Boolean
Whether task-augmented execution is optional for this tool.
-
#task_required? ⇒ Boolean
Whether task-augmented execution is required for this tool.
-
#to_anthropic_tool ⇒ Hash
Convert tool to Anthropic Claude tool specification format.
-
#to_google_tool ⇒ Hash
Convert tool to Google Vertex AI tool specification format.
-
#to_openai_tool ⇒ Hash
Convert tool to OpenAI function specification format.
Methods included from DeepCopy
copy, #initialize_copy, shallow_copy
Constructor Details
#initialize(name:, description:, schema:, title: nil, output_schema: nil, annotations: nil, server: nil, task_support: nil, icons: nil, meta: nil, output_schema_declared: nil) ⇒ Tool
Initialize a new Tool
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/mcp_client/tool.rb', line 54 def initialize(name:, description:, schema:, title: nil, output_schema: nil, annotations: nil, server: nil, task_support: nil, icons: nil, meta: nil, output_schema_declared: nil) @name = name @title = title @description = description @schema = schema @output_schema = output_schema # An explicit `"outputSchema": null` declares a schema — an unusable # one — and is not the same as leaving the member out. @output_schema_declared = output_schema_declared.nil? ? !output_schema.nil? : output_schema_declared @annotations = annotations @server = server @task_support = task_support @icons = icons @meta = # A frozen object is copied by reference by DeepCopy, so the token # survives every copy of this definition. @schema_identity = Object.new.freeze end |
Instance Attribute Details
#annotations ⇒ Hash? (readonly)
Returns optional annotations describing tool behavior (e.g., readOnly, destructive).
31 32 |
# File 'lib/mcp_client/tool.rb', line 31 attr_reader :name, :title, :description, :schema, :output_schema, :annotations, :server, :task_support, :icons, :meta |
#description ⇒ String (readonly)
Returns the description of the tool.
31 32 |
# File 'lib/mcp_client/tool.rb', line 31 attr_reader :name, :title, :description, :schema, :output_schema, :annotations, :server, :task_support, :icons, :meta |
#icons ⇒ Array<Hash>? (readonly)
Returns optional icons for display in user interfaces (MCP 2025-11-25, SEP-973).
31 32 |
# File 'lib/mcp_client/tool.rb', line 31 attr_reader :name, :title, :description, :schema, :output_schema, :annotations, :server, :task_support, :icons, :meta |
#meta ⇒ Object (readonly)
Returns the value of attribute meta.
31 32 |
# File 'lib/mcp_client/tool.rb', line 31 attr_reader :name, :title, :description, :schema, :output_schema, :annotations, :server, :task_support, :icons, :meta |
#name ⇒ String (readonly)
Returns the name of the tool.
31 32 33 |
# File 'lib/mcp_client/tool.rb', line 31 def name @name end |
#output_schema ⇒ Hash? (readonly)
Returns optional JSON schema for structured tool outputs (MCP 2025-06-18).
31 32 |
# File 'lib/mcp_client/tool.rb', line 31 attr_reader :name, :title, :description, :schema, :output_schema, :annotations, :server, :task_support, :icons, :meta |
#schema ⇒ Hash (readonly)
Returns the JSON schema for the tool inputs.
31 32 |
# File 'lib/mcp_client/tool.rb', line 31 attr_reader :name, :title, :description, :schema, :output_schema, :annotations, :server, :task_support, :icons, :meta |
#schema_identity ⇒ Object (readonly)
Returns the value of attribute schema_identity.
39 40 41 |
# File 'lib/mcp_client/tool.rb', line 39 def schema_identity @schema_identity end |
#server ⇒ MCPClient::ServerBase? (readonly)
Returns the server this tool belongs to.
31 32 |
# File 'lib/mcp_client/tool.rb', line 31 attr_reader :name, :title, :description, :schema, :output_schema, :annotations, :server, :task_support, :icons, :meta |
#task_support ⇒ String? (readonly)
Returns tool-level task negotiation (MCP 2025-11-25): 'forbidden' (default), 'optional', or 'required'; nil when not advertised.
31 32 |
# File 'lib/mcp_client/tool.rb', line 31 attr_reader :name, :title, :description, :schema, :output_schema, :annotations, :server, :task_support, :icons, :meta |
#title ⇒ String? (readonly)
Returns optional human-readable name of the tool for display purposes.
31 32 |
# File 'lib/mcp_client/tool.rb', line 31 attr_reader :name, :title, :description, :schema, :output_schema, :annotations, :server, :task_support, :icons, :meta |
Class Method Details
.from_json(data, server: nil) ⇒ MCPClient::Tool
Create a Tool instance from JSON data
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/mcp_client/tool.rb', line 78 def self.from_json(data, server: nil) # Some servers (Playwright MCP CLI) use 'inputSchema' instead of 'schema' # Handle both string and symbol keys schema = data['inputSchema'] || data[:inputSchema] || data['schema'] || data[:schema] # By key presence: a boolean false schema is a schema (one that # accepts nothing), not an absent one, and neither is an explicit null # (an unusable schema root, like any other non-schema value). output_schema_declared = data.key?('outputSchema') || data.key?(:outputSchema) output_schema = data.key?('outputSchema') ? data['outputSchema'] : data[:outputSchema] annotations = data['annotations'] || data[:annotations] title = data['title'] || data[:title] execution = data['execution'] || data[:execution] task_support = execution && (execution['taskSupport'] || execution[:taskSupport]) icons = data['icons'] || data[:icons] = data['_meta'] || data[:_meta] new( name: data['name'] || data[:name], description: data['description'] || data[:description], schema: schema, title: title, output_schema: output_schema, output_schema_declared: output_schema_declared, annotations: annotations, server: server, task_support: task_support, icons: icons, meta: ) end |
Instance Method Details
#destructive? ⇒ Boolean
Check if the tool is marked as destructive (legacy annotation field)
151 152 153 |
# File 'lib/mcp_client/tool.rb', line 151 def destructive? !!(@annotations && @annotations['destructive'] == true) end |
#destructive_hint? ⇒ Boolean
Check the destructiveHint annotation (MCP 2025-11-25) When true, the tool may perform destructive updates. Only meaningful when readOnlyHint is false. Per the MCP ToolAnnotations schema the default is true, i.e. a non-read-only tool without this hint is assumed to be potentially destructive.
178 179 180 181 182 |
# File 'lib/mcp_client/tool.rb', line 178 def destructive_hint? return true unless @annotations fetch_annotation_hint('destructiveHint', :destructiveHint, true) end |
#idempotent_hint? ⇒ Boolean
Check the idempotentHint annotation (MCP 2025-11-25) When true, calling the tool repeatedly with the same arguments has no additional effect. Only meaningful when readOnlyHint is false.
188 189 190 191 192 |
# File 'lib/mcp_client/tool.rb', line 188 def idempotent_hint? return false unless @annotations fetch_annotation_hint('idempotentHint', :idempotentHint, false) end |
#open_world_hint? ⇒ Boolean
Check the openWorldHint annotation (MCP 2025-11-25) When true, the tool may interact with the "open world" (external entities).
197 198 199 200 201 |
# File 'lib/mcp_client/tool.rb', line 197 def open_world_hint? return true unless @annotations fetch_annotation_hint('openWorldHint', :openWorldHint, true) end |
#read_only? ⇒ Boolean
Check if the tool is marked as read-only (legacy annotation field)
144 145 146 |
# File 'lib/mcp_client/tool.rb', line 144 def read_only? !!(@annotations && @annotations['readOnly'] == true) end |
#read_only_hint? ⇒ Boolean
Check the readOnlyHint annotation (MCP 2025-11-25) When true, the tool does not modify its environment. Per the MCP ToolAnnotations schema the default is false, i.e. a tool without this hint is assumed to potentially modify its environment.
166 167 168 169 170 |
# File 'lib/mcp_client/tool.rb', line 166 def read_only_hint? return false unless @annotations fetch_annotation_hint('readOnlyHint', :readOnlyHint, false) end |
#requires_confirmation? ⇒ Boolean
Check if the tool requires confirmation before execution
157 158 159 |
# File 'lib/mcp_client/tool.rb', line 157 def requires_confirmation? !!(@annotations && @annotations['requiresConfirmation'] == true) end |
#structured_output? ⇒ Boolean
Check if the tool supports structured outputs (MCP 2025-06-18)
205 206 207 208 209 210 211 |
# File 'lib/mcp_client/tool.rb', line 205 def structured_output? # Any declared schema counts: a boolean schema (true: any value; # false: none), the empty schema `{}` (any value) and an explicit null # (a schema root the validator rejects) included. Only the absence of # outputSchema means no structured output. @output_schema_declared end |
#supports_task? ⇒ Boolean
Whether task-augmented execution is allowed for this tool (MCP 2025-11-25). True when execution.taskSupport is 'optional' or 'required'.
216 217 218 |
# File 'lib/mcp_client/tool.rb', line 216 def supports_task? %w[optional required].include?(@task_support) end |
#task_forbidden? ⇒ Boolean
Whether task-augmented execution is forbidden (the default when unset)
234 235 236 |
# File 'lib/mcp_client/tool.rb', line 234 def task_forbidden? @task_support.nil? || @task_support == 'forbidden' end |
#task_optional? ⇒ Boolean
Whether task-augmented execution is optional for this tool
228 229 230 |
# File 'lib/mcp_client/tool.rb', line 228 def task_optional? @task_support == 'optional' end |
#task_required? ⇒ Boolean
Whether task-augmented execution is required for this tool
222 223 224 |
# File 'lib/mcp_client/tool.rb', line 222 def task_required? @task_support == 'required' end |
#to_anthropic_tool ⇒ Hash
Convert tool to Anthropic Claude tool specification format
123 124 125 126 127 128 129 |
# File 'lib/mcp_client/tool.rb', line 123 def to_anthropic_tool { name: @name, description: @description, input_schema: cleaned_schema(@schema) } end |
#to_google_tool ⇒ Hash
Convert tool to Google Vertex AI tool specification format
133 134 135 136 137 138 139 |
# File 'lib/mcp_client/tool.rb', line 133 def to_google_tool { name: @name, description: @description, parameters: cleaned_schema(@schema) } end |
#to_openai_tool ⇒ Hash
Convert tool to OpenAI function specification format
110 111 112 113 114 115 116 117 118 119 |
# File 'lib/mcp_client/tool.rb', line 110 def to_openai_tool { type: 'function', function: { name: @name, description: @description, parameters: @schema } } end |