Apidog

Nền tảng phát triển API hợp tác tất cả trong một

Thiết kế API

Tài liệu API

Gỡ lỗi API

Giả lập API

Kiểm thử API tự động

Cách tích hợp LangChain với máy chủ MCP sử dụng langchain-mcp-adapters

中村 拓也

中村 拓也

Updated on tháng 4 14, 2025

Giao thức Ngữ cảnh Mô hình (MCP) nhằm mục đích chuẩn hóa cách các mô hình AI tương tác với các công cụ và dịch vụ bên ngoài. Nó định nghĩa một giao diện chung, cho phép các mô hình và nhà cung cấp công cụ khác nhau giao tiếp hiệu quả. Tuy nhiên, việc tích hợp những công cụ tuân thủ MCP này trực tiếp vào các khuôn khổ AI hiện có như LangChain đòi hỏi phải thích nghi.

Đây là lúc thư viện langchain-mcp-adapters trở nên cần thiết. Nó hoạt động như một cây cầu quan trọng, chuyển đổi mượt mà các công cụ MCP sang định dạng mà LangChain và khung đại lý mạnh mẽ của nó, LangGraph, có thể hiểu và sử dụng. Thư viện này cung cấp một lớp bọc nhẹ, cho phép các nhà phát triển tận dụng hệ sinh thái ngày càng phát triển của các công cụ MCP trong các ứng dụng LangChain của họ.

Các tính năng chính bao gồm:

  • Chuyển đổi Công cụ MCP: Tự động chuyển đổi các công cụ MCP thành các đối tượng BaseTool tương thích với LangChain.
  • Khách hàng Đa Máy Chủ: Cung cấp một khách hàng mạnh mẽ (MultiServerMCPClient) có khả năng kết nối với nhiều máy chủ MCP đồng thời, thu thập các công cụ từ nhiều nguồn khác nhau.
  • Độ Linh Hoạt Vận Chuyển: Hỗ trợ các phương thức vận chuyển giao tiếp MCP thông dụng như đầu vào/đầu ra chuẩn (stdio) và Sự Kiện Gửi từ Máy chủ (sse).

Tutorial này sẽ hướng dẫn bạn cách thiết lập các máy chủ MCP, kết nối với chúng bằng thư viện adapter, và tích hợp các công cụ đã tải vào một đại lý LangGraph.

💡
Muốn một công cụ Kiểm Tra API tuyệt vời mà tự động tạo ra Tài liệu API đẹp?

Muốn một nền tảng tích hợp, Tất cả trong một để Nhóm Nhà Phát Triển của bạn cùng nhau làm việc với năng suất tối đa?

Apidog đáp ứng mọi nhu cầu của bạn, và thay thế Postman với giá cả phải chăng hơn rất nhiều!
button

MCP Server là gì? Nó hoạt động như thế nào?

Hiểu một vài khái niệm cốt lõi là rất cần thiết trước khi đi vào các ví dụ:

MCP Server:

  • Một máy chủ MCP phơi bày các công cụ (chức năng) mà một mô hình AI có thể gọi.
  • Thư viện mcp (một phụ thuộc của langchain-mcp-adapters) cung cấp các công cụ như FastMCP để dễ dàng tạo ra những máy chủ này trong Python.
  • Các công cụ được định nghĩa bằng cách sử dụng bộ trang trí @mcp.tool(), tự động suy diễn lược đồ đầu vào từ các gợi ý kiểu và chuỗi tài liệu.
  • Các máy chủ cũng có thể định nghĩa các lời nhắc bằng cách sử dụng @mcp.prompt(), cung cấp các khởi đầu hoặc hướng dẫn cuộc trò chuyện có cấu trúc.
  • Các máy chủ được chạy bằng cách xác định một cơ chế vận chuyển (ví dụ: mcp.run(transport="stdio") hoặc mcp.run(transport="sse")). stdio chạy máy chủ như một quy trình con giao tiếp qua đầu vào/đầu ra chuẩn, trong khi sse thường chạy một máy chủ web đơn giản để giao tiếp.

MCP Client (langchain-mcp-adapters):

  • Vai trò của khách hàng là kết nối với một hoặc nhiều máy chủ MCP.
  • Nó xử lý các chi tiết giao thức giao tiếp (stdio, sse).
  • Nó lấy danh sách các công cụ có sẵn và các định nghĩa của chúng (tên, mô tả, lược đồ đầu vào) từ máy chủ.
  • Class MultiServerMCPClient là cách chính để quản lý các kết nối, đặc biệt khi làm việc với nhiều máy chủ công cụ.

