LangChain.MCP.ToolExecutor (LangChain MCP v0.2.0)

View Source

Executes MCP tool calls and handles responses.

This module bridges MCP tool execution with LangChain's function calling system. It handles:

  • Calling MCP tools via Anubis.Client
  • Converting results to LangChain format (text, ContentParts, or ToolResult)
  • Error handling with fallback support
  • Timeout and async execution options

Examples

# Simple execution
config = Config.new!(client: MyApp.MCPClient)
{:ok, result} = ToolExecutor.execute(config, "search", %{"query" => "elixir"})

# With fallback
config = Config.new!(
  client: MyApp.PrimaryMCP,
  fallback_client: MyApp.BackupMCP
)
{:ok, result} = ToolExecutor.execute(config, "search", %{"query" => "elixir"})

# Result formats:
# - String: "Search results: ..."
# - ContentParts: [%ContentPart{type: :text, ...}, %ContentPart{type: :image, ...}]
# - ToolResult: %ToolResult{content: ..., is_error: false}

Summary

Functions

Executes an MCP tool and returns the result in LangChain format.

Executes a tool on a specific client without fallback logic.

Lists all available tools on an MCP server.

Validates that a tool exists on the MCP server before execution.

Types

execution_result()

Functions

execute(config, tool_name, args, context \\ %{})

@spec execute(LangChain.MCP.Config.t(), String.t(), map(), map()) ::
  {:ok, execution_result()} | {:error, String.t()}

Executes an MCP tool and returns the result in LangChain format.

Parameters

  • config - MCP Config struct
  • tool_name - Name of the tool to execute
  • args - Map of arguments to pass to the tool
  • context - Optional context map (merged with config context)

Returns

  • {:ok, result} - Success with string, ContentParts, or ToolResult
  • {:error, reason} - Failure with error message

Examples

iex> config = Config.new!(client: MyApp.MCPClient)
iex> {:ok, result} = ToolExecutor.execute(config, "echo", %{"text" => "hello"})
iex> is_binary(result)
true

execute_on_client(client, tool_name, args, timeout \\ 30000, context \\ %{})

@spec execute_on_client(module(), String.t(), map(), pos_integer(), map()) ::
  {:ok, execution_result()} | {:error, String.t()}

Executes a tool on a specific client without fallback logic.

Used internally by execute/4 and useful for testing.

Parameters

  • client - Anubis.Client module
  • tool_name - Tool name
  • args - Arguments map
  • timeout - Timeout in milliseconds (default: 30_000)
  • context - Context map (default: %{})

Returns

  • {:ok, result} - Success
  • {:error, reason} - Failure

list_tools(client)

@spec list_tools(module()) :: {:ok, [map()]} | {:error, String.t()}

Lists all available tools on an MCP server.

Parameters

  • client - Anubis.Client module

Returns

  • {:ok, tool_list} - List of tool maps
  • {:error, reason} - Error listing tools

Examples

iex> {:ok, tools} = ToolExecutor.list_tools(MyApp.MCPClient)
iex> is_list(tools)
true

validate_tool(client, tool_name)

@spec validate_tool(module(), String.t()) :: :ok | {:error, String.t()}

Validates that a tool exists on the MCP server before execution.

This is optional but can provide better error messages.

Parameters

  • client - Anubis.Client module
  • tool_name - Tool name to validate

Returns

  • :ok - Tool exists
  • {:error, reason} - Tool not found or error listing tools

Examples

iex> ToolExecutor.validate_tool(MyApp.MCPClient, "search")
:ok

iex> ToolExecutor.validate_tool(MyApp.MCPClient, "nonexistent")
{:error, "Tool 'nonexistent' not found on MCP server"}