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.2.tar.gz (24.1 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.2-py3-none-any.whl (14.4 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for lc2mcp-0.1.2.tar.gz
Algorithm Hash digest
SHA256 1b98c62a60f6ebe1542a9a7ea856f52819816aa9d3046b6ff6a90a75de2cff70
MD5 c6b30be64f23f6389bdaba37032ccfd9
BLAKE2b-256 c1d5933acb0ecd268e7cae55ebcb77c59f3f8d2bb25a1a457731da144331b616

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for lc2mcp-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 e551e1867b41e6e38b2229f079ae0988bbc0636f146b5271732468449a86d1bf
MD5 af8b7f350aa11002c2925b535c5b67f0
BLAKE2b-256 664039bb63ddf13eed953d693f67015120fd94956ee8114b8e7db476aabfd223

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