Class: FastMcp::Tool

Inherits:
Object
  • Object
show all
Defined in:
lib/mcp/tool.rb

Overview

Main Tool class that represents an MCP Tool

Defined Under Namespace

Classes: InvalidArgumentsError

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(headers: {}) ⇒ Tool

Returns a new instance of Tool.



161
162
163
164
# File 'lib/mcp/tool.rb', line 161

def initialize(headers: {})
  @_meta = {}
  @headers = headers
end

Class Attribute Details

.serverObject

Returns the value of attribute server.



95
96
97
# File 'lib/mcp/tool.rb', line 95

def server
  @server
end

Instance Attribute Details

#_metaObject

Returns the value of attribute _meta.



186
187
188
# File 'lib/mcp/tool.rb', line 186

def _meta
  @_meta
end

#headersObject (readonly)

Returns the value of attribute headers.



187
188
189
# File 'lib/mcp/tool.rb', line 187

def headers
  @headers
end

Class Method Details

.annotations(annotations_hash = nil) ⇒ Object



138
139
140
141
142
# File 'lib/mcp/tool.rb', line 138

def annotations(annotations_hash = nil)
  return @annotations || {} if annotations_hash.nil?

  @annotations = annotations_hash
end

.arguments(&block) ⇒ Object



118
119
120
# File 'lib/mcp/tool.rb', line 118

def arguments(&block)
  @input_schema = Dry::Schema.JSON(&block)
end

.authorize(&block) ⇒ Object



144
145
146
147
# File 'lib/mcp/tool.rb', line 144

def authorize(&block)
  @authorization_blocks ||= []
  @authorization_blocks.push block
end

.call(**args) ⇒ Object

Raises:

  • (NotImplementedError)


149
150
151
# File 'lib/mcp/tool.rb', line 149

def call(**args)
  raise NotImplementedError, 'Subclasses must implement the call method'
end

.description(description = nil) ⇒ Object



132
133
134
135
136
# File 'lib/mcp/tool.rb', line 132

def description(description = nil)
  return @description if description.nil?

  @description = description
end

.input_schemaObject



122
123
124
# File 'lib/mcp/tool.rb', line 122

def input_schema
  @input_schema ||= Dry::Schema.JSON
end

.input_schema_to_jsonObject



153
154
155
156
157
158
# File 'lib/mcp/tool.rb', line 153

def input_schema_to_json
  return nil unless @input_schema

  compiler = SchemaCompiler.new
  compiler.process(@input_schema)
end

.metadata(key = nil, value = nil) ⇒ Object

Add metadata support for tools



107
108
109
110
111
112
113
114
115
116
# File 'lib/mcp/tool.rb', line 107

def (key = nil, value = nil)
  @metadata ||= {}
  if key.nil?
    @metadata
  elsif value.nil?
    @metadata[key]
  else
    @metadata[key] = value
  end
end

.tags(*tag_list) ⇒ Object

Add tagging support for tools



98
99
100
101
102
103
104
# File 'lib/mcp/tool.rb', line 98

def tags(*tag_list)
  if tag_list.empty?
    @tags || []
  else
    @tags = tag_list.flatten.map(&:to_sym)
  end
end

.tool_name(name = nil) ⇒ Object



126
127
128
129
130
# File 'lib/mcp/tool.rb', line 126

def tool_name(name = nil)
  return @name || self.name if name.nil?

  @name = name
end

Instance Method Details

#authorized?(**args) ⇒ Boolean

Returns:

  • (Boolean)

Raises:



166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# File 'lib/mcp/tool.rb', line 166

def authorized?(**args)
  auth_checks = self.class.ancestors.filter_map do |ancestor|
    ancestor.ancestors.include?(FastMcp::Tool) &&
      ancestor.instance_variable_get(:@authorization_blocks)
  end.flatten

  return true if auth_checks.empty?

  arg_validation = self.class.input_schema.call(args)
  raise InvalidArgumentsError, arg_validation.errors.to_h.to_json if arg_validation.errors.any?

  auth_checks.all? do |auth_check|
    if auth_check.parameters.empty?
      instance_exec(&auth_check)
    else
      instance_exec(**args, &auth_check)
    end
  end
end

#call_with_schema_validation!(**args) ⇒ Object



193
194
195
196
197
198
199
200
# File 'lib/mcp/tool.rb', line 193

def call_with_schema_validation!(**args)
  arg_validation = self.class.input_schema.call(args)
  raise InvalidArgumentsError, arg_validation.errors.to_h.to_json if arg_validation.errors.any?

  # When calling the tool, its metadata can be altered to be returned in response.
  # We return the altered metadata with the tool's result
  [call(**args), _meta]
end

#notify_resource_updated(uri) ⇒ Object



189
190
191
# File 'lib/mcp/tool.rb', line 189

def notify_resource_updated(uri)
  self.class.server.notify_resource_updated(uri)
end