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 框架
............
相关推荐
拾柒SHY31 分钟前
Python爬虫入门自学笔记
笔记·爬虫·python
Franciz小测测32 分钟前
如何实现 Web 触发后的“离线”升级?Systemd 异步机制与 A/B 状态机切换详解
python·部署·自动升级·离线升级
小北方城市网35 分钟前
第 9 课:Python 全栈项目性能优化实战|从「能用」到「好用」(企业级优化方案|零基础落地)
开发语言·数据库·人工智能·python·性能优化·数据库架构
E_ICEBLUE1 小时前
PPT 智能提取与分析实战:把演示文档变成结构化数据
数据库·python·powerpoint
JSU_曾是此间年少1 小时前
pytorch自动微分机制探寻
人工智能·pytorch·python
敢敢のwings1 小时前
VGGT-Long:极简主义驱动的公里级单目三维重建系统深度解析(Pytorch安装手册版)
人工智能·pytorch·python
aiguangyuan1 小时前
CART算法简介
人工智能·python·机器学习
龘龍龙1 小时前
Python基础学习(十)
服务器·python·学习
轻竹办公PPT1 小时前
用 AI 制作 2026 年工作计划 PPT,需要准备什么
大数据·人工智能·python·powerpoint
Mqh1807621 小时前
day58 经典时序预测模型
python