Chuyển đổi Công cụ:

  • Các công cụ MCP có định dạng định nghĩa riêng. LangChain sử dụng cấu trúc lớp BaseTool của nó.
  • Thư viện langchain-mcp-adapters cung cấp các chức năng như load_mcp_tools (tìm thấy trong langchain_mcp_adapters.tools) dùng để kết nối với một máy chủ thông qua một ClientSession đang hoạt động, liệt kê các công cụ MCP và bọc từng công cụ vào một StructuredTool tương thích với LangChain.
  • Lớp bọc này xử lý việc gọi công cụ MCP thực tế (session.call_tool) khi đại lý LangChain quyết định sử dụng công cụ và định dạng đúng phản hồi.

Chuyển đổi Lời nhắc:

  • Giống như các công cụ, các lời nhắc MCP có thể được lấy bằng cách sử dụng load_mcp_prompt (từ langchain_mcp_adapters.prompts).
  • Chức năng này tải cấu trúc lời nhắc từ máy chủ MCP và chuyển đổi nó thành danh sách các đối tượng HumanMessage hoặc AIMessage của LangChain, phù hợp để khởi tạo hoặc dẫn dắt một cuộc trò chuyện.

Cài đặt Langchain-mcp-adapter

Đầu tiên, cài đặt các gói cần thiết:

pip install langchain-mcp-adapters langgraph langchain-openai # Hoặc tích hợp LLM LangChain yêu thích của bạn

Bạn cũng sẽ cần phải cấu hình các khóa API cho nhà cung cấp mô hình ngôn ngữ mà bạn chọn, thường bằng cách thiết lập các biến môi trường:

export OPENAI_API_KEY=<your_openai_api_key>
# hoặc export ANTHROPIC_API_KEY=<...> v.v.

Xây dựng Một Máy Chủ MCP Đơn Giản với langchain-mcp-adapters

Hãy xây dựng một ví dụ đơn giản: một máy chủ MCP cung cấp các hàm toán học và một đại lý LangGraph sử dụng những hàm đó.

Bước 1: Tạo Máy chủ MCP (math_server.py)

# math_server.py
from mcp.server.fastmcp import FastMCP

# Khởi tạo máy chủ MCP với một tên
mcp = FastMCP("Toán")

@mcp.tool()
def add(a: int, b: int) -> int:
    """Cộng hai số lại"""
    print(f"Thực hiện add({a}, {b})") # Nhật ký phía máy chủ
    return a + b

@mcp.tool()
def multiply(a: int, b: int) -> int:
    """Nhân hai số lại"""
    print(f"Thực hiện multiply({a}, {b})") # Nhật ký phía máy chủ
    return a * b

# Định nghĩa lời nhắc ví dụ
@mcp.prompt()
def configure_assistant(skills: str) -> list[dict]:
    """Cấu hình trợ lý với các kỹ năng đã chỉ định."""
    return [
        {
            "role": "assistant", # Tương ứng với AIMessage
            "content": f"Bạn là một trợ lý hữu ích. Bạn có những kỹ năng sau: {skills}. Luôn chỉ sử dụng một công cụ một lần.",
        }
    ]

if __name__ == "__main__":
    # Chạy máy chủ bằng cách sử dụng vận chuyển stdio
    print("Bắt đầu máy chủ MCP Toán qua stdio...")
    mcp.run(transport="stdio")

Lưu mã này với tên math_server.py.

Bước 2: Tạo Khách hàng và Đại lý (client_app.py)

import asyncio
import os
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client

from langchain_mcp_adapters.tools import load_mcp_tools
from langgraph.prebuilt import create_react_agent
from langchain_openai import ChatOpenAI

# --- QUAN TRỌNG: Cập nhật đường dẫn này ---
# Lấy đường dẫn tuyệt đối tới tệp math_server.py
current_dir = os.path.dirname(os.path.abspath(__file__))
math_server_script_path = os.path.join(current_dir, "math_server.py")
# ---

