掬月在手 發表於 2026-1-26 13:22:00

张高兴的大模型开发实战:(八)在 Dify 中使用 MCP 协议

<p></p><div class="toc"><div class="toc-container-header">目录</div><ul><li>MCP 是什么</li><li>Dify 作为 Client:调用外部 MCP 工具<ul><li>搭建 MCP 天气服务端</li><li>在 Dify 中接入“天气感知”能力</li></ul></li><li>Dify 作为 Server:被外部应用调用<ul><li>搭建“翻译专家”工作流</li><li>启用 MCP 服务</li><li>在外部 AI 应用中调用</li></ul></li></ul></div><p></p>
<p>在之前的博客中已经介绍了 MCP 的概念,以及在 LangChain 中如何使用 MCP 协议。今天这篇博客,将带大家实战如何在 Dify 中实现 MCP 场景。在开始正式的内容前,还是先简单的介绍一下 MCP。</p>
<h2 id="mcp-是什么">MCP 是什么</h2>
<p>想象一下,你想要构建一个超级 AI 助手,它不仅能陪你聊天,还能帮你查询实时天气、读取本地数据库里的库存信息等。为了实现这些功能,在过去,你需要为每一个外部工具编写特定的“适配器”。AI 模型本该是通用的智能大脑,但连接外部世界(工具和数据)的方式却极其割裂和破碎,需要花费大量时间在“对齐接口”这种低效的重复劳动上,MCP 协议应运而生。可以把 MCP 想象成 AI 世界的 USB 接口。USB 的出现改变了一切,它提供了一个统一的标准:无论你是鼠标、键盘还是 U 盘,只要符合 USB 协议,插上就能用。MCP 就是要成为 AI 与外部数据/工具连接的 USB 标准。它将世界分成了两端:</p>
<ul>
<li><strong>Host (主机端)</strong>:需要使用工具的 AI 应用,比如 Claude Desktop 客户端、Dify。</li>
<li><strong>Server (服务端)</strong>:提供特定能力的工具,比如一个能查天气的 Python 脚本,或者一个连接 MySQL 数据库的服务。</li>
</ul>
<p>只要 Host 和 Server 都支持 MCP 协议,它们就能瞬间“握手”成功,Host 能够自动理解 Server 提供了什么工具,需要什么参数,而无需人工再去编写复杂的接口定义。</p>
<p><img src="https://img2024.cnblogs.com/blog/1085877/202601/1085877-20260126131843078-636780870.jpg" alt="1" loading="lazy"></p>
<p>Dify 在 MCP 的生态中,它既可以是“插U盘的主机”,也可以是“被别人插的U盘”。</p>
<ul>
<li><strong>Dify 作为 Client (主机端):调用外部能力。</strong></li>
<li><strong>Dify 作为 Server (服务端):暴露自身能力。</strong> 这可能是更有趣的一点,比如在 Dify 里精心编排了一个复杂的工作流,这个工作流本身可以被封装成一个标准的 MCP 工具。这意味着,在其他 AI 应用中,可以直接调用在 Dify 里搭建好的这个强大的 Agent。</li>
</ul>
<h2 id="dify-作为-client调用外部-mcp-工具">Dify 作为 Client:调用外部 MCP 工具</h2>
<p>在这一部分,想让 Dify 的 AI 助手拥有“感知”当下天气的能力,而不是在那胡诌过去的训练数据。即将 Dify 作为一个“主机”,让它去连接一个 MCP Server。</p>
<h3 id="搭建-mcp-天气服务端">搭建 MCP 天气服务端</h3>
<p>首先,需要一个能够“说” MCP 协议的服务端。这里用到了 Python 的 <code>mcp</code> 库。</p>
<pre><code class="language-shell">pip install mcp httpx
</code></pre>
<p>创建一个 Python 文件 <code>weather_server.py</code> 实现天气查询的 MCP 服务,不需要手写复杂的协议握手代码,只需要用几个简单的装饰器即可。使用免费的 Open-Meteo API 进行天气查询。</p>
<pre><code class="language-python">import httpx
from mcp.server.fastmcp import FastMCP

