Skip to main content

Convert LangChain tools to FastMCP tools

Project description

lc2mcp

PyPI version Python versions License: MIT

Convert LangChain tools to FastMCP tools โ€” in one line of code.

Stop rewriting your tools. Just adapt them.

lc2mcp is a lightweight adapter that converts existing LangChain tools into FastMCP tools, enabling you to quickly build MCP servers accessible to Claude, Cursor, and any MCP-compatible client.


โœจ Features

Feature Description
๐Ÿ”„ Instant Conversion One function call to convert any LangChain tool to FastMCP tool
๐Ÿ“ฆ Ecosystem Access Unlock 1000+ LangChain community tools (Search, Wikipedia, SQL, APIs...)
๐ŸŽฏ Zero Boilerplate Automatic Pydantic โ†’ JSON Schema conversion
๐Ÿ” Context Injection Pass auth, user info, and request context to tools
๐Ÿ“Š Progress & Logging Full support for MCP progress notifications and logging
๐Ÿท๏ธ Namespace Support Prefix tool names and handle conflicts automatically

๐Ÿš€ Quick Start

Installation

pip install lc2mcp

3 Lines to MCP

from langchain_core.tools import tool
from fastmcp import FastMCP
from lc2mcp import register_tools

@tool
def get_weather(city: str) -> str:
    """Get current weather for a city."""
    return f"Sunny, 25ยฐC in {city}"

mcp = FastMCP("weather-server")
register_tools(mcp, [get_weather])  # โ† That's it!

if __name__ == "__main__":
    mcp.run()

Your tool is now available to Claude, Cursor, and any MCP client.


๐Ÿ”Œ How It Works

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”      โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”      โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  LangChain Tool โ”‚ โ”€โ”€โ”€โ–ถ โ”‚   lc2mcp    โ”‚ โ”€โ”€โ”€โ–ถ โ”‚  FastMCP Tool   โ”‚
โ”‚  (@tool, etc.)  โ”‚      โ”‚  (adapter)  โ”‚      โ”‚                 โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜      โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜      โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                                                       โ”‚
                                                       โ–ผ
                                              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                                              โ”‚  FastMCP Server โ”‚
                                              โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                                                       โ”‚
                                                       โ–ผ
                                          โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                                          โ”‚      MCP Clients      โ”‚
                                          โ”‚ (Claude, Cursor, ...) โ”‚
                                          โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

๐Ÿ“š Examples

Using Community Tools

Instantly expose DuckDuckGo search and Wikipedia to MCP clients:

pip install lc2mcp langchain-community duckduckgo-search wikipedia
from fastmcp import FastMCP
from langchain_community.tools import DuckDuckGoSearchRun, WikipediaQueryRun
from langchain_community.utilities import WikipediaAPIWrapper
from lc2mcp import register_tools

mcp = FastMCP("knowledge-server")

register_tools(mcp, [
    DuckDuckGoSearchRun(),
    WikipediaQueryRun(api_wrapper=WikipediaAPIWrapper()),
])

if __name__ == "__main__":
    mcp.run()

With Authentication Context

Inject user authentication and app context into your tools:

from dataclasses import dataclass
from fastmcp import Context, FastMCP
from langchain_core.tools import tool
from langgraph.prebuilt import ToolRuntime
from lc2mcp import register_tools

@dataclass(frozen=True)
class UserContext:
    user_id: str
    tenant_id: str

@tool
def whoami(runtime: ToolRuntime[UserContext]) -> str:
    """Return the current user."""
    return f"Hello, user {runtime.context.user_id} from {runtime.context.tenant_id}"

def runtime_adapter(mcp_ctx: Context) -> ToolRuntime[UserContext]:
    return ToolRuntime(
        context=UserContext(
            user_id=mcp_ctx.get_state("user_id") or "anonymous",
            tenant_id=mcp_ctx.get_state("tenant_id") or "default",
        ),
        state={}, config={}, stream_writer=lambda x: None,
        tool_call_id=None, store=None,
    )

mcp = FastMCP("auth-server")
register_tools(mcp, [whoami], runtime_adapter=runtime_adapter)

if __name__ == "__main__":
    mcp.run()