async def main():
    model = ChatOpenAI(model="gpt-4o") # Hoặc mô hình yêu thích của bạn

    # Cấu hình các tham số để chạy tệp math_server.py
    server_params = StdioServerParameters(
        command="python", # Lệnh để thực thi
        args=[math_server_script_path], # Các tham số (đường dẫn tệp)
        # cwd=..., env=... # Thư mục làm việc và biến môi trường (tùy chọn)
    )

    print("Kết nối đến máy chủ MCP...")
    # Thiết lập kết nối bằng cách sử dụng quản lý ngữ cảnh stdio_client
    async with stdio_client(server_params) as (read, write):
        # Tạo một ClientSession với các luồng đọc/ghi
        async with ClientSession(read, write) as session:
            print("Khởi tạo phiên...")
            # Khởi động thương thuyết với máy chủ
            await session.initialize()
            print("Phiên đã được khởi tạo.")

            print("Tải các công cụ MCP...")
            # Lấy các công cụ MCP và chuyển đổi chúng thành các công cụ LangChain
            tools = await load_mcp_tools(session)
            print(f"Các công cụ đã tải: {[tool.name for tool in tools]}")

            # Tạo một đại lý ReAct LangGraph sử dụng mô hình và các công cụ đã tải
            agent = create_react_agent(model, tools)

            print("Gọi đại lý...")
            # Chạy đại lý
            inputs = {"messages": [("human", "điều gì là (3 + 5) * 12?")]}
            async for event in agent.astream_events(inputs, version="v1"):
                 print(event) # Luồng sự kiện để dễ quan sát

            # Hoặc nhận phản hồi cuối cùng trực tiếp
            # final_response = await agent.ainvoke(inputs)
            # print("Phản hồi của đại lý:", final_response['messages'][-1].content)

if __name__ == "__main__":
    asyncio.run(main())

Lưu mã này với tên client_app.py trong cùng thư mục với math_server.py.

Để Chạy:

Thực thi tệp khách hàng:

python client_app.py

Tệp khách hàng sẽ tự động khởi động math_server.py dưới dạng một quy trình con, kết nối với nó, tải các công cụ addmultiply, và sử dụng đại lý LangGraph để giải quyết bài toán toán học bằng cách gọi những công cụ đó qua máy chủ MCP. Bạn sẽ thấy nhật ký từ cả khách hàng lẫn máy chủ.

Kết Nối với Nhiều Máy Chủ MCP

Thường thì bạn sẽ muốn kết hợp các công cụ từ các máy chủ chuyên biệt khác nhau. MultiServerMCPClient làm điều này trở nên đơn giản.

Bước 1: Tạo Một Máy Chủ Khác (weather_server.py)

Hãy tạo một máy chủ thời tiết chạy bằng vận chuyển SSE.

# weather_server.py
from mcp.server.fastmcp import FastMCP
import uvicorn # Cần: pip install uvicorn

mcp = FastMCP("Thời tiết")

@mcp.tool()
async def get_weather(location: str) -> str:
    """Lấy thời tiết cho địa điểm."""
    print(f"Thực hiện get_weather({location})")
    # Trong một kịch bản thực tế, điều này sẽ gọi một API thời tiết
    return f"Trời luôn nắng ở {location}"

if __name__ == "__main__":
    # Chạy máy chủ bằng vận chuyển SSE (yêu cầu một máy chủ ASGI như uvicorn)
    # Thư viện mcp tự động tạo một ứng dụng FastAPI cho SSE.
    # Theo mặc định, nó chạy trên cổng 8000 tại điểm cuối /sse.
    print("Bắt đầu máy chủ MCP Thời tiết qua SSE trên cổng 8000...")
    # uvicorn.run(mcp.app, host="0.0.0.0", port=8000) # Bạn có thể chạy bằng tay
    mcp.run(transport="sse", host="0.0.0.0", port=8000) # Hoặc sử dụng tiện ích mcp.run

Lưu mã này với tên weather_server.py.

Bước 2: Cập nhật Khách hàng để Sử dụng MultiServerMCPClient (multi_client_app.py)

import asyncio
import os
from langchain_mcp_adapters.client import MultiServerMCPClient
from langgraph.prebuilt import create_react_agent
from langchain_openai import ChatOpenAI

# --- QUAN TRỌNG: Cập nhật đường dẫn ---
current_dir = os.path.dirname(os.path.abspath(__file__))
math_server_script_path = os.path.join(current_dir, "math_server.py")
# Máy chủ thời tiết chạy riêng, kết nối qua URL
# ---

