Skip to content

Langchain Adapter

This module implements the LangChain adapter.

LangChain tools support both sync and async functions for their tools so we can leverage both in our implementation.

Example Usage:

with MCPAdapt(StdioServerParameters(command="uv", args=["run", "src/echo.py"]), LangChainAdapter()) as tools: print(tools)

LangChainAdapter

Bases: ToolAdapter

Adapter for langchain.

Note that langchain support both sync and async tools so we write adapt for both methods.

Warning: if the mcp tool name is a python keyword, starts with digits or contains dashes, the tool name will be sanitized to become a valid python function name.

Source code in src/mcpadapt/langchain_adapter.py
class LangChainAdapter(ToolAdapter):
    """Adapter for `langchain`.

    Note that `langchain` support both sync and async tools so we
    write adapt for both methods.

    Warning: if the mcp tool name is a python keyword, starts with digits or contains
    dashes, the tool name will be sanitized to become a valid python function name.

    """

    def adapt(
        self,
        func: Callable[[dict | None], mcp.types.CallToolResult],
        mcp_tool: mcp.types.Tool,
    ) -> BaseTool:
        """Adapt a MCP tool to a LangChain tool.

        Args:
            func: The function to adapt.
            mcp_tool: The MCP tool to adapt.

        Returns:
            A LangChain tool.
        """
        mcp_tool_name = _sanitize_function_name(mcp_tool.name)

        generate_class_template = partial(
            _generate_tool_class,
            mcp_tool_name,
            mcp_tool.description,
            mcp_tool.inputSchema,
            False,
        )
        return _instanciate_tool(mcp_tool_name, generate_class_template, func)

    def async_adapt(
        self,
        afunc: Callable[[dict | None], Coroutine[Any, Any, mcp.types.CallToolResult]],
        mcp_tool: mcp.types.Tool,
    ) -> BaseTool:
        """Adapt a MCP tool to a LangChain tool.

        Args:
            afunc: The function to adapt.
            mcp_tool: The MCP tool to adapt.

        Returns:
            A LangChain tool.
        """
        mcp_tool_name = _sanitize_function_name(mcp_tool.name)
        if mcp_tool_name != mcp_tool.name:
            log.warning(f"MCP tool name {mcp_tool.name} sanitized to {mcp_tool_name}")

        generate_class_template = partial(
            _generate_tool_class,
            mcp_tool_name,
            mcp_tool.description,
            mcp_tool.inputSchema,
            True,
        )
        return _instanciate_tool(mcp_tool_name, generate_class_template, afunc)

adapt

adapt(
    func: Callable[[dict | None], CallToolResult],
    mcp_tool: Tool,
) -> BaseTool

Adapt a MCP tool to a LangChain tool.

Parameters:

Name Type Description Default
func Callable[[dict | None], CallToolResult]

The function to adapt.

required
mcp_tool Tool

The MCP tool to adapt.

required

Returns:

Type Description
BaseTool

A LangChain tool.

Source code in src/mcpadapt/langchain_adapter.py
def adapt(
    self,
    func: Callable[[dict | None], mcp.types.CallToolResult],
    mcp_tool: mcp.types.Tool,
) -> BaseTool:
    """Adapt a MCP tool to a LangChain tool.

    Args:
        func: The function to adapt.
        mcp_tool: The MCP tool to adapt.

    Returns:
        A LangChain tool.
    """
    mcp_tool_name = _sanitize_function_name(mcp_tool.name)

    generate_class_template = partial(
        _generate_tool_class,
        mcp_tool_name,
        mcp_tool.description,
        mcp_tool.inputSchema,
        False,
    )
    return _instanciate_tool(mcp_tool_name, generate_class_template, func)

async_adapt

async_adapt(
    afunc: Callable[
        [dict | None], Coroutine[Any, Any, CallToolResult]
    ],
    mcp_tool: Tool,
) -> BaseTool

Adapt a MCP tool to a LangChain tool.

Parameters:

Name Type Description Default
afunc Callable[[dict | None], Coroutine[Any, Any, CallToolResult]]

The function to adapt.

required
mcp_tool Tool

The MCP tool to adapt.

required

Returns:

Type Description
BaseTool

A LangChain tool.

Source code in src/mcpadapt/langchain_adapter.py
def async_adapt(
    self,
    afunc: Callable[[dict | None], Coroutine[Any, Any, mcp.types.CallToolResult]],
    mcp_tool: mcp.types.Tool,
) -> BaseTool:
    """Adapt a MCP tool to a LangChain tool.

    Args:
        afunc: The function to adapt.
        mcp_tool: The MCP tool to adapt.

    Returns:
        A LangChain tool.
    """
    mcp_tool_name = _sanitize_function_name(mcp_tool.name)
    if mcp_tool_name != mcp_tool.name:
        log.warning(f"MCP tool name {mcp_tool.name} sanitized to {mcp_tool_name}")

    generate_class_template = partial(
        _generate_tool_class,
        mcp_tool_name,
        mcp_tool.description,
        mcp_tool.inputSchema,
        True,
    )
    return _instanciate_tool(mcp_tool_name, generate_class_template, afunc)