With Progress Reporting & Logging

Use MCP context for real-time progress updates and logging:

from fastmcp import Context, FastMCP
from langchain_core.tools import tool
from lc2mcp import register_tools

@tool
async def process_data(data: str, mcp_ctx: Context) -> str:
    """Process data with progress reporting."""
    await mcp_ctx.info(f"Starting: {data}")
    await mcp_ctx.report_progress(0, 100, "Starting")
    
    # ... processing steps ...
    await mcp_ctx.report_progress(50, 100, "Processing")
    
    await mcp_ctx.info("Complete!")
    await mcp_ctx.report_progress(100, 100, "Done")
    return f"Processed: {data}"

mcp = FastMCP("processor")
register_tools(mcp, [process_data], inject_mcp_ctx=True)

if __name__ == "__main__":
    mcp.run()

Namespace & Conflict Handling

Organize tools with prefixes and handle name collisions:

from fastmcp import FastMCP
from lc2mcp import register_tools

mcp = FastMCP("multi-domain")

# Prefix all finance tools
register_tools(mcp, finance_tools, name_prefix="finance.")

# Auto-suffix on collision: tool โ†’ tool_2 โ†’ tool_3
register_tools(mcp, ops_tools, name_prefix="ops.", on_name_conflict="suffix")

if __name__ == "__main__":
    mcp.run()

๐Ÿ“– API Reference

register_tools()

Convert and register LangChain tools as FastMCP tools on a server.

register_tools(
    mcp: FastMCP,
    tools: list[BaseTool | Callable],
    *,
    name_prefix: str | None = None,           # e.g. "finance." โ†’ "finance.get_stock"
    on_name_conflict: str = "error",          # "error" | "overwrite" | "suffix"
    inject_mcp_ctx: bool = False,             # inject mcp_ctx: Context
    runtime_adapter: Callable | None = None,  # Context โ†’ ToolRuntime[...]
)

to_mcp_tool()

Convert a single LangChain tool to FastMCP tool for manual registration.

to_mcp_tool(
    tool: BaseTool | Callable,
    *,
    name: str | None = None,
    description: str | None = None,
    args_schema: Type[BaseModel] | None = None,
    inject_mcp_ctx: bool = False,
    runtime_adapter: Callable | None = None,
) -> Callable

๐Ÿ”ง Compatibility

Component Supported Versions
Python 3.10, 3.11, 3.12+
LangChain >= 1.0.0
FastMCP >= 2.0.0

Tool Support

Tool Type Status
@tool decorated functions โœ… Full support
StructuredTool โœ… Full support
BaseTool subclasses โœ… Supported (requires args_schema)

๐Ÿค Contributing

Contributions are welcome! Please feel free to submit a Pull Request.


๐Ÿ“„ License

MIT License - see LICENSE for details.


Made with โค๏ธ for the LangChain and MCP communities

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

lc2mcp-0.1.1.tar.gz (24.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

lc2mcp-0.1.1-py3-none-any.whl (14.3 kB view details)

Uploaded Python 3

File details

Details for the file lc2mcp-0.1.1.tar.gz.

File metadata

  • Download URL: lc2mcp-0.1.1.tar.gz
  • Upload date:
  • Size: 24.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.1

File hashes

Hashes for lc2mcp-0.1.1.tar.gz
Algorithm Hash digest
SHA256 1f4bea1d6180de65b6c2d818ac3d0b7e5b5fb5f5c713f3cd8820ca4f4c926db9
MD5 86104bdf3620d96031fbd381f55983a0
BLAKE2b-256 9a7ae628e9ff47b5202775a9d8f4cfad376ee3cd61edb0aa3bac4fd7f855074a

See more details on using hashes here.

File details

Details for the file lc2mcp-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: lc2mcp-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 14.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.1

File hashes

Hashes for lc2mcp-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 8a2d7a5404a09ab37b3fa603a58408d5b0de0b56e5a598adf33690f5bb4f9399
MD5 a5e5f85cbb8ec7ee2b6453123f02345a
BLAKE2b-256 9b8a7740d9b06647523ab0b8abd7922709f9889394a7a43bd288296187e4dc27

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page