async def main():
    model = ChatOpenAI(model="gpt-4o")

    # Định nghĩa kết nối cho nhiều máy chủ
    server_connections = {
        "math_service": { # Tên duy nhất cho kết nối này
            "transport": "stdio",
            "command": "python",
            "args": [math_server_script_path],
            # Thêm các tham số kết nối Stdio khác nếu cần (env, cwd, v.v.)
        },
        "weather_service": { # Tên duy nhất cho kết nối này
            "transport": "sse",
            "url": "http://localhost:8000/sse", # URL nơi máy chủ thời tiết đang chạy
            # Thêm các tham số kết nối SSE khác nếu cần (headers, timeout, v.v.)
        }
    }

    print("Kết nối với nhiều máy chủ MCP...")
    # Sử dụng quản lý ngữ cảnh MultiServerMCPClient
    async with MultiServerMCPClient(server_connections) as client:
        print("Kết nối đã được thiết lập.")

        # Lấy *tất cả* các công cụ từ *tất cả* các máy chủ đã kết nối
        all_tools = client.get_tools()
        print(f"Các công cụ đã tải: {[tool.name for tool in all_tools]}")

        # Tạo đại lý với danh sách công cụ kết hợp
        agent = create_react_agent(model, all_tools)

        # --- Tương tác với đại lý ---
        print("\nGọi đại lý cho truy vấn toán học...")
        math_inputs = {"messages": [("human", "điều gì là (3 + 5) * 12?")]}
        math_response = await agent.ainvoke(math_inputs)
        print("Phản hồi Toán học:", math_response['messages'][-1].content)

        print("\nGọi đại lý cho truy vấn thời tiết...")
        weather_inputs = {"messages": [("human", "thời tiết ở nyc là gì?")]}
        weather_response = await agent.ainvoke(weather_inputs)
        print("Phản hồi Thời tiết:", weather_response['messages'][-1].content)

        # --- Ví dụ: Lấy một lời nhắc ---
        # print("\nLấy lời nhắc máy chủ toán học...")
        # prompt_messages = await client.get_prompt(
        #     server_name="math_service", # Sử dụng tên đã xác định trong kết nối
        #     prompt_name="configure_assistant",
        #     arguments={"skills": "các phép toán cơ bản"}
        # )
        # print("Lời nhắc:", prompt_messages)


if __name__ == "__main__":
    # Khởi động máy chủ thời tiết trước trong một terminal riêng:
    # python weather_server.py
    # Sau đó chạy tệp khách hàng này:
    asyncio.run(main())

Lưu mã này với tên multi_client_app.py.

Để Chạy:

  1. Bắt đầu máy chủ thời tiết trong một terminal: python weather_server.py
  2. Chạy ứng dụng khách đa máy chủ trong một terminal khác: python multi_client_app.py

MultiServerMCPClient sẽ khởi động quy trình con math_server.py (stdio) và kết nối với weather_server.py đang chạy (sse). Nó tổng hợp các công cụ (add, multiply, get_weather) mà sau đó có sẵn cho đại lý LangGraph.

Tích Hợp với Máy chủ API LangGraph

Bạn có thể triển khai một đại lý LangGraph sử dụng các công cụ MCP như một dịch vụ API liên tục bằng cách sử dụng langgraph deploy. Chìa khóa là quản lý vòng đời MultiServerMCPClient một cách chính xác trong ngữ cảnh ứng dụng LangGraph.

Tạo một tệp graph.py:

# graph.py
from contextlib import asynccontextmanager
import os
from langchain_mcp_adapters.client import MultiServerMCPClient
from langgraph.prebuilt import create_react_agent
from langchain_openai import ChatOpenAI # Hoặc Anthropic, v.v.

# --- QUAN TRỌNG: Cập nhật đường dẫn ---
# Giả sử các máy chủ tương đối với nơi máy chủ LangGraph chạy
math_server_script_path = os.path.abspath("math_server.py")
# ---

# Định nghĩa kết nối (đảm bảo các đường dẫn/URL chính xác cho môi trường máy chủ)
server_connections = {
    "math_service": {
        "transport": "stdio",
        "command": "python",
        "args": [math_server_script_path],
    },
    "weather_service": {
        "transport": "sse",
        "url": "http://localhost:8000/sse", # Máy chủ thời tiết phải chạy riêng
    }
}

model = ChatOpenAI(model="gpt-4o")

# Sử dụng một quản lý ngữ cảnh bất đồng bộ để xử lý thiết lập/giải phóng khách hàng
@asynccontextmanager
async def lifespan(_app): # LangGraph mong đợi cấu trúc này để quản lý vòng đời
    async with MultiServerMCPClient(server_connections) as client:
        print("Khách hàng MCP đã được khởi tạo trong vòng đời.")
        # Tạo đại lý *trong* ngữ cảnh mà khách hàng hoạt động
        agent = create_react_agent(model, client.get_tools())
        yield {"agent": agent} # Làm cho đại lý khả dụng

