图片中山塑料挤出机价格中山塑料挤出机价格
作家:小傅哥博客: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 作事转发和考证智商。细心,隔热条PA66生产设备部署的时辰,要把 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自动发帖作事 本站仅提供存储作事,扫数内容均由用户发布,如发现存害或侵权内容,请举报。 相关词条:不锈钢保温施工 塑料管材生产线 钢绞线厂家 玻璃棉板 泡沫板橡塑板专用胶