class RubyLLM::MCP::Tool
A tool offered by an MCP server. It works anywhere a Tool does: a chat renders its name, description, and schema for the model, and calling it calls the server.
tool = linear.tools.first tool.read_only? # => true chat.with_tools(tool)
The behavior predicates read the server’s annotations. They are hints from the server, so trust them only as far as you trust the server.
Attributes
The description the model sees.
The tool’s _meta as the server sent it: a Hash with String keys, empty when there is none. Extensions keep their own vocabulary there.
The name the model calls this tool by.
The JSON Schema for the arguments the model provides.
The tool’s name on the server.
The URI of the tool’s UI, the ui:// resource an MCP App renders next to the tool’s results, or nil for a tool without one. Read it with MCP#resource.
Who may call the tool, as Symbols: :model when chats offer it to the model, :app when a UI from the same server may call it. Tools say nothing about it unless they belong to an MCP App, which makes them [:model, :app].
Public Instance Methods
Source
# File lib/ruby_llm/mcp/tool.rb, line 99 def call(**arguments) @mcp.run(self, arguments.except(:tool_call)) end
Calls the tool on the server and returns its MCP::Result, what the wrap: method made of it, or { error: } when the tool failed. A chat sends the model the result’s content. When the server runs the call as a task, returns the MCP::Task without waiting, and a chat pauses the tool call until the task is done. Raises MCP::InputRequiredError when the server needs input that no MCP.before_input_request callback gave.
Source
# File lib/ruby_llm/mcp/tool.rb, line 71 def destructive? !read_only? && @annotations['destructiveHint'] != false end
Returns whether the tool may destroy or overwrite data. Tools that are not read-only count as destructive unless the server says otherwise.
Source
# File lib/ruby_llm/mcp/tool.rb, line 77 def idempotent? @annotations['idempotentHint'] == true end
Returns whether calling the tool again with the same arguments has no further effect.
Source
# File lib/ruby_llm/mcp/tool.rb, line 82 def open_world? @annotations['openWorldHint'] != false end
Returns whether the tool reaches beyond the server, such as the web.
Source
# File lib/ruby_llm/mcp/tool.rb, line 64 def read_only? @annotations['readOnlyHint'] == true end
Returns whether the server says the tool only reads.
Source
# File lib/ruby_llm/mcp/tool.rb, line 88 def requires_approval? @mcp.requires_approval?(self) end
Returns whether the tool pauses for approval, as declared with MCP.requires_approval.