# 初始化 FastMCP 服务器
mcp = FastMCP("Weather Service", host="0.0.0.0", port=8000)

async def _get_lat_long(city_name: str):
    """
    内部辅助函数:使用 Open-Meteo Geocoding API 将城市名称转换为经纬度。
    """
    url = "https://geocoding-api.open-meteo.com/v1/search"
    params = {"name": city_name, "count": 1, "language": "zh", "format": "json"}
   
    async with httpx.AsyncClient() as client:
      response = await client.get(url, params=params)
      data = response.json()
      
    if not data.get("results"):
      return None
      
    location = data["results"]
    return {
      "name": location["name"],
      "latitude": location["latitude"],
      "longitude": location["longitude"],
      "timezone": location.get("timezone", "UTC")
    }

@mcp.tool()
async def get_weather(city_name: str) -&gt; str:
    """
    获取指定城市的当前天气情况。
    输入城市名称(如 'Beijing', 'San Francisco', '上海'),返回温度、风速等信息。
    """
    # 1. 首先获取经纬度
    location = await _get_lat_long(city_name)
    if not location:
      return f"错误:未找到城市 '{city_name}'。请尝试使用更具体的名称或英文名称。"

    # 2. 构建 Open-Meteo API 请求
    url = "https://api.open-meteo.com/v1/forecast"
    params = {
      "latitude": location["latitude"],
      "longitude": location["longitude"],
      "current": ["temperature_2m", "relative_humidity_2m", "apparent_temperature", "weather_code", "wind_speed_10m"],
      "timezone": location["timezone"]
    }

    async with httpx.AsyncClient() as client:
      response = await client.get(url, params=params)
      weather_data = response.json()

    # 3. 解析并返回数据
    current = weather_data.get("current", {})
    units = weather_data.get("current_units", {})
   
    # 将天气代码 (WMO Code) 转换为文字描述 (简化版)
    weather_code = current.get("weather_code")
    weather_desc = "未知"
    if weather_code == 0: weather_desc = "晴朗"
    elif weather_code in : weather_desc = "多云/阴"
    elif weather_code in : weather_desc = "有雾"
    elif 51 &lt;= weather_code &lt;= 67: weather_desc = "有雨"
    elif 71 &lt;= weather_code &lt;= 77: weather_desc = "有雪"
    elif weather_code &gt;= 80: weather_desc = "雷雨/阵雨"

    return (
      f"--- {location['name']} 天气报告 ---\n"
      f"天气状况: {weather_desc}\n"
      f"当前温度: {current.get('temperature_2m')} {units.get('temperature_2m')}\n"
      f"体感温度: {current.get('apparent_temperature')} {units.get('apparent_temperature')}\n"
      f"相对湿度: {current.get('relative_humidity_2m')} {units.get('relative_humidity_2m')}\n"
      f"风速: {current.get('wind_speed_10m')} {units.get('wind_speed_10m')}"
    )

if __name__ == "__main__":
    # 运行 MCP 服务器
    mcp.run(transport="sse")
