Module: Anthropic::Helpers::Tools::Mcp

Defined in:
lib/anthropic/helpers/tools/mcp.rb

Overview

Helpers for integrating Model Context Protocol (MCP) servers with the Anthropic SDK.

These helpers convert types returned by the mcp gem into the shapes the Beta Messages API accepts, so you don't have to write glue code yourself.

The mcp gem is an optional dependency; install it separately:

gem install mcp

Examples:

Convert MCP tools and run them through tool_runner

require "mcp"
require "anthropic"

transport  = MCP::Client::HTTP.new(url: "https://example.com/mcp")
mcp_client = MCP::Client.new(transport: transport)
anthropic  = Anthropic::Client.new

runner = anthropic.beta.messages.tool_runner(
  model: "claude-sonnet-4-5",
  max_tokens: 1024,
  messages: [{role: "user", content: "Use the available tools"}],
  tools: Anthropic::Mcp.tools(mcp_client.tools, mcp_client)
)
runner.run_until_finished

Defined Under Namespace

Classes: Tool, UnsupportedMCPValueError

Constant Summary collapse

SUPPORTED_IMAGE_TYPES =
Set.new(%w[image/jpeg image/png image/gif image/webp]).freeze

Class Method Summary collapse

Class Method Details

.content(mcp_content, cache_control: nil) ⇒ Hash

Convert a single MCP content item into a Beta content block.

Handles text, image, and embedded resource content types. Raises UnsupportedMCPValueError for audio or resource_link types.

Parameters:

  • mcp_content (MCP::Content::Text, MCP::Content::Image, MCP::Content::EmbeddedResource, Hash)
  • cache_control (Hash, nil) (defaults to: nil)

Returns:

  • (Hash)


197
198
199
200
201
202
203
# File 'lib/anthropic/helpers/tools/mcp.rb', line 197

def content(mcp_content, cache_control: nil)
  require_mcp!
  h = to_hash!(mcp_content, "MCP content")
  block = convert_content(h)
  block[:cache_control] = cache_control if cache_control
  block
end

.convert_tool_result(response) ⇒ Object

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.

Called by Anthropic::Helpers::Tools::Mcp::Tool#call; converts a JSON-RPC tools/call response into the value the tool runner expects.



257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
# File 'lib/anthropic/helpers/tools/mcp.rb', line 257

def convert_tool_result(response)
  result = nested_result(response)
  is_error = hkey(result, :isError)
  content_items = hkey(result, :content) || []
  structured = hkey(result, :structuredContent)

  if is_error
    blocks = content_items.map { content(_1) }
    raise Anthropic::Errors::Error, render_error_blocks(blocks)
  end

  return JSON.generate(structured) if content_items.empty? && structured

  content_items.map { content(_1) }
end

.message(mcp_message, cache_control: nil) ⇒ Hash

Convert an MCP prompt message into a Beta message parameter.

Parameters:

  • mcp_message (MCP::Prompt::Message, Hash)
  • cache_control (Hash, nil) (defaults to: nil)

    Forwarded to the produced content block.

Returns:

  • (Hash)


177
178
179
180
181
182
183
184
185
186
# File 'lib/anthropic/helpers/tools/mcp.rb', line 177

def message(mcp_message, cache_control: nil)
  require_mcp!
  h = to_hash!(mcp_message, "MCP prompt message")
  role = hkey(h, :role)
  role = role.to_sym if role.respond_to?(:to_sym)
  {
    role: role,
    content: [content(hkey(h, :content), cache_control: cache_control)]
  }
end

.resource_to_contents(result, cache_control: nil) ⇒ Array<Hash>

Convert MCP resource read results into Beta content blocks — one per item in contents. Raises UnsupportedMCPValueError on any item whose MIME type is unsupported.

