Dify 可以通过插件实现 MCP 服务调用,而被调用的 MCP 服务基本可以分为以下两类:

  1. 通用 MCP 服务(非本地 MCP 服务)。
  2. 本地 MCP 服务。

本地 MCP 服务指的是本地通过 Java 或其他语言实现的 MCP 服务器端。

当你会用 Dify 调用本地 MCP 服务,也就意味着你会使用 Dify 调用通用 MCP 服务了,因为实现步骤和原理基本都是一样。

1.什么是MCP?

MCP 是 Model Context Protocol,模型上下文协议,它是由 Anthropic(Claude 大模型母公司)提出的开放协议,用于大模型连接外部“数据源”的一种协议。

它可以通俗的理解为 Java 界的 Spring Cloud Openfeign,只不过 Openfeign 是用于微服务通讯的,而 MCP 用于大模型通讯的,但它们都是为了通讯获取某项数据的一种机制,如下图所示:

2.为什么需要MCP?

MCP 存在的意义是它解决了大模型时代最关键的三个问题:数据孤岛、开发低效和生态碎片化等问题。

1.打破数据孤岛,让AI“连接万物”

大模型本身无法直接访问实时数据或本地资源(如数据库、文件系统),传统方式需要手动复制粘贴或定制接口。MCP 通过标准化协议,让大模型像“插USB”一样直接调用外部工具和数据源,例如:

  • 查天气时自动调用气象 API,无需手动输入数据。
  • 分析企业数据时直接连接内部数据库,避免信息割裂。

2.降低开发成本,一次适配所有场景

在之前每个大模型(如 DeepSeek、ChatGPT)需要为每个工具单独开发接口(Function Calling),导致重复劳动,MCP 通过统一协议:

  • 开发者只需写一次 MCP 服务端,所有兼容 MCP 的模型都能调用。
  • 用户无需关心技术细节,大模型可直接操作本地文件、设计软件等。

3.提升安全性与互操作性

  • 安全性:MCP 内置权限控制和加密机制,比直接开放数据库更安全。
  • 生态统一:类似 USB 接口,MCP 让不同厂商的工具能“即插即用”,避免生态分裂。

4.推动AIAgent的进化

MCP 让大模型从“被动应答”变为“主动调用工具”,例如:

  • 自动抓取网页新闻补充实时知识。
  • 打开 Idea 编写一个“Hello World”的代码。

MCP 的诞生,相当于为AI世界建立了“通用语言”,让模型、数据和工具能高效协作,最终释放大模型的全部潜力。

3.MCP组成和执行流程

MCP 架构分为以下 3 部分:

  • 客户端:大模型应用(如 DeepSeek、ChatGPT)发起 MCP 协议请求。
  • 服务器端:服务器端响应客户端的请求,并查询自己的业务实现请求处理和结果返回。

运行流程

  1. 用户提问 LLM。
  2. LLM 查询 MCP 服务列表。
  3. 找到需要调用 MCP 服务,调用 MCP 服务器端。
  4. MCP 服务器接收到指令。
  5. 调用对应工具(如数据库)执行。
  6. 返回结果给 LLM。

4.编写本地MCP服务

接下来,我们使用 Spring AI 来实现本地 MCP 服务器端,它的主要实现步骤如下:

  1. 添加 MCP Server 依赖。
  2. 设置 MCP 配置信息。
  3. 编写 MCP Server 服务代码。
  4. 将 MCP Server 进行暴露设置。

关键实现代码如下。

4.1 添加 MCP Server 依赖

<dependencies>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-server-webflux</artifactId>
</dependency>
</dependencies> <repositories>
<repository>
<name>Central Portal Snapshots</name>
<id>central-portal-snapshots</id>
<url>https://central.sonatype.com/repository/maven-snapshots/</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<releases>
<enabled>false</enabled>
</releases>
</repository>
</repositories>

MCP Server 依赖有三种类型:

  • 标准输入/输出 (STDIO):spring-ai-starter-mcp-server
  • Spring MVC****(服务器发送的事件):spring-ai-starter-mcp-server-webmvc
  • Spring WebFlux(响应式 SSE):spring-ai-starter-mcp-server-webflux

4.2 设置 MCP 配置信息

MCP Server 包含以下配置信息:

配置项 描述 默认值
enabled 启用/禁用 MCP 服务器 TRUE
stdio 启用/禁用 stdio 传输 FALSE
name 用于标识的服务器名称 mcp-server
version 服务器版本 1.0.0
type 服务器类型 (SYNC/ASYNC) SYNC
resource-change-notification 启用资源更改通知 TRUE
prompt-change-notification 启用提示更改通知 TRUE
tool-change-notification 启用工具更改通知 TRUE
tool-response-mime-type (可选)每个工具名称的响应 MIME 类型。例如,将 mime 类型与工具名称相关联spring.ai.mcp.server.tool-response-mime-type.generateImage=image/pngimage/pnggenerateImage() -
sse-message-endpoint Web 传输的 SSE 终端节点路径 /mcp/message

其中 MCP Server 又分为以下两种类型。

