LangChain.MCP.Adapter (LangChain MCP v0.2.0)
View SourceMain adapter for integrating MCP tools with LangChain.
This module provides the primary API for discovering MCP tools and converting them to LangChain Functions that can be used in LLMChains.
Features
- Tool discovery from MCP servers
- Automatic schema conversion
- Tool caching for performance
- Tool filtering
- Fallback client support
- Async execution configuration
Usage
# Define MCP client
defmodule MyApp.MCPClient do
use Anubis.Client,
name: "MyApp",
version: "1.0.0",
protocol_version: "2025-03-26"
end
# Create adapter
adapter = Adapter.new(client: MyApp.MCPClient)
# Discover and convert tools
functions = Adapter.to_functions(adapter)
# Use in LLMChain
chain = LLMChain.new!(%{llm: model})
|> LLMChain.add_tools(functions)
|> LLMChain.run(mode: :while_needs_response)With Options
adapter = Adapter.new(
client: MyApp.MCPClient,
cache_tools: true,
timeout: 60_000,
async: true,
fallback_client: MyApp.BackupMCP,
tool_filter: fn tool -> tool["name"] != "admin_only" end
)
Summary
Functions
Discovers tools from the MCP server without converting to Functions.
Returns the adapter's configuration.
Gets information about a specific tool.
Creates a new MCP adapter.
Refreshes the tool cache for an adapter.
Discovers tools from the MCP server and converts them to LangChain Functions.
Converts a single MCP tool to a LangChain Function.
Updates the adapter's configuration.
Validates that all required tools are available on the MCP server.
Waits for the associated server for a client to be ready.
Types
@type t() :: %LangChain.MCP.Adapter{ cached_tools: [map()] | nil, config: LangChain.MCP.Config.t() }
Functions
Discovers tools from the MCP server without converting to Functions.
Useful for inspecting available tools.
Parameters
adapter- Adapter structopts- Options (:refreshto force cache refresh)
Returns
{:ok, tools}- List of tool maps{:error, reason}- Error message
Examples
iex> {:ok, tools} = Adapter.discover_tools(adapter)
iex> Enum.map(tools, & &1["name"])
["search", "fetch", "analyze"]
@spec get_config(t()) :: LangChain.MCP.Config.t()
Returns the adapter's configuration.
Examples
iex> config = Adapter.get_config(adapter)
iex> config.client
MyApp.MCPClient
Gets information about a specific tool.
Parameters
adapter- Adapter structtool_name- Name of the tool
Returns
{:ok, tool}- Tool map{:error, :not_found}- Tool not found
Examples
iex> {:ok, tool} = Adapter.get_tool(adapter, "search")
iex> tool["description"]
"Search for information"
Creates a new MCP adapter.
Options
See LangChain.MCP.Config.new!/1 for all available options.
Examples
iex> adapter = Adapter.new(client: MyApp.MCPClient)
%Adapter{config: %Config{...}}
iex> adapter = Adapter.new(
...> client: MyApp.MCPClient,
...> cache_tools: true,
...> timeout: 60_000,
...> async: true
...> )
Refreshes the tool cache for an adapter.
Only useful if caching is enabled.
Parameters
adapter- Adapter struct
Returns
{:ok, updated_adapter}- Adapter with refreshed cache{:error, reason}- Error message
Examples
iex> {:ok, updated_adapter} = Adapter.refresh_cache(adapter)
@spec to_functions( t(), keyword() ) :: [LangChain.Function.t()]
Discovers tools from the MCP server and converts them to LangChain Functions.
Parameters
adapter- Adapter structopts- Optional keyword list:only- List of tool names to include:except- List of tool names to exclude:refresh- Force refresh cached tools (default: false)
Returns
- List of
LangChain.Function.t()structs
Examples
# Get all tools
functions = Adapter.to_functions(adapter)
# Get specific tools
functions = Adapter.to_functions(adapter, only: ["search", "fetch"])
# Exclude tools
functions = Adapter.to_functions(adapter, except: ["admin_tool"])
# Force refresh cache
functions = Adapter.to_functions(adapter, refresh: true)
@spec tool_to_function(t(), map()) :: LangChain.Function.t()
Converts a single MCP tool to a LangChain Function.
Parameters
adapter- Adapter structtool- MCP tool map
Returns
LangChain.Function.t()struct
Examples
iex> tool = %{
...> "name" => "search",
...> "description" => "Search for information",
...> "inputSchema" => %{
...> "type" => "object",
...> "properties" => %{"query" => %{"type" => "string"}},
...> "required" => ["query"]
...> }
...> }
iex> function = Adapter.tool_to_function(adapter, tool)
iex> function.name
"search"
Updates the adapter's configuration.
Parameters
adapter- Adapter structupdates- Keyword list of config updates
Returns
- Updated adapter
Examples
iex> updated = Adapter.update_config(adapter, timeout: 60_000, async: true)
iex> updated.config.timeout
60_000
Validates that all required tools are available on the MCP server.
Parameters
adapter- Adapter structtool_names- List of required tool names
Returns
:ok- All tools available{:error, missing_tools}- List of missing tool names
Examples
iex> Adapter.validate_tools(adapter, ["search", "fetch"])
:ok
iex> Adapter.validate_tools(adapter, ["search", "nonexistent"])
{:error, ["nonexistent"]}
@spec wait_for_server_ready(pid(), timeout :: non_neg_integer()) :: :ok | {:error, :initialization_timeout | :invalid_client}
Waits for the associated server for a client to be ready.
If a client is started with start_link/1 the server initialization is asynchronous, so calling functions such as Adapter.discover_tools/2 or Adapter.to_functions/2 immediately after start link will produce a 'Server capabilities not set' error.
In this case, calling wait_for_server_ready/1 before calls to the Adapter ensures the server has time to initialize.
Parameters
client_pid- The process ID for a Anubis client.timeout- Maximum time to wait in milliseconds (default: 5000)
Returns
:ok- Server is ready{:error, :initialization_timeout}- Server didn't initialize within timeout{:error, :invalid_client}- The provided PID is not a valid Anubis client
Examples
{:ok, client_pid} =
MCPClient.start_link(
client_info: ...,
capabilities: ...,
protocol_version: ...,
transport: ...
)
case Adapter.wait_for_server_ready(client_pid) do
:ok ->
adapter = Adapter.new(client: client_pid)
functions = Adapter.to_functions(adapter)
{:error, reason} ->
{:error, reason}
end