Spring Ai Alibaba Gateway 實現存量應用轉 MCP 工具

作者簡介:你好,我是影子,Spring Ai Alibaba開源社區 Committer,持續分享Spring Ai Alibaba最新進展 + 業界各類AI工程相關的方案

  • 最近有斷時間沒更了,熟悉我的朋友知道我剛結束完畢業旅行,最近也因為入職,參與公司為期一周的文化相關的培訓(培訓的東西真是太贊了,每一條都直擊高效生活的本質,受益非淺,主動積極、雙贏思維,個人成長->公眾成長等等),實在抽不出時間來寫文章了,這不趁著周末趕快寫點東西

本文是官網更詳細的上手例子:Spring AI Alibaba MCP Gateway 正式發布,零代碼實現存量應用轉換 MCP 工具!

Gateway 實現存量應用轉 MCP 工具

[!TIP]
Spring AI Alibaba MCP Gateway 基于 Nacos 提供的 MCP server registry 實現,為普通應用建立一個中間代理層 Java MCP 應用。一方面將 Nacos 中注冊的服務信息轉換成 MCP 協議的服務器信息,以便 MCP 客戶端可以無縫調用這些服務;另一方面可以實現協議轉化,將 MCP 協議轉換為對后端 HTTP、Dubbo 等服務的調用。基于 Spring AI Alibaba MCP Gateway,您無需對原有業務代碼進行改造,新增或者刪除 MCP 服務(在 Nacos 中)無需重啟代理應用

實戰代碼可見:https://github.com/GTyingzi/spring-ai-tutorial 下的 other 目錄下的 nacos-restful 模塊、mcp 目錄下的 server 目錄下的 mcp-gateway 模塊

restful 服務

pom 文件
<properties><nacos.version>3.0.2</nacos.version>
</properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>com.alibaba.nacos</groupId><artifactId>nacos-client</artifactId><version>${nacos.version}</version><scope>compile</scope></dependency>
</dependencies>
application.yml
server:port: ${SERVERPORT:18081}  # 默認端口為18081,可以通過命令行參數SERVERPORT覆蓋spring:application:name: nacos-restfultcloud:# nacos注冊中心配置nacos:discovery:username: nacospassword: nacosserver-addr: 127.0.0.1:8848namespace: 4ad3108b-4d44-43d0-9634-3c1ac4850c8c # nacos3.*版本
config
package com.spring.ai.tutorial.other.config;import com.alibaba.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingFactory;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.pojo.Instance;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Map;
import java.util.Objects;
import java.util.Properties;/*** @author yingzi* @since 2025/7/7*/
@Configuration
public class NacosConfig {private static final Logger logger = LoggerFactory.getLogger(NacosConfig.class);@Value("${spring.application.name}")private String serviceName;@Value("${spring.cloud.nacos.discovery.server-addr}")private String serverAddr;@Value("${spring.cloud.nacos.discovery.namespace}")private String namespace;@Value("${spring.cloud.nacos.discovery.username}")private String username;@Value("${spring.cloud.nacos.discovery.password}")private String password;@Value("${server.port}")private int port;@Beanpublic NamingService namingService() throws NacosException, UnknownHostException {Properties properties = new Properties();properties.put(PropertyKeyConst.NAMESPACE, Objects.toString(this.namespace, ""));properties.put(PropertyKeyConst.SERVERADDR, Objects.toString(this.serverAddr, ""));properties.put(PropertyKeyConst.USERNAME, Objects.toString(this.username, ""));properties.put(PropertyKeyConst.PASSWORD, Objects.toString(this.password, ""));NamingService namingService = NamingFactory.createNamingService(properties);init(namingService);return namingService;}private void init(NamingService namingService) throws NacosException, UnknownHostException {Instance instance = new Instance();// 自動獲取本機IPinstance.setIp(InetAddress.getLocalHost().getHostAddress());instance.setPort(port);instance.setMetadata(Map.of("register.timestamp", String.valueOf(System.currentTimeMillis())));logger.info("注冊實例: {}:{}", instance.getIp(), port);namingService.registerInstance(serviceName, instance);}}
Controller
package com.spring.ai.tutorial.other.controller;import com.spring.ai.tutorial.other.utils.ZoneUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;/*** @author yingzi* @date 2025/4/6:12:56*/
@RestController
@RequestMapping("/time")
public class TimeController {private static final Logger logger = LoggerFactory.getLogger(TimeController.class);/*** 獲取指定時區的時間*/@GetMapping("/city")public String getCiteTimeMethod(@RequestParam("timeZoneId") String timeZoneId) {logger.info("The current time zone is {}", timeZoneId);return String.format("The current time zone is %s and the current time is " + "%s", timeZoneId,ZoneUtils.getTimeByZoneId(timeZoneId));}
}
package com.spring.ai.tutorial.other.utils;import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;/*** @author yingzi* @date 2025/3/25:14:59*/
public class ZoneUtils {public static String getTimeByZoneId(String zoneId) {// Get the time zone using ZoneIdZoneId zid = ZoneId.of(zoneId);// Get the current time in this time zoneZonedDateTime zonedDateTime = ZonedDateTime.now(zid);// Defining a formatterDateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss z");// Format ZonedDateTime as a stringString formattedDateTime = zonedDateTime.format(formatter);return formattedDateTime;}public static void main(String[] args) {System.out.println(getTimeByZoneId("Asia/Shanghai"));}}
效果:注冊至 Nacos 中

nacos 配置

Mcp server 連接 restful 配置

在 MCP 管理-MCP 列表處創建 MCP Server

