MCP实践

文章目录

    • [创建 mcp server](#创建 mcp server)
    • [创建 mcp配置文件](#创建 mcp配置文件)
    • [Langchain 客户端](#Langchain 客户端)

LangChain调用MCP是可以将MCP的工具直接转换为LangChain的工具,然后通过预定义的MCP_Client实现与外部MCP的读写操作,换而言之就是我们需要改写原先的client,将原先的Function calling调用逻辑修改为LangChain调用逻辑

创建 mcp server

python 复制代码
import json
import os
import httpx
import dotenv
from mcp.server.fastmcp import FastMCP
from loguru import logger

dotenv.load_dotenv()

# 创建FastMCP实例,用于启动天气服务器SSE服务
mcp = FastMCP("WeatherServerSSE", host="0.0.0.0", port=8000)



@mcp.tool()
def get_weather(city: str) -> str:
    """
    查询指定城市的即时天气信息。
    参数 city: 城市英文名,如 Beijing
    返回: OpenWeather API 的 JSON 字符串
    """
    url = "https://api.openweathermap.org/data/2.5/weather"
    params = {
        "q": city,
        "appid": os.getenv("OPENWEATHER_API_KEY"),
        "units": "metric",
        "lang": "zh_cn"
    }
    resp = httpx.get(url, params=params, timeout=10)
    data = resp.json()
    logger.info(f"查询 {city} 天气结果:{data}")
    return json.dumps(data, ensure_ascii=False)


if __name__ == "__main__":
    logger.info("启动 MCP SSE 天气服务器,监听 http://0.0.0.0:8000/sse")
    # 运行MCP客户端,使用Server-Sent Events(SSE)作为传输协议
    mcp.run(transport="sse")

运行 server

python 复制代码
# uv run server.py
2026-01-02 10:26:26.789 | INFO     | __main__:<module>:36 - 启动 MCP SSE 天气服务器,监听 http://0.0.0.0:8000/sse

创建 mcp配置文件

mcp.json 文件内容如下:

python 复制代码
{
  "mcpServers": {
    "weather": {
      "url": "http://127.0.0.1:8000/sse",
      "transport": "sse"
    },
    "fetch": {
      "command": "uvx",
      "args": [
        "mcp-server-fetch"
      ],
      "transport": "stdio"
    }
  }
}

Langchain 客户端

python 复制代码
import asyncio
import json
from typing import Any, Dict
from dotenv import load_dotenv
from langchain import hub
from langchain.agents import AgentExecutor, create_openai_tools_agent
from langchain_mcp_adapters.client import MultiServerMCPClient
from langchain_ollama import ChatOllama
from loguru import logger

# 加载 .env 文件中的环境变量,override=True 表示覆盖已存在的变量
load_dotenv(override=True)

def load_servers(file_path: str = "mcp.json") -> Dict[str, Any]:
    """
    从指定的 JSON 文件中加载 MCP 服务器配置。

    参数:
        file_path (str): 配置文件路径,默认为 "mcp.json"

    返回:
        Dict[str, Any]: 包含 MCP 服务器配置的字典,若文件中没有 "mcpServers" 键则返回空字典
    """
    with open(file_path, "r", encoding="utf-8") as file:
        data = json.load(file)
        return data.get("mcpServers", {})

async def run_chat_loop() -> None:
    """
    启动并运行一个基于 MCP 工具的聊天代理循环。
    
    该函数会:
    1. 加载 MCP 服务器配置;
    2. 初始化 MCP 客户端并获取工具;
    3. 创建基于 Ollama 的语言模型和代理;
    4. 启动命令行聊天循环;
    5. 在退出时清理资源。
    
    返回:
        None
    """
    # 1️⃣ 加载服务器配置
    servers_cfg = load_servers()
    
    # 2️⃣ 初始化 MCP 客户端并获取工具
    mcp_client = MultiServerMCPClient(servers_cfg)
    tools = await mcp_client.get_tools()
    logger.info(f"✅ 已加载 {len(tools)} 个 MCP 工具: {[t.name for t in tools]}")
    
    # 3️⃣ 初始化语言模型、提示模板和代理执行器
    llm = ChatOllama(model="qwen3:8b", reasoning=False)
    prompt = hub.pull("hwchase17/openai-tools-agent")
    agent = create_openai_tools_agent(llm, tools, prompt)
    agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)

    # 4️⃣ CLI 聊天
    logger.info("\n🤖 MCP Agent 已启动,输入 'quit' 退出")
    while True:
        user_input = input("\n你: ").strip()
        if user_input.lower() == "quit":
            break
        try:
            result = await agent_executor.ainvoke({"input": user_input})
            print(f"\nAI: {result['output']}")
        except Exception as exc:
            logger.error(f"\n⚠️  出错: {exc}")

    # 5️⃣ 清理
    logger.info("🧹 会话已结束,Bye!")

if __name__ == "__main__":
    # 启动异步事件循环并运行聊天代理
    asyncio.run(run_chat_loop())

访问验证

python 复制代码
2026-01-02 10:42:03.213 | INFO     | __main__:run_chat_loop:21 - ✅ 已加载 2 个 MCP 工具: ['get_weather', 'fetch']

你: 2026-01-02 10:42:04.410 | INFO     | __main__:run_chat_loop:28 - 
🤖 MCP Agent 已启动,输入 'quit' 退出
上海天气怎么样

> Entering new AgentExecutor chain...

Invoking: `get_weather` with `{'city': 'Shanghai'}`

{"coord": {"lon": 121.4581, "lat": 31.2222}, "weather": [{"id": 800, "main": "Clear", "description": "晴", "icon": "01d"}], "base": "stations", "main": {"temp": 35.36, "feels_like": 39.24, "temp_min": 35.36, "temp_max": 35.36, "pressure": 1007, "humidity": 44, "sea_level": 1007, "grnd_level": 1006}, "visibility": 10000, "wind": {"speed": 2.82, "deg": 125, "gust": 1.69}, "clouds": {"all": 1}, "dt": 1755657672, "sys": {"country": "CN", "sunrise": 1755638574, "sunset": 1755685962}, "timezone": 28800, "id": 1796236, "name": "Shanghai", "cod": 200}上海的天气晴朗,当前温度为35.36°C,体感温度为39.24°C。湿度为44%,风速为2.82 m/s,风向为125度。天气条件良好,适合外出活动。

> Finished chain.

AI: 上海的天气晴朗,当前温度为3°C,体感温度为39.24°C。湿度为44%,风速为2.82 m/s,风向为125度。天气条件良好,适合外出活动。


    
你: https://github.langchain.ac.cn/langgraph/reference/mcp/总结这篇文档

> Entering new AgentExecutor chain...

Invoking: `fetch` with `{'max_length': 10000, 'raw': False, 'url': 'https://github.langchain.ac.cn/langgraph/reference/mcp/'}`

Contents of https://github.langchain.ac.cn/langgraph/reference/mcp/:
MCP 适配器 - LangChain 框架
............
相关推荐
木头左6 小时前
基于Backtrader框架的指数期权备兑策略实现与验证
python
淬炼之火6 小时前
基于Docker Desktop 和 Ubuntu 在 Windows上部署轻量化大模型(Qwen-LLM)
笔记·ubuntu·docker·语言模型·容器
李松桃7 小时前
python第三次作业
java·前端·python
m0_561359677 小时前
使用PyTorch构建你的第一个神经网络
jvm·数据库·python
马士兵教育7 小时前
计算机专业学生入行IT行业,编程语言如何选择?
java·开发语言·c++·人工智能·python
CoderJia程序员甲7 小时前
GitHub 热榜项目 - 日榜(2026-01-28)
人工智能·ai·大模型·github·ai教程
diediedei7 小时前
持续集成/持续部署(CI/CD) for Python
jvm·数据库·python
shangjian0077 小时前
AI-大语言模型LLM-Transformer架构1-整体介绍
人工智能·语言模型·transformer
weixin_445402307 小时前
Python游戏中的碰撞检测实现
jvm·数据库·python
勇往直前plus7 小时前
大模型开发手记(二):基于 LangChain 的 RAG 架构全面解析与落地实践
架构·langchain