Parameters:

  • result (Hash, Array, #contents)

    The result from mcp_client.read_resource(uri: ...). The mcp gem returns just the contents array — both that and a {contents: [...]} hash are accepted.

  • cache_control (Hash, nil) (defaults to: nil)

    Forwarded to each produced block.

Returns:

  • (Array<Hash>)


215
216
217
218
219
220
221
222
223
224
225
226
227
228
# File 'lib/anthropic/helpers/tools/mcp.rb', line 215

def resource_to_contents(result, cache_control: nil)
  require_mcp!
  contents = extract_resource_contents(result)
  if contents.empty?
    raise UnsupportedMCPValueError,
          "Resource contents array must contain at least one item"
  end

  contents.map do |item|
    block = resource_contents_to_block(to_hash!(item, "resource"))
    block[:cache_control] = cache_control if cache_control
    block
  end
end

.resource_to_files(result) ⇒ Array<Anthropic::FilePart>

Convert MCP resource read results into FilePart instances suitable for client.beta.files.upload(file: ...). No MIME filtering — every item in contents becomes a file.

Parameters:

  • result (Hash, Array, #contents)

Returns:



236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
# File 'lib/anthropic/helpers/tools/mcp.rb', line 236

def resource_to_files(result)
  require_mcp!
  contents = extract_resource_contents(result)
  if contents.empty?
    raise UnsupportedMCPValueError,
          "Resource contents array must contain at least one item"
  end

  contents.map do |item|
    resource = to_hash!(item, "resource")
    Anthropic::FilePart.new(
      StringIO.new(resource_bytes(resource)),
      filename: filename_from_uri(hkey(resource, :uri)),
      content_type: hkey(resource, :mimeType)
    )
  end
end

.tool(mcp_tool, mcp_client, cache_control: nil, defer_loading: nil, allowed_callers: nil, eager_input_streaming: nil, input_examples: nil, strict: nil) ⇒ Anthropic::Helpers::Tools::Mcp::Tool

Convert an MCP tool definition into a runnable tool for tool_runner.

Parameters:

  • mcp_tool (MCP::Client::Tool, Hash)

    An MCP tool, typically from mcp_client.list_tools / mcp_client.tools. May be a typed MCP::Client::Tool or a hash with :name, :description, :input_schema (or :inputSchema).

  • mcp_client (#call_tool)

    The MCP client used to invoke the tool.

  • cache_control (Hash, nil) (defaults to: nil)

    Prompt-caching control passed through to the tool definition.

  • defer_loading (Boolean, nil) (defaults to: nil)

    If true, the tool is excluded from the initial system prompt.

  • allowed_callers (Array<Symbol, String>, nil) (defaults to: nil)

    Restricts which callers may invoke the tool.

  • eager_input_streaming (Boolean, nil) (defaults to: nil)

    Enables eager input streaming for the tool.

  • input_examples (Array<Hash>, nil) (defaults to: nil)

    Example inputs for the tool.

  • strict (Boolean, nil) (defaults to: nil)

    When true, guarantees schema validation on tool names and inputs.

Returns:



140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# File 'lib/anthropic/helpers/tools/mcp.rb', line 140

def tool(
  mcp_tool,
  mcp_client,
  cache_control: nil,
  defer_loading: nil,
  allowed_callers: nil,
  eager_input_streaming: nil,
  input_examples: nil,
  strict: nil
)
  require_mcp!
  Tool.build(
    mcp_tool: mcp_tool,
    mcp_client: mcp_client,
    cache_control: cache_control,
    defer_loading: defer_loading,
    allowed_callers: allowed_callers,
    eager_input_streaming: eager_input_streaming,
    input_examples: input_examples,
    strict: strict
  )
end

.tools(mcp_tools, mcp_client, **opts) ⇒ Array<Anthropic::Helpers::Tools::Mcp::Tool>

Convert a list of MCP tools into runnable tools.

Parameters:

  • mcp_tools (Array<MCP::Client::Tool, Hash>)
  • mcp_client (#call_tool)

Returns:



168
169
170
# File 'lib/anthropic/helpers/tools/mcp.rb', line 168

def tools(mcp_tools, mcp_client, **opts)
  mcp_tools.map { tool(_1, mcp_client, **opts) }
end