哪个直播看大秀
发布日期:2025-12-17 13:51 点击次数:188图片
作家:小傅哥博客:https://bugstack.cn
❝千里淀、共享、成长,让我方和他东谈主齐能有所收货!😜
❞全球好,我是时刻UP主小傅哥。
刚刚曩昔两个月,市面的 MCP 处事,如星罗棋布一般约束炫夸出来,包括;百度、高德、网盘、支付宝。这些 MCP 处事,不错让咱们基于 Spring AI 框架构建的 Agent 具备额外丰富的使费力能。同期这也诠释,表率员👨🏻💻,应该具备开荒 MCP 处事的才调,Spring AI 让 Java 再次给力!
图片
对于 RAG、MCP、Agent 是什么,这里小傅哥仍是编写过了全套的教程,不错参加学习;https://bugstack.cn/md/project/ai-knowledge/ai-knowledge.html
本节小傅哥主要给全球共享,对于市面上这些轨范的带有考据权限的 MCP 处事,怎样使用 Spring AI 进行对接。同期咱们我方开荒的 MCP 处事,怎样加上权限校验。
一、例如,对接高德舆图 MCP高德舆图 MCP Server;
{ "mcpServers": { "amap-amap-sse": { "url": "https://mcp.amap.com/sse?key=您在高德官网上请求的key" } }}官网:https://lbs.amap.com/api/mcp-server/gettingstarted - 官网提供了创建对接 Key1. 代码使用示例@Configurationpublicclass McpConfig { @Bean public List<NamedClientMcpTransport> mcpClientTransport() { McpClientTransport transport = HttpClientSseClientTransport .builder("https://mcp.amap.com") .sseEndpoint("/sse?key=<your_key>") .objectMapper(new ObjectMapper()) .build(); return Collections.singletonList(new NamedClientMcpTransport("amap", transport)); } }对接时,需要设定 sseEndpoint 要是不设定个,Spring AI 默许是对 builder 的 baseUrl 值添加 /sse 的。是以,要是你要对接外部带有考据权限的 MCP 处事,需要手动开荒下 sseEndpoint 值。2. 形貌中的建设小傅哥,带着全球作念的 Ai Agent,也支撑了外部的这些带有权限校验的 MCP 处事。你不错,以多种风景进行建设。如;
{ "baseUri":"https://mcp.amap.com", "sseEndpoint":"/sse?key=801aabf79ed0ff78603cfe85****"}{ "baseUri":"https://mcp.amap.com", "sseEndpoint":"/sse?key=801aabf79ed0ff78603cfe85****"}以上两种建设风景,在 ai-agent-station 齐作念了兼容处理。以下是兼容代码,学习这部分项打算伙伴,不错平直阅读课程代码。@Slf4j@Componentpublicclass AiClientToolMcpNode extends AbstractArmorySupport { // ... 不祥部分代码 protected McpSyncClient createMcpSyncClient(AiClientToolMcpVO aiClientToolMcpVO) { String transportType = aiClientToolMcpVO.getTransportType(); switch (transportType) { case"sse" -> { AiClientToolMcpVO.TransportConfigSse transportConfigSse = aiClientToolMcpVO.getTransportConfigSse(); // http://127.0.0.1:9999/sse?apikey=DElk89iu8Ehhnbu String originalBaseUri = transportConfigSse.getBaseUri(); String baseUri; String sseEndpoint; int queryParamStartIndex = originalBaseUri.indexOf("sse"); if (queryParamStartIndex != -1) { baseUri = originalBaseUri.substring(0, queryParamStartIndex - 1); sseEndpoint = originalBaseUri.substring(queryParamStartIndex - 1); } else { baseUri = originalBaseUri; sseEndpoint = transportConfigSse.getSseEndpoint(); } sseEndpoint = StringUtils.isBlank(sseEndpoint) ? "/sse" : sseEndpoint; HttpClientSseClientTransport sseClientTransport = HttpClientSseClientTransport .builder(baseUri) // 使用截取后的 baseUri .sseEndpoint(sseEndpoint) // 使用截取或默许的 sseEndpoint .build(); McpSyncClient mcpSyncClient = McpClient.sync(sseClientTransport).requestTimeout(Duration.ofMinutes(aiClientToolMcpVO.getRequestTimeout())).build(); var init_sse = mcpSyncClient.initialize(); log.info("Tool SSE MCP Initialized {}", init_sse); return mcpSyncClient; } case"stdio" -> { AiClientToolMcpVO.TransportConfigStdio transportConfigStdio = aiClientToolMcpVO.getTransportConfigStdio(); Map<String, AiClientToolMcpVO.TransportConfigStdio.Stdio> stdioMap = transportConfigStdio.getStdio(); AiClientToolMcpVO.TransportConfigStdio.Stdio stdio = stdioMap.get(aiClientToolMcpVO.getMcpName()); // https://github.com/modelcontextprotocol/servers/tree/main/src/filesystem var stdioParams = ServerParameters.builder(stdio.getCommand()) .args(stdio.getArgs()) .build(); var mcpClient = McpClient.sync(new StdioClientTransport(stdioParams)) .requestTimeout(Duration.ofSeconds(aiClientToolMcpVO.getRequestTimeout())).build(); var init_stdio = mcpClient.initialize(); log.info("Tool Stdio MCP Initialized {}", init_stdio); return mcpClient; } } thrownew RuntimeException("err! transportType " + transportType + " not exist!"); }}以上代码,是为了自动化构建 MCP 处事的,其中 case sse 的部分,会对 url 进行拆分,要是自身 url 建设了校验权限,则不会从另外一个参数获取,不然从另外参数拼接。这么就不错很好的膨胀用户建设时的各种性问题了。以上是对于带有权限校验的 MCP 处事建设的问题,接下来,咱们要说下怎样我方开荒一个带有权限校验
二、收场,带有权限校验的 MCP 处事领先,Spring AI 是零碎提供基于自家的 OAuth2 框架,完成 MCP 处事的各种性权限校验的。不外现在提供的有打算能用,但不算进修。
图片
官网:https://spring.io/blog/2025/05/19/spring-ai-mcp-client-oauth2
1. 基于 OAuth2 认证1.1 工程结构图片
工程:https://gitcode.net/KnowledgePlanet/mcp-server-auth - 面向于学习 ai-agent-station 的伙伴使用 OAuth2 基于 Spring MVC 的风景到也简短,知谈添加建设即可。1.2 所需的 POM 文献<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-oauth2-resource-server</artifactId></dependency><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-oauth2-authorization-server</artifactId></dependency><dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-starter-mcp-server-webmvc</artifactId></dependency>1.3 测考研证
@Slf4j@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, properties = "server.shutdown=immediate")publicclass ApiTest { @LocalServerPort privateint port; privatefinal ObjectMapper objectMapper = new ObjectMapper(); @Test public void test_access_token() throws IOException, InterruptedException { String token = obtainAccessToken(); log.info("token:{}", token); // eyJraWQiOiJiMWQ0MGIxNi1hOTYzLTQ2NmYtYTVkOC02NGRjMzg0ODljYWEiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJtY3AtY2xpZW50IiwiYXVkIjoibWNwLWNsaWVudCIsIm5iZiI6MTc0ODA1MTc1NiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo1ODA5OCIsImV4cCI6MTc0ODA1MjA1NiwiaWF0IjoxNzQ4MDUxNzU2LCJqdGkiOiI5NjY4ZmZkMi0wNjQ2LTRiNmItODQ4Ni1jYzk3ZjMxNTdmOTEifQ.CG4GYai_NYkmfcqmNi-_HYG06Kan04uNSsC2ivn_eC9Ra6xMKYTs9KIT7k5lKxSFRUOPI7K0zJNVvNXrrIe0iFl-csrG2vGukNTGTPMxtUi2hheBMRbnvjvuojW4DeOEE8UOpdA6uow67ucwcymTlDXE-k7OjRZeyp7UdVz2WyoDFQhLB6ihLbDSj5puAZxfNocirRzo36gmW243aW9f1gugPUcpND-oobc2q8xyBG2cX2AlGXUSS-v9PLjHr2W2smFTKHHGwu7FpMMBnJLUT5gZD0llIg6yqro91nFaAFOpGHXjRZYgVjkRlzxx08Zuquva9PbStxbUl2j8hI43_Q var client = HttpClient.newHttpClient(); var request = HttpRequest.newBuilder() .uri(URI.create("http://localhost:" + port + "/sse")) .header("Accept", "text/event-stream") .header("Authorization", "Bearer " + token) .GET() .build(); var responseCode = new AtomicInteger(-1); var sseRequest = client.sendAsync(request, HttpResponse.BodyHandlers.ofInputStream()).thenApply(response -> { responseCode.set(response.statusCode()); if (response.statusCode() == 200) { log.info("response:{}", JSON.toJSONString(response)); return response; } else { thrownew RuntimeException("Failed to connect to SSE endpoint: " + response.statusCode()); } }); await().atMost(Duration.ofSeconds(1)).until(sseRequest::isDone); assertThat(sseRequest).isCompleted(); assertThat(responseCode).hasValue(200); } private String obtainAccessToken() throws IOException, InterruptedException { var client = HttpClient.newHttpClient(); var clearTextCredentials = "mcp-client:secret".getBytes(StandardCharsets.UTF_8); var credentials = new String(Base64.getUrlEncoder().encode(clearTextCredentials)); var request = HttpRequest.newBuilder() .uri(URI.create("http://localhost:" + port + "/oauth2/token")) .header("Authorization", "Basic " + credentials) .header("Content-Type", "application/x-www-form-urlencoded") .POST(ofString("grant_type=client_credentials")) .build(); var rawResponse = client.send(request, HttpResponse.BodyHandlers.ofString()).body(); Map<String, String> response = objectMapper.readValue(rawResponse, Map.class); return response.get("access_token"); } }加上 OAuth2 以后,就需要获取并开荒 accessToken 才能旁观 sse 处事了。2. 基于网关收场其实咱们到不非得依赖于 Spring OAuth2 往 MCP 处事里在添加一些其他的东西。倒不如平直走网关,让网关来管束权限,MCP 处事只作念处事的事情就好。
这里咱们基于 Nginx 来建设考据功能,诚然你不错在学习本节的案例后,建设任何其他的网关来管束你的 MCP 处事。
注重,这里的前置条目为你仍是随着小傅哥,至少完成了一个 MCP 处事。课程;https://t.zsxq.com/GwNZp
当咱们有了一套基于 sse 风景旁观的 mcp 后,咱们是不错给这套 mcp 基于 nginx 转发的风景进行旁观背面信得过的 mcp 处事的。在转发的经由中,拿到用户在地址 http://127.0.0.1:9999/sse?apikey=DElk89iu8Ehhnbu mcp 处事背面拼接的 apikey,并对 apikey 进行考据。
2.1 建设工程图片
在 ai-agent-station 形貌下,提供了 dev-ops-v2 建设 mcp 处事转发和考据才调。注重,泰国按摩群部署的时间,要把 mcp.localhost.conf 转发的 mcp 处事的地址,更换为你的地址。另外,每一个 mcp.localhost.conf 还不错建设域名,这么就达到了高德舆图 mcp 旁观的成果。例如;https://fatie.mcp.bugstack.cn/sse/apikey=*******2.2 处事转发&校验# 不错负载处事upstream backend_servers { server 192.168.1.108:8101;}server { listen 80; server_name 192.168.1.104; # 修改为你的现实处事器 IP 或域名【域名需要备案】 location /sse { # 考据apikey参数,这个apikey也不错对给与事端接口来处理。 if ($arg_apikey != "DElk89iu8Ehhnbu") { return403; # 要是apikey不正确,复返403谢绝旁观 } # 重写URL,去掉apikey参数 rewrite ^(/sse/)\?apikey=.* $1break; proxy_pass http://backend_servers; # 将请求代理到上游处事器组 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; chunked_transfer_encoding off; proxy_buffering off; proxy_cache off; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-Proto $scheme; } location /mcp/message { proxy_pass http://backend_servers; # 将请求代理到上游处事器组 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; }}特出注重,mcp 处事是有2个次序的,一个是 sse 旁观,还有一个 mcp/message 的处理。咱们只需要对 sse 的请求进行考据即可。/sse 请求旅途,需要会索要 apikey 与 nginx 建设的值进行对比,要是不正确则会复返一个 403 谢绝旁观,通过则放行。之后重写 url 地址,让转发到自身 mcp 的地址是干净的。从 http://127.0.0.1:9999/sse?apikey=DElk89iu8Ehhnbu 考据转发后为 http://192.168.1.108:8101/sse2.3 功能考据领先,要确保你的 mcp 处事是不错使用的。如,旁观;http://192.168.1.108:8101/sse 不错取得到驱散。
图片
- 如图,考据得手。咱们不错通过转发的风景进行考据和使用。 - 另外,有了转发和考据,你正本的处事,sse 8101 就毋庸对外了。只好你的网关(nginx)不错旁观即可。这么就不错贬抑权限了。2.4 动态考据那么,现在咱们建设的nginx 转发这不是一个固定的权限账号吗,怎样让不同的接入方齐请求一个秘钥key来使用呢?这里咱们需要使用到 nginx 的 auth 认证模块。
# 不错负载处事upstream backend_servers { server 192.168.1.108:8101;}server { listen 80; server_name 192.168.1.104; # 修改为你的现实处事器 IP 或域名【域名需要备案】 location /sse { auth_request /auth; # 重写URL,去掉apikey参数 rewrite ^(/sse/)\?apikey=.* $1break; proxy_pass http://backend_servers; # 将请求代理到上游处事器组 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; chunked_transfer_encoding off; proxy_buffering off; proxy_cache off; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-Proto $scheme; } location /mcp/message { proxy_pass http://backend_servers; # 将请求代理到上游处事器组 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } location = /auth { # 发送子请求到HTTP处事,考据客户端的左证,复返反应码 internal; # 开荒参数 set $query ''; if ($request_uri ~* "[^\?]+\?(.*)$") { set $query $1; } # 考据得手,复返200 OK proxy_pass http://207.246.123.*:8090/auth/token?$query; # 发送原始请求 proxy_pass_request_body off; # 清空 Content-Type proxy_set_header Content-Type ""; } }在旁观 /sse 的时间,加多 auth 认证,auth 来旁观土产货一个 http 接口。你不错是 SpringBoot 收场的接口。这个接口肃穆考据你的秘钥是否正确。同期你的 SpringBoot 处事还不错提供出一个创建秘钥的平台,让接入方使用。其实近似这么的场景,使费力能愈加丰富的 api 网关齐是自带的,概略 github 一些专门为 mcp 作念网关处事的也齐有。三、增强,学习 rag、mcp、agent小傅哥,仍是为你准备好了一套 AI RAG、MCP、Agent 实施编程课程,使用 Java + Spring AI 框架,增强我方的 AI 行使开荒才调,马上囤积编程妙技,得志各个公司招聘时对AI行使类开荒的要求!如下哪个直播看大秀,课程目次,全程文档小册 + 视频带着你从0到1学习。
第1期 RAG Spring AI 0.8.1 - 完结【更】AI RAG 学问库,形貌先容&需求分析&环境诠释【更】运滚动学问库工程&部署模子&提嘱咐码【更】Ollama DeepSeek 流式打发接口收场【更】Ollama DeepSeek 流式打发页濒临接【更】Ollama RAG 学问库上传、表露和考据【更】Ollama RAG 学问库接口服求收场【更】基于AI器具,联想前端UI和接口对接【更】Git仓库代码库表露到学问库并完善UI对接【更】膨胀OpenAI模子对接,以及齐全AI对接【更】云处事器部署学问库(Docker、Nginx)第2期 MCP Spring AI 1.0.0 - 完结【更】吃上细糠,升级SpringAI框架【更】康庄通衢,上手 AI MCP 使命流【更】谈山学海,收场MCP自动发帖处事(stdio)【更】海纳百川,上线MCP自动发帖处事 本站仅提供存储处事,所有内容均由用户发布,如发现存害或侵权内容,请点击举报。