Skip to main content

Seamless integration between FastMCP and LangChain - convert MCP tools to LangChain StructuredTools

Project description

FastMCP LangChain Adaptor

Python 3.11+ License: MIT Code style: black

A Python package that provides seamless integration between FastMCP (Model Context Protocol) and LangChain, allowing you to use MCP tools as LangChain StructuredTools.

Features

  • 🔄 Seamless Integration: Convert FastMCP tools to LangChain StructuredTools with a single function call
  • 🔄 Async Support: Full async/await support for modern Python applications
  • 📊 Progress Callbacks: Forward MCP progress events to LangChain callbacks
  • 🛡️ Error Handling: Comprehensive error handling with detailed logging
  • 🔍 Type Safety: Full type hints and Pydantic model validation
  • 📝 Extensive Logging: Debug-friendly logging for troubleshooting

Installation

pip install fastmcp-langchain-adaptor

Or using uv (recommended):

uv add fastmcp-langchain-adaptor

Development Installation

git clone https://github.com/username/fastmcp-langchain-adaptor.git
cd fastmcp-langchain-adaptor
uv sync --dev
uv run pre-commit install

Quick Start

import asyncio
from fastmcp import Client
from fastmcp_langchain_adaptor import mcp_to_langchain
from langchain.agents import create_openai_functions_agent
from langchain_openai import ChatOpenAI

async def main():
    # Create FastMCP client
    client = Client("http://localhost:8000")

    # Get MCP tools and convert to LangChain tools
    mcp_tools = await client.list_tools()
    lc_tools = mcp_to_langchain(mcp_tools, client=client)

    # Use with LangChain
    llm = ChatOpenAI(temperature=0)
    agent = create_openai_functions_agent(llm, lc_tools, prompt)

    # Execute with agent
    result = await agent.ainvoke({"input": "Use the MCP tool to help me"})
    print(result)

asyncio.run(main())

Advanced Usage

Custom Progress Formatting

def custom_progress_formatter(event: dict) -> str:
    progress = event.get("progress", 0)
    total = event.get("total", 100)
    message = event.get("message", "")
    return f"Progress: {progress}/{total} - {message}"

lc_tools = mcp_to_langchain(
    mcp_tools,
    client=client,
    progress_formatter=custom_progress_formatter
)

Elicitation (User Input During Tool Execution)

FastMCP supports elicitation, which allows tools to request additional information from users during execution. This is particularly useful for tools that need to make decisions based on user preferences or require confirmation for sensitive operations.

from fastmcp import Client
from fastmcp.client.elicitation import ElicitResult

# Set up elicitation handler
async def elicitation_handler(
    message: str,
    response_type: type,
    params,
    context
):
    """Handle elicitation requests from MCP tools."""
    print(f"Tool is asking: {message}")

    # Example: call_friend tool asking which phone to use
    if "phone" in message.lower():
        # In a real app, you'd show a UI dialog or prompt
        user_choice = input("Which phone? (mobile/home/work): ")
        return {"phone_type": user_choice}

    # Example: delete_files tool asking for confirmation
    elif "delete" in message.lower():
        confirm = input("Are you sure? (yes/no): ")
        if confirm.lower() == 'yes':
            return ElicitResult(action="accept", content={})
        else:
            return ElicitResult(action="reject", content={})

    # Default response
    return ElicitResult(action="accept", content={})

# Create client with elicitation handler
client = Client("http://localhost:8000", elicitation_handler=elicitation_handler)

# Convert tools - elicitation will work transparently
lc_tools = mcp_to_langchain(mcp_tools, client=client)

# When you invoke tools, they may trigger elicitation
result = await lc_tools[0].ainvoke({"friend_name": "Alice"})
# This might pause and ask: "Which phone should I use to call Alice?"
# User responds, tool continues execution
print(result)  # "Successfully called Alice on mobile phone"

Common Elicitation Scenarios:

  • Phone calls: Asking which number to use (mobile/home/work)
  • File operations: Confirming dangerous operations (delete, overwrite)
  • Configuration: Requesting user preferences (theme, settings)
  • Data input: Collecting structured information (forms, profiles)
  • Multi-step workflows: Making decisions at each step

### Error Handling

```python
import logging

# Enable debug logging
logging.getLogger('fastmcp_langchain_adaptor').setLevel(logging.DEBUG)

try:
    lc_tools = mcp_to_langchain(mcp_tools, client=client)
except Exception as e:
    logger.error(f"Failed to convert MCP tools: {e}")

API Reference

mcp_to_langchain

Convert a list of FastMCP tool descriptors into LangChain StructuredTools.

Parameters:

  • tools (List[McpTool]): The descriptors returned by await client.list_tools()
  • client (Client): The FastMCP client you created
  • progress_formatter (Optional[Callable]): Optional function to format progress events

Returns:

  • List[StructuredTool]: List of LangChain StructuredTools

Requirements

  • Python 3.11+
  • fastmcp >= 2.12.4
  • langchain >= 0.3.27

Contributing

We welcome contributions! Please see our Contributing Guide for details.

Development Setup

  1. Fork the repository
  2. Clone your fork
  3. Install development dependencies:
    uv sync --dev
    uv run pre-commit install
    
  4. Run tests:
    uv run pytest
    
  5. Run linting and formatting:
    uv run black . && uv run ruff check . --fix
    

Security

This package follows security best practices:

  • Input validation using Pydantic models
  • Comprehensive error handling without exposing sensitive information
  • No hardcoded secrets or credentials
  • Secure defaults for all configurations

If you discover a security vulnerability, please email security@example.com instead of opening a public issue.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Changelog

See CHANGELOG.md for version history.

Support

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

fastmcp_langchain_adaptor-0.1.2.tar.gz (156.2 kB view details)

Uploaded Source

Built Distribution

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

fastmcp_langchain_adaptor-0.1.2-py3-none-any.whl (8.7 kB view details)

Uploaded Python 3

File details

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

File metadata

File hashes

Hashes for fastmcp_langchain_adaptor-0.1.2.tar.gz
Algorithm Hash digest
SHA256 490b3d47d4a6d80d6ad1bf4f3d9283123dadc97e9a158ba0a7b1b77395926a7d
MD5 fdf8366e80ef318cf3d2adf91b870fb9
BLAKE2b-256 5f5d288a3bad18cc7aec3b975d675f9b83474580eddae211e211c7faf25d4865

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for fastmcp_langchain_adaptor-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 af24cc56c767c34c1deca204c8aa53da7df3afb952a163b08ff802773d155f5b
MD5 562b12fb6be5b0556a37f9c2d151ae17
BLAKE2b-256 158eb112478943cdb0f7a4f7bb116be8d9ec0e37b8d2a17230c0b074315d3ce8

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