服务器类型

  • 同步服务器:默认服务器类型,它专为应用程序中的简单请求-响应模式而设计。要启用此服务器类型,请在您的配置中设置。 激活后,它会自动处理同步工具规格的配置,spring.ai.mcp.server.type=SYNC。
  • 异步服务器:异步服务器实现使用非阻塞作并针对非阻塞作进行了优化。要启用此服务器类型,请使用配置您的应用程序。此服务器类型会自动设置具有内置 Project Reactor 支持的异步工具规范,spring.ai.mcp.server.type=ASYNC。

4.3 编写MCPServer服务代码

编写天气预报查询伪代码:

import org.springframework.ai.tool.annotation.Tool;
import org.springframework.stereotype.Service; import java.util.Map; @Service
public class WeatherService { @Tool(description = "根据城市名称获取天气预报")
public String getWeatherByCity(String city) {
Map<String, String> mockData = Map.of(
"西安", "晴天",
"北京", "小雨",
"上海", "大雨"
);
return mockData.getOrDefault(city, "抱歉:未查询到对应城市!");
} }

4.4 将服务暴露出去

@Bean
public ToolCallbackProvider weatherTools(WeatherService weatherService) {
return MethodToolCallbackProvider.builder().toolObjects(weatherService).build();
}

这样 MCP Server 就编写完成了。

5.Dify调用本地MCP

Dify 调用 MCP 主要步骤如下:

  1. 安装 MCP 插件。
  2. 配置 MCP 服务 HTTP 地址。
  3. 配置 Agent 相关信息。
  4. 运行测试。

具体配置如下。

5.1 安装 MCP 插件

安装 Agent 策略(支持 MCP 工具)如下图所示:

MCP SSE 选装,非必须,可以为后续 Agent 提供 MCP 工具列表,方便 LLM 正确理解和调用工具。

5.2 配置 MCP 服务地址

Dify 只支持 HTTP 协议的 MCP 服务调用,它的配置格式如下:

{
"server_name1": {
"transport": "sse",
"url": "http://127.0.0.1:8000/sse",
"headers": {},
"timeout": 50,
"sse_read_timeout": 50
},
"server_name2": {
"transport": "sse",
"url": "http://127.0.0.1:8001/sse"
},
"server_name3": {
"transport": "streamable_http",
"url": "http://127.0.0.1:8002/mcp",
"headers": {},
"timeout": 50
},
"server_name4": {
"transport": "streamable_http",
"url": "http://127.0.0.1:8003/mcp"
}
}

支持配置多个 MCP 服务,或者是以下 JSON 格式也支持:

{
"mcpServers": {
"server_name1": {
"transport": "sse",
"url": "http://127.0.0.1:8000/sse",
"headers": {},
"timeout": 50,
"sse_read_timeout": 50
},
"server_name2": {
"transport": "sse",
"url": "http://127.0.0.1:8001/sse"
},
"server_name3": {
"transport": "streamable_http",
"url": "http://127.0.0.1:8002/mcp",
"headers": {},
"timeout": 50
},
"server_name4": {
"transport": "streamable_http",
"url": "http://127.0.0.1:8003/mcp"
}
}
}

5.3 配置 Agent

Agent 需要配置的项目比较多,首先是 Agent 策略:

然后是 LLM,选择合适的大模型即可,之后配置 MCP 工具和 HTTP 地址,如下图所示:

之后配置指令和查询问题:

5.4 测试 MCP 调用

我们创建的是一个 ChatFlow,执行效果如下:

执行符合预期。

小结

Dify 调用 MCP 服务主要依靠的是 HTTP 地址和 MCP 协议,对于用户来说他面向的是大模型,对于程序来说是大模型调用了 MCP 服务,所以大模型端也就是 MCP 的客户端。我们会调用本地 MCP 服务了,那么问题来了,如何调用通用的 MCP 服务呢?

本文已收录到我的技术小站 www.javacn.site,其中包含的内容有:Spring AI、LangChain4j、Dify、AI Agent、MCP、Function Call、RAG、向量数据库、Prompt、多模态、向量数据库、嵌入模型等内容。