  • 填寫命名空間:4ad3108b-4d44-43d0-9634-3c1ac4850c8c

,不填寫默認為 Default

  • MCP 服務名:mcp-nacos-restful
  • 協議類型:這里選擇 sse
  • HTTP 轉 MCP 服務:這里選擇 http
  • 后端服務:選擇已有服務(因為我們的后端服務已經注冊在 Nacos 中了,故直接使用即可,也可以通過新建服務指定 ip+port 的形式)
  • 描述:該項服務的說明
  • 服務版本:指定版本

新增 Tool 配置

Tool 名稱:getCiteTimeMethod

Tool 描述:獲取指定時區的時間

啟用:True

Tool 入參描述:

  • timeZoneId;string;time zone id, such as Asia/Shanghai

協議轉換配置(注意,這里輸出的轉換邏輯具體可看 com.alibaba.cloud.ai.mcp.nacos.gateway.jsontemplate 包下的 ResponseTemplateParser 類)

{
"requestTemplate":{"method":"GET","url":"/time/city","argsToUrlParam":true
},
"responseTemplate":{"body":"{{.}}"
}
}

發布后,可到配置管理處看到相關配置信息

gateway 轉接

pom 文件
<properties><!-- Spring AI Alibaba --><spring-ai-alibaba.version>1.0.0.3-SNAPSHOT</spring-ai-alibaba.version>
</properties><dependencies><dependency><groupId>com.alibaba.cloud.ai</groupId><artifactId>spring-ai-alibaba-starter-nacos-mcp-gateway</artifactId><version>${spring-ai-alibaba.version}</version></dependency><!-- MCP Server WebFlux 支持(也可換成 WebMvc--><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-starter-mcp-server-webflux</artifactId></dependency></dependencies>
application.yml
server:port: 19000spring:application:name: mcp-gateway-serverai:mcp:server:name: mcp-gateway-serverversion: 1.0.0alibaba:mcp:nacos:namespace: 4ad3108b-4d44-43d0-9634-3c1ac4850c8cserver-addr: 127.0.0.1:8848username: nacospassword: nacosgateway:enabled: trueservice-names: mcp-nacos-restful # 和nacos配置的mcp server保持一致# 調試日志
logging:level:io:modelcontextprotocol:client: DEBUGspec: DEBUGserver: DEBUG

驗證

啟動對應的兩個模塊

  • nacos-restful 模塊
  • mcp-gateway 模塊

在利用 MCP Inspector 進行測試

參考資料

Spring AI Alibaba MCP Gateway 正式發布,零代碼實現存量應用轉換 MCP 工具!

往期文章解讀

第一章內容

SpringAI(GA)的chat:快速上手+自動注入源碼解讀

SpringAI(GA):ChatClient調用鏈路解讀

第二章內容

SpringAI的Advisor:快速上手+源碼解讀

SpringAI(GA):Sqlite、Mysql、Redis消息存儲快速上手

第三章內容

SpringAI(GA):Tool工具整合—快速上手

SpringAI(GA):Tool源碼+工具觸發鏈路解讀

第四章內容

SpringAI(GA):結構化輸出的快速上手+源碼解讀

第五章內容

SpringAI(GA):內存、Redis、ES的向量數據庫存儲—快速上手

SpringAI(GA):向量數據庫理論源碼解讀+Redis、Es接入源碼

第六章內容

SpringAI(GA):RAG快速上手+模塊化解讀

SpringAI(GA):RAG下的ETL快速上手

SpringAI(GA):RAG下的ETL源碼解讀

第七章內容

SpringAI(GA):Nacos2下的分布式MCP

SpringAI(GA):Nacos3下的分布式MCP

SpringAI(GA):MCP源碼解讀

SpringAI(GA): SpringAI下的MCP源碼解讀

進階:MCP服務鑒權案例

第八章內容

SpringAI(GA): 多模型評估篇

第九章內容

SpringAI(GA):觀測篇快速上手+源碼解讀

第十章內容

Spring AI Alibaba Graph:快速入門

Spring AI Alibaba Graph:多節點并行—快速上手

Spring AI Alibaba Graph:節點流式透傳案例

Spring AI Alibaba Graph:分配MCP到指定節點

Spring AI Alibaba Graph:中斷!人類反饋介入,流程絲滑走完~

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/88771.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/88771.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/88771.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

HTTP和HTTPS部分知識點

HTTP基本概念 超文本-傳輸-協議 協議 HTTP是一個用在計算機世界里的協議。它使用計算機可以理解的語言確立了一種計算機之間交流通信的規范(兩個以上的參與者)&#xff0c;以及相關的各種控制和錯誤處理方式(行為約定和規范)。傳輸 HTTP協議是一個雙向協議。是一個在計算機世界…

第10講——一元函數積分學的幾何應用

文章目錄定積分計算平面圖形的面積直角坐標系下參數方程下極坐標系下定積分計算旋轉體的體積曲邊梯形繞x軸旋轉一周所得到的旋轉體的體積曲邊梯形繞y軸旋轉一周所得到的旋轉體的體積平面曲線繞定直線旋轉定積分計算函數的平均值定積分計算平面光滑曲線的弧長曲線L繞x軸旋轉一周…

Go從入門到精通(20)-一個簡單web項目-服務搭建

Go從入門到精通&#xff08;15&#xff09;-包&#xff08;package&#xff09; Go從入門到精通&#xff08;9&#xff09;-函數 文章目錄Go從入門到精通&#xff08;15&#xff09;-包&#xff08;package&#xff09;Go從入門到精通&#xff08;9&#xff09;-函數前言gogin…

Python爬蟲實戰:研究python-docx庫相關技術

1. 引言 1.1 研究背景與意義 隨著學術資源數字化程度的提高,科研工作者面臨海量文獻數據的篩選與分析挑戰。傳統人工調研方式效率低下,難以全面捕捉研究領域的動態趨勢。自動化文獻分析系統能夠通過爬蟲技術快速采集多源數據,并通過文本挖掘提取關鍵信息,為研究方向選擇、…

Django中序列化與反序列化

1&#xff1a;序列化&#xff1a;將數據結構或對象狀態轉換為可以存儲或傳輸的格式&#xff08;如JSON、XML&#xff09;的過程。在Web開發中&#xff0c;通常是將模型實例&#xff08;或查詢集&#xff09;轉換為JSON格式&#xff0c;以便通過HTTP響應發送給客戶端。序列化&am…

【離線數倉項目】——電商域DWD層開發實戰

摘要本文主要介紹了離線數倉項目中電商域DWD層的開發實戰。DWD層是數據倉庫架構中的明細數據層&#xff0c;對ODS層的原始數據進行清洗、規范、整合與業務建模。它具有數據清洗、標準化、業務建模、整合、維度掛載等作用&#xff0c;常見設計特征包括一致性、明細級建模、保留歷…

爬蟲-正則使用

1.模塊選擇用re模塊導入&#xff0c;&#xff0c;最前面加個r&#xff0c;就不用怕轉義了2.模塊使用re.findall使用結果是數組方式呈現re.finditer把結果變成迭代器&#xff0c;從迭代器類中間取數re.searchre.search 只能匹配到第一個識別到的內容re.match3.推薦寫法先預加載完…

python-range函數

文章目錄基本用法重要特性與列表轉換注意事項遍歷回去列表的元素索引range()是Python中用于生成數字序列的內置函數&#xff0c;常用于循環和序列生成。基本用法 range(stop) # 生成0到stop-1的整數序列 range(start, stop) # 生成start到stop-1的整數序列 r…

汽車功能安全-軟件集成和驗證(Software Integration Verification)【目的、驗證輸入、集成驗證要求】9

文章目錄1 目的2 驗證輸入3 軟件集成要求3.1 要求和建議3.2 汽車行業示例&#xff08;混合動力控制器軟件&#xff09;4 驗證要求1 目的 軟件集成和驗證階段的核心目標是證明集成后的軟件單元&#xff08;模塊、組件&#xff09;已經正確地開發出來&#xff0c;滿足了所有的功…

每天一個前端小知識 Day 27 - WebGL / WebGPU 數據可視化引擎設計與實踐

WebGL / WebGPU 數據可視化引擎設計與實踐&#x1f3af; 一、為什么前端需要 WebGL / WebGPU&#xff1f; 傳統的圖表庫如 ECharts、Highcharts 基于 Canvas 或 SVG&#xff0c;適合 2D 渲染&#xff0c;但&#xff1a; 當數據量 > 1 萬時&#xff0c;SVG 性能瓶頸明顯&…

JavaScript代碼段注入:動態抓取DOM元素的原理與實踐

1.F12打開網頁說明&#xff1a;以百度網站為例。通過插入代碼塊抓取當前網頁dom元素。2.新代碼段說明&#xff1a;點擊源代碼/來源菜單項下面的代碼段。點擊新代碼段新增代碼段。下面以腳本代碼段#6為例。3.編寫代碼塊說明&#xff1a;編寫javascript代碼&#xff0c;點擊下面的…

Spring Easy

Spring Easy 用途 通過自動配置&#xff0c;實現了一些國內 Spring Boot 開發時需要在 Spring Boot 框架基礎上完成的一些配置工作&#xff0c;可以提升基于 Spring Boot 開發 Web 應用的效率。 安裝 使用 Maven 進行包管理&#xff0c;可以從中央倉庫安裝依賴&#xff1a;…

【Node.js】文本與 pdf 的相互轉換

pdf 轉文本 主要使用 pdf-parse 這個庫&#xff0c;直接識別提取我們 pdf 文件中的文字。 const express require("express"); const fs require("fs"); const PDFParser require("pdf-parse"); const cors require("cors");const…

分布式ID方案

目錄 &#x1f4ca; 分布式ID方案核心指標對比 &#x1f50d; 分方案深度解析 ?? 1. UUID (Universally Unique Identifier) ?? 2. Snowflake (Twitter開源) ?? 3. 美團Leaf 號段模式 Snowflake模式 &#x1f504; 4. 百度UidGenerator &#x1f680; 5. CosId …

張量類型轉換

一.前言本章節我們來講解張量的類型轉換&#xff0c;掌握張量的轉換方法&#xff0c;張量的類型轉換也是經常使?的?種操作&#xff0c;是必須掌握的知識點。在本?節&#xff0c;我們主要學習如何將 numpy 數組和 PyTorch Tensor 的轉化?法.二.張量轉換為 numpy 數組使? Te…

JavaEE-初階-多線程初階

概念第一個多線程程序 可以通過查看jdk路徑來找到jdk的控制可以通過jconsole來查看線程。創建線程這是實現多線程的其中一種方法&#xff0c;繼承Thread類&#xff0c;實現run方法&#xff0c;之后實例化繼承了Thread類的MyThread方法&#xff0c;調用start方法&#xff0c;就會…

解釋全連接層的“參數數量”和“計算過程”,保證像看動畫片一樣直觀~

假設場景輸入圖像&#xff1a;一張極小的 灰度圖&#xff08;即 H2,W2&#xff0c;共4個像素&#xff09;&#xff0c;像素值如圖所示&#xff1a;隱藏層&#xff1a;假設隱藏層也是 &#xff08;即 H2,W2&#xff0c;共4個神經元&#xff09;&#xff0c;每個神經元用 ( 表示…

DOM編程實例(不重要,可忽略)

文章目錄 簡介 表格增加刪除&#xff0c;效果如下圖 樣式屬性案例 簡介 DOM---表格添加刪除&#xff0c;樣式屬性案例 表格增加刪除&#xff0c;效果如下圖 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><met…

?Windows API 介紹及核心函數分類表

Windows API 介紹? Windows API&#xff08;Application Programming Interface&#xff09;&#xff0c;也稱為WinAPI&#xff0c;是微軟Windows操作系統的核心編程接口。它提供了一系列函數、消息、數據結構、宏和系統服務&#xff0c;允許開發者創建運行在Windows平臺上的應…

Kubernetes Dashboard UI 部署安裝

K8S 集群環境&#xff1a; Ubuntu 24 / K8S 1.28.21. 推薦使用helm 安裝Kubernetes Dashboardsudo snap install helm --classic2. 部署Kubernetes Dashboard# Add kubernetes-dashboard repository helm repo add kubernetes-dashboard https://kubernetes.github.io/dashboar…