</code></pre>
<h3 id="在-dify-中接入天气感知能力">在 Dify 中接入“天气感知”能力</h3>
<p>现在 MCP 服务已经跑起来了,下面需要告诉 Dify 去哪里找到这个服务。回到 Dify 的网页界面:</p>
<ol>
<li>点击顶部菜单栏的 <code>工具 -&gt; MCP -&gt; 添加 MCP 服务</code>。<br>
<img src="https://img2024.cnblogs.com/blog/1085877/202601/1085877-20260126131855100-220859406.jpg" alt="2" loading="lazy"></li>
<li>在弹出的窗口中填写配置:<br>
服务端点 URL:http://host.docker.internal:8000/sse<br>
名称:Weather Service<br>
服务器标识符:weather-service<br>
<img src="https://img2024.cnblogs.com/blog/1085877/202601/1085877-20260126131906403-1457899443.jpg" alt="3" loading="lazy"></li>
</ol>
<p>如果连接成功,列表里会出现了一个绿色的“已连接”状态,点击展开,Dify 已经自动解析出了在 Python 代码里定义的 <code>get_weather</code> 函数,甚至连代码里写的注释都变成了工具的描述。</p>
<p><img src="https://img2024.cnblogs.com/blog/1085877/202601/1085877-20260126131920703-1710802138.jpg" alt="4" loading="lazy"></p>
<p>最后,来验证一下效果。</p>
<ol>
<li>创建一个新的 Chatflow 应用 <code>出行小助手</code>。<br>
<img src="https://img2024.cnblogs.com/blog/1085877/202601/1085877-20260126131931234-1720479185.jpg" alt="5" loading="lazy"></li>
<li>删除原有的 <code>LLM</code> 节点,添加一个 <code>Agent</code> 节点。<br>
<img src="https://img2024.cnblogs.com/blog/1085877/202601/1085877-20260126131941444-371143797.jpg" alt="6" loading="lazy"></li>
<li>设置 <code>AGENT 策略</code>,如果下拉列表为空,可以在插件市场进行下载。<br>
<img src="https://img2024.cnblogs.com/blog/1085877/202601/1085877-20260126131947624-566887205.jpg" alt="7" loading="lazy"></li>
<li>配置要使用的 <code>模型</code>,并在 <code>工具列表</code> 中新增刚刚添加的 MCP 服务。在 <code>指令</code> 中设置提示词。<code>查询</code> 设置为用户输入。<br>
<img src="https://img2024.cnblogs.com/blog/1085877/202601/1085877-20260126131954537-1839023922.jpg" alt="8" loading="lazy"><pre><code class="language-markdown"># Role
你是一位专业且贴心的出行规划专家。你擅长分析实时气象数据,提供包含穿衣、交通、安全及活动建议在内的全方位出行方案。

# Constraints
1. 语气专业、友好且富有亲和力。
2. 必须基于 MCP 工具返回的真实数据进行建议,严禁编造天气数值。
3. 输出应条理清晰,多使用列清单,避免大段文字。

# Goals
4. 数据调用:主动调用获取天气的 MCP 工具,获取用户指定目标的实时天气。
5. 多维分析:不仅报告气温,更要分析该天气对出行的具体影响。
6. 精准建议:给出极具参考价值的穿衣指南、交通方式推荐以及针对性提醒(如带伞、涂防晒霜或调整户外行程)。
</code></pre>
</li>
</ol>
<p>以上配置完成后,先在右侧进行预览测试。例如“我明天要去北京,查一下天气和穿衣建议。”观察结果发现,Dify 成功获取了北京的天气,并根据天气给出了具体的出行建议。</p>
<p><img src="https://img2024.cnblogs.com/blog/1085877/202601/1085877-20260126132010456-672146549.jpg" alt="9" loading="lazy"></p>
<h2 id="dify-作为-server被外部应用调用">Dify 作为 Server:被外部应用调用</h2>
<p>有时,当你在 Dify 中配置了一个复杂的工作流(Workflow),想要在外部的 AI 应用中进行调用,这时就需要反转视角,将 Dify 作为一个 MCP 服务。在开始案例之前,先添加一个“翻译专家”工作流,作为要被调用的 MCP 服务。</p>
<h3 id="搭建翻译专家工作流">搭建“翻译专家”工作流</h3>
<ol>
<li>在 Dify 首页点击 <code>创建空白应用</code>,选择 <code>工作流</code>,命名为 <code>翻译专家</code>,开始节点选择 <code>用户输入</code>。<br>
<img src="https://img2024.cnblogs.com/blog/1085877/202601/1085877-20260126132018580-1696326618.jpg" alt="10" loading="lazy"></li>
<li>点击 <code>用户输入</code> 节点,添加输入变量 <code>chinese</code>,即要翻译的中文。<br>
<img src="https://img2024.cnblogs.com/blog/1085877/202601/1085877-20260126132026421-1728406767.jpg" alt="11" loading="lazy"></li>
<li>添加一个 <code>LLM</code> 节点,并设置提示词。<br>
<img src="https://img2024.cnblogs.com/blog/1085877/202601/1085877-20260126132033495-2061130448.jpg" alt="12" loading="lazy"><pre><code class="language-markdown"># Role
你是一位资深的翻译专家,擅长将中文翻译为英文。用户的输入是一段中文,请将其翻译成最地道、最专业、最简洁的英文。直接输出翻译后的英文,不要包含任何解释或废话。