超实用!Dify快速接入本地MCP服务的更多相关文章

  1. 快速搭建本地Nuget服务

    一  创建Nuget 服务项目 1.创建一个空白的asp.net web项目,需要.net 4.6以上 2.在Nuget中搜索 nuget.server ,可以看到是由 .Net 基金再维护的,几乎傻 ...

  2. 【NGROK】快速实现本地Web服务到外网的映射

    NGROK官网:https://ngrok.com NGROK百科:http://baike.baidu.com/view/13085941.htm?fr=aladdin 使用ngrok(Window ...

  3. 【转】使用ngrok快速地将本地Web服务映射到外网

    为什么要使用ngrok? 作为一个Web开发者,我们有时候会需要临时地将一个本地的Web网站部署到外网,以供它人体验评价或协助调试等等,通常我们会这么做: 找到一台运行于外网的Web服务器 服务器上有 ...

  4. Spring-boot:快速搭建微框架服务

    前言: Spring Boot是为了简化Spring应用的创建.运行.调试.部署等而出现的,使用它可以做到专注于Spring应用的开发,而无需过多关注XML的配置. 简单来说,它提供了一堆依赖打包,并 ...

  5. incubator-dolphinscheduler 如何在不写任何新代码的情况下,能快速接入到prometheus和grafana中进行监控

    一.prometheus和grafana 简介 prometheus是由谷歌研发的一款开源的监控软件,目前已经贡献给了apache 基金会托管. 监控通常分为白盒监控和黑盒监控之分. 白盒监控:通过监 ...

  6. 【转】使用sinopia五步快速完成本地npm搭建

    使用sinopia五步快速完成本地npm搭建 时间 2016-03-01 14:55:30  繁星UED 原文  http://ued.fanxing.com/shi-yong-sinopiawu-b ...

  7. 如何让微信小程序快速接入七牛云

    如果你确定用七牛运行小程序的话,给大家分享一个九折优惠码:61d1fd4d1 月 9 日 微信小程序正式发布,小程序终于揭开了它神秘的面纱,开发者对小程序的追捧更是热度不减.从小程序的热门应用场景来看 ...

  8. spring boot / cloud (十八) 使用docker快速搭建本地环境

    spring boot / cloud (十八) 使用docker快速搭建本地环境 在平时的开发中工作中,环境的搭建其实一直都是一个很麻烦的事情 特别是现在,系统越来越复杂,所需要连接的一些中间件也越 ...

  9. 如何接入银联“快速接入”产品API

    引言:使用银联开放平台的用户或多或少都接触过产品API吧,那么大家对于“快速接入”产品API是否还会存在一些疑问呢?因为我之前对“快速接入”模糊不清,所以整理的一份详细的资料,里面梳理了“快速接入”产 ...

  10. 快速接入 Android BLE 开发的基础框架

    代码地址如下:http://www.demodashi.com/demo/12092.html ** Android BLE基础操作框架,基于回调,操作简单.包含扫描.多连接.广播包解析.服务读写及通 ...

随机推荐

  1. 删除空白行,报错 raise KeyError(list(np.compress(check, subset))) KeyError: ['姓名']

    之前这段程序跑完后没报错,经调试发现到这一句报错 > df.dropna(subset=['姓名'],inplace=True) 意思是删除'姓名'列 含有'NAN'的行 思考第一步:应该是 d ...

  2. uniapp支付宝小程序生成分享图方案(最新)

    最近公司业务开发支付宝小程序,功能涉及生成分享图的功能,开始研究实现方案. 开发过微信小程序的小伙伴应该都知道,在微信中生成分享图最常用的方案是使用第三方库Painter GitHub官方仓库地址为: ...

  3. Mac 干净彻底地卸载 MySQL

    前言 卸载MySQL,首先得知道MySQL的路径.默认的话是在/usr/local文件夹下的. 在系统偏好设置面板中可以看到之前安装的MySQL,此时若想卸载MySQL,可以按照如下步骤来. 之前安装 ...

  4. mysql8导入myslq5 报错

    打开sql文件替换 我的数据库编码是utf8mb4,如果你的数据库编码是别的,替换成你自己的编码. utf8mb4_0900_ai_ci替换为utf8mb4_general_ci

  5. Tauri跨端笔记实战(1) - 从零打造一款跨端的 AI 笔记

    前言 Tauri 跨端笔记实战项目是基于 Notegen 开源项目,本系列深度解析如何运用Tauri框架开发跨平台AI笔记应用.涵盖核心技术选型.架构设计.典型场景开发及常见问题解决方案,通过代码级演 ...

  6. final关键字、Object类--java进阶day01

    1.规则 被final修饰的变量,名称都要大写,多单词的名称则需_来分隔 1.修饰方法 method方法已经不能被重写了,因为修饰该方法的是final 2.修饰类 当一个类中所有的成员方法都不想被重写 ...

  7. 【Maven】在 Eclipse 中使用 Maven

    在 Eclipse 中使用 Maven 1 安装 Maven 核心程序 下载地址:http://maven.apache.org/ 检查 JAVA_HOME 环境变量.Maven 是使用 Java 开 ...

  8. 【服务器】Nodejs在局域网配置https访问

    [服务器]Node.js在局域网配置https访问 零.需求: 做一个局域网WebRTC视频聊天系统,需要用到HTTPS.因此,配置Node.js使其支持HTTPS访问. 一.解决 在线生成和证书 访 ...

  9. leetcode每日一题:最小化字符串长度

    题目 2716. 最小化字符串长度 给你一个下标从 0 开始的字符串 s ,重复执行下述操作 任意 次: 在字符串中选出一个下标 i ,并使 c 为字符串下标 i 处的字符.并在 i 左侧(如果有)和 ...

  10. PG的子查询:insert 没有就插入记录,update有则更新记录

    insert into t --进行插入 values(1,'name') ON CONFLICT(id) --如果id这个键存在 do update set --更新以下字段 name=EXCLUD ...