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 `[…]` 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