# Không cần định nghĩa chính cho đồ thị riêng nếu vòng đời dẫn nó

Cấu hình của bạn langgraph.json (hoặc pyproject.toml dưới [tool.langgraph]) để sử dụng định nghĩa đồ thị này với quản lý vòng đời:

// langgraph.json (ví dụ)
{
  "dependencies": ["."], // Hoặc chỉ định các gói cần thiết
  "graphs": {
    "my_mcp_agent": {
      "entrypoint": "graph:agent", // Tham chiếu đến khóa được cung cấp bởi vòng đời
      "lifespan": "graph:lifespan"
    }
  }
}

Bây giờ, khi bạn chạy langgraph up, hàm lifespan sẽ được thực thi, khởi động MultiServerMCPClient (và máy chủ toán stdio). Đại lý được tạo trong ngữ cảnh này sẽ được phục vụ bởi LangGraph. Hãy nhớ rằng máy chủ thời tiết SSE vẫn cần được chạy riêng.

Vận Chuyển Máy Chủ (stdio so với SSE)

stdio:

  • Giao tiếp: Thông qua các luồng đầu vào và đầu ra chuẩn của quy trình máy chủ.
  • Ưu điểm: Thiết lập đơn giản cho phát triển cục bộ; khách hàng quản lý vòng đời của máy chủ. Không liên quan đến mạng.
  • Nhược điểm: Liên kết chặt chẽ; ít phù hợp hơn cho các hệ thống phân tán hoặc máy chủ không phải Python. Cần cấu hình commandargs.

sse (Sự Kiện Gửi từ Máy chủ):

  • Giao tiếp: Qua HTTP sử dụng giao thức SSE. Máy chủ chạy như một dịch vụ web (thường sử dụng FastAPI/Uvicorn một cách ngầm định).
  • Ưu điểm: Giao thức web chuẩn; phù hợp cho các máy chủ mạng/ từ xa, có thể được triển khai bằng các ngôn ngữ khác nhau. Máy chủ chạy độc lập.
  • Nhược điểm: Cần máy chủ phải đang chạy riêng. Cần cấu hình url.

Chọn phương thức vận chuyển dựa trên nhu cầu triển khai của bạn.

Cấu Hình Khách Hàng Nâng Cao cho Thiết Lập langchain-mcp-adapters

Các từ điển StdioConnectionSSEConnection bên trong MultiServerMCPClient chấp nhận thêm các tham số tùy chọn bổ sung cho kiểm soát tốt hơn:

  • Stdio: env (biến môi trường tùy chỉnh cho quy trình con), cwd (thư mục làm việc), encoding, encoding_error_handler, session_kwargs (được chuyển tới mcp.ClientSession).
  • SSE: headers (tiêu đề HTTP tùy chỉnh), timeout (thời gian chờ kết nối HTTP), sse_read_timeout, session_kwargs.

Xem định nghĩa MultiServerMCPClient trong langchain_mcp_adapters/client.py để biết thêm chi tiết.

Kết Luận (100 từ)

Thư viện langchain-mcp-adapters hiệu quả đóng vai trò cầu nối giữa Giao thức Ngữ cảnh Mô hình tiêu chuẩn và hệ sinh thái linh hoạt LangChain. Bằng cách cung cấp MultiServerMCPClient và chuyển đổi công cụ tự động, nó cho phép các nhà phát triển dễ dàng kết hợp các công cụ tuân thủ MCP đa dạng vào các đại lý LangChain và các ứng dụng LangGraph của họ.

Quy trình làm việc cốt lõi bao gồm:

  1. Định nghĩa các công cụ (và tùy chọn các lời nhắc) trong một máy chủ MCP bằng cách sử dụng @mcp.tool().
  2. Cấu hình MultiServerMCPClient với các chi tiết kết nối (stdio hoặc sse) cho từng máy chủ.
  3. Sử dụng quản lý ngữ cảnh khách hàng (async with ...) để kết nối và lấy các công cụ thông qua client.get_tools().
  4. Chuyển các công cụ tương thích với LangChain được lấy vào đại lý của bạn (create_react_agent hoặc các đại lý tùy chỉnh).

Điều này cho phép xây dựng các ứng dụng AI mạnh mẽ, mô-đun mà tận dụng các công cụ bên ngoài chuyên biệt thông qua một giao thức tiêu chuẩn hóa. Khám phá các ví dụ và bài kiểm tra trong kho lưu trữ để có thêm thông tin.