# Input
{{#1769390459829.chinese#}}
</code></pre>
</li>
<li>添加一个 <code>输出</code> 节点,并设置输出变量 <code>english</code>。<br>
<img src="https://img2024.cnblogs.com/blog/1085877/202601/1085877-20260126132050151-133391096.jpg" alt="13" loading="lazy"></li>
</ol>
<h3 id="启用-mcp-服务">启用 MCP 服务</h3>
<ol>
<li>进入工作流,点击左侧列表的 <code>设置</code>。<br>
<img src="https://img2024.cnblogs.com/blog/1085877/202601/1085877-20260126132059536-213985656.jpg" alt="14" loading="lazy"></li>
<li>启用 MCP 服务,并添加描述。<br>
<img src="https://img2024.cnblogs.com/blog/1085877/202601/1085877-20260126132106734-432797240.jpg" alt="15" loading="lazy"></li>
<li>复制 <code>服务端点 URL</code> 留存备用。</li>
</ol>
<h3 id="在外部-ai-应用中调用">在外部 AI 应用中调用</h3>
<p>拿到了 URL 后,在任意支持 MCP 调用的应用中都可以使用刚刚配置好的工作流,这里以 Visual Studio Code 为例。</p>
<ol>
<li>点击聊天框中的 <code>配置工具</code> 按钮,在弹出的顶部菜单中点击 <code>添加 MCP 服务器</code>。<br>
<img src="https://img2024.cnblogs.com/blog/1085877/202601/1085877-20260126132119267-1069399690.jpg" alt="16" loading="lazy"></li>
<li>选择 <code>HTTP</code>,输入刚刚复制的 URL,并设置唯一的 <code>服务器 ID</code>。<br>
<img src="https://img2024.cnblogs.com/blog/1085877/202601/1085877-20260126132126985-181144262.jpg" alt="17" loading="lazy"></li>
<li>配置完成后,可以看到 Visual Studio Code 输出的日志,提示已经连接到 MCP 服务。<br>
<img src="https://img2024.cnblogs.com/blog/1085877/202601/1085877-20260126132133212-264370915.jpg" alt="18" loading="lazy"></li>
<li>在 <code>配置工具</code> 列表中,只勾选刚刚添加的 MCP 服务,用于测试。<br>
<img src="https://img2024.cnblogs.com/blog/1085877/202601/1085877-20260126132141298-646916756.jpg" alt="19" loading="lazy"></li>
<li>尝试进行对话,Dify 中配置的“翻译专家”被成功调用。<br>
<img src="https://img2024.cnblogs.com/blog/1085877/202601/1085877-20260126132150863-510966656.jpg" alt="20" loading="lazy"></li>
</ol>
<p>AI 的未来,不在于拥有一个多么巨大的单一模型,而在于协作,MCP 正在迅速成为这种协作的标准语言。这篇博客通过两个简单的案例,介绍了 MCP 在 Dify 中的用法,后续不妨尝试一些更有趣的玩法:</p>
<ul>
<li>连接物理世界:写一个 MCP Server 控制家里的智能家居(Home Assistant)。想象一下,在 Dify 的对话框里输入“我得睡觉了”,AI 自动帮你关灯、拉窗帘、定闹钟。</li>
<li>连接私有数据:使用 <code>mcp-server-sqlite</code> 或 <code>mcp-server-postgres</code>,让 Dify 直接拥有查询你本地业务数据库的能力,生成报表。</li>
<li>打造个人超级助理:在 Dify 里编排好你专属的“周报生成器”、“代码审查器”,然后在 VS Code 里随时呼叫它们,让 AI 真正融入你的工作流。</li>
</ul><br><br>
来源:https://www.cnblogs.com/zhanggaoxing/p/19532842
頁: [1]
查看完整版本: 张高兴的大模型开发实战:(八)在 Dify 中使用 MCP 协议