SpringAIAlibaba整合 Streamable HTTP 调用免费 MCP Server 实战全解

场景

SpringBoot中使用SpringAIAlibaba框架集成阿里云百炼实现AI快速对话入门示例:

https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/160024361

SpringBoot+LangChain4j+Ollama+MCP实现智能天气工具调用示例:

https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/160884392

上述示例中使用LangChain4j调用mcpserver的示例demo,使用本地模拟的mcp server,

下面介绍更快速的使用Spring AI Alibaba 整合 Streamable HTTP 调用免费 MCP Server 实战。

MCP(Model Context Protocol)是 Anthropic 推出的模型上下文协议,旨在为 AI 模型提供统一的外部工具调用接口。

在实际项目开发中,我们常常需要让大语言模型(LLM)动态发现并调用第三方服务,

例如高德地图、Hacker News 等。

本文将详细记录从理论到实践的过程:

基于 Spring AI Alibaba 框架,采用 Streamable HTTP 模式连接免费的第三方 MCP Server,

并在 Spring Boot 应用中完成工具的自动注册与调用。文中将完整呈现项目搭建、依赖配置、常见错误排查及背后的协议知识。

MCP 协议与传输模式

MCP 规范定义了多种传输方式,主要演进路线为:

SSE (Server-Sent Events):

早期主流方式,客户端通过长连接接收服务端推送。缺点是无法断线续传且需要维持连接,现已被逐步弃用。

Streamable HTTP:

MCP 2025-03-26 版本新引入的传输模式。统一了请求端点,支持无状态请求和可选的 SSE 流,天然适配云原生和负载均衡。

Spring AI 从 1.1.2 版本开始通过 spring-ai-starter-mcp-client 全面支持 Streamable HTTP,并可同时兼容 STDIO(本地进程)和 SSE。

关键术语

MCP Server:提供工具的远端服务,如高德地图 MCP Server。

MCP Client:集成在 AI 应用中的客户端,负责发现并调用远程工具。

ToolCallbackProvider:Spring AI 中用于将 MCP 工具回调注入到 ChatClient 的接口。

技术选型

Spring Boot: 3.4.5

Spring AI: 1.1.2

Spring AI Alibaba: 1.1.2.0 (DashScope 大模型)

MCP Server: 免费且无需 API Key 的 Hacker News MCP Server (https://hn.caseyjhand.com )

注:

博客:
https://blog.csdn.net/badao_liumang_qizhi

实现

核心依赖 pom.xml

复制代码
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.4.5</version>
    </parent>

    <groupId>com.badao</groupId>
    <artifactId>spring-ai-alibaba-mcp-third-news</artifactId>
    <version>1.0.0</version>

    <properties>
        <java.version>17</java.version>
        <maven.compiler.release>17</maven.compiler.release>
        <spring-ai-alibaba.version>1.1.2.0</spring-ai-alibaba.version>
        <spring-ai.version>1.1.2</spring-ai.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.ai</groupId>
                <artifactId>spring-ai-bom</artifactId>
                <version>${spring-ai.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <!-- Spring Boot Web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- Spring AI Alibaba DashScope 大模型 -->
        <dependency>
            <groupId>com.alibaba.cloud.ai</groupId>
            <artifactId>spring-ai-alibaba-starter-dashscope</artifactId>
            <version>${spring-ai-alibaba.version}</version>
        </dependency>

        <!-- Spring AI MCP 客户端 -->
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-starter-mcp-client</artifactId>
        </dependency>
    </dependencies>

    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
        </repository>
        <repository>
            <id>aliyun</id>
            <name>Aliyun Maven</name>
            <url>https://maven.aliyun.com/repository/public</url>
        </repository>
    </repositories>

通过 dependencyManagement 引入 spring-ai-bom:1.1.2 统一版本管理。

配置 Streamable HTTP 连接

在 application.yml 中声明要连接的远程 MCP Server:

复制代码
​
server:
  port: 8082

spring:
  ai:
    dashscope:
      api-key: ${DASHSCOPE_API_KEY}
    mcp:
      client:
        enabled: true
        request-timeout: 30s
        toolcallback:
          enabled: true
        streamable-http:
          connections:
            hacker-news:                    # 连接名称(可自定义)
              url: https://hn.caseyjhand.com   # Hacker News MCP 服务地址

logging:
  level:
    org.springframework.ai.mcp: DEBUG
    org.springframework.ai.chat.client: DEBUG

​

注意:

connections 下的名称(如 hacker-news)将作为该 MCP Server 的唯一标识。

无需手动创建 Transport Bean,Spring AI 会自动根据配置构建 HttpClientSseClientTransport 并完成连接。

对于需要 API Key 的服务(如高德),可通过额外的 api-key 或 headers 参数配置,但本示例中的 Hacker News 服务完全免费,无需认证。

工具注册配置类

复制代码
package com.badao.ai.config;

import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.tool.ToolCallbackProvider;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AiConfig {

    @Bean
    public ChatClient chatClient(ChatClient.Builder chatClientBuilder,
                                 ToolCallbackProvider toolCallbackProvider) {
        return chatClientBuilder
                // ✅ 关键:必须使用 .defaultToolCallbacks() 而不是 .defaultTools()
                .defaultToolCallbacks(toolCallbackProvider.getToolCallbacks())
                .build();
    }
}

关键点:

必须使用 .defaultToolCallbacks() 而非 .defaultTools(),因为 ToolCallbackProvider 提供的是 ToolCallback 列表,

而不是标有 @Tool 注解的方法

服务层

复制代码
package com.badao.ai.service;

import org.springframework.ai.chat.client.ChatClient;
import org.springframework.stereotype.Service;

@Service
public class AiService {
   
    private final ChatClient chatClient;
   
    public AiService(ChatClient chatClient) {
        this.chatClient = chatClient;
    }
   
    public String chat(String userMessage) {
        return chatClient.prompt()
                .user(userMessage)
                .call()
                .content();
    }
}

控制器

复制代码
package com.badao.ai.controller;

import com.badao.ai.service.AiService;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api")
public class AiController {

    private final AiService aiService;

    public AiController(AiService aiService) {
        this.aiService = aiService;
    }

    @PostMapping("/chat")
    public ChatResponse chat(@RequestBody ChatRequest request) {
        String result = aiService.chat(request.message());
        return new ChatResponse(200, "success", result);
    }

    public record ChatRequest(String message) {}
    public record ChatResponse(int code, String msg, String data) {}
}

运行与测试

启动前准备

JDK 17+

设置环境变量 DASHSCOPE_API_KEY 为你的百炼 API Key。

无需安装任何本地 MCP Server 进程,远程服务已部署。

测试接口

复制代码
​
curl -X POST http://localhost:8082/api/chat \
  -H "Content-Type: application/json" \
  -d '{"message": "What are the top stories on Hacker News right now?"}'

​

AI 将自动调用 Hacker News MCP 工具获取热门文章,并以自然语言返回结果。

遇到的典型错误及解决方案

错误1:

No @Tool annotated methods found ... use .toolCallbacks()

原因:

在 ChatClient 构建时使用了 .defaultTools(toolCallbackProvider),而 ToolCallbackProvider 不是 @Tool 注解的类。

解决:

改为 .defaultToolCallbacks(toolCallbackProvider.getToolCallbacks())。

错误2:

HttpClientSseClientTransport 构造函数访问限制

尝试手动创建 new HttpClientSseClientTransport(url) 时报错 is not public。

解决:

不要手动实例化 Transport,Spring AI 会根据 YAML 配置自动创建。

如果必须手动配置(如需要自定义请求头),应使用 NamedClientMcpTransport 包装,并确保 application.yml 中连接名称与之对应。

错误3:

Cannot resolve symbol 'StreamableHttpMcpTransport'

在使用旧版 LangChain4j 时,该类不存在。迁移到 Spring AI 后自然解决。

错误4:

api-key 属性不被识别

McpStreamableHttpClientProperties 不支持直接配置 api-key。

对于需要认证的服务,应使用请求头注入或通过 URL 参数传递(如 /sse?key=xxx),或在 YAML 中使用 headers 字段。

知识点总结

Streamable HTTP vs SSE:新项目优先选用 Streamable HTTP,更简洁、无状态、易于扩展。

工具自动发现:Spring AI MCP Client 通过自动配置读取 YAML 中的连接列表,调用 MCP 协议的 tools/list 方法获取远程能力。

ToolCallbackProvider 与 ToolCallback:前者是工厂,后者是具体的工具执行体,注册时需使用 defaultToolCallbacks() 方法。

免费 MCP Server 生态:

可前往 PulseMCP

https://www.pulsemcp.com/

mcp.so

https://mcp.so/

发现大量免费服务,覆盖新闻、天气、区块链、地图等。

故障排查技巧:开启 logging.level.org.springframework.ai.mcp=DEBUG 可观察完整的协议交互过程。

相关推荐
Lust Dusk1 小时前
移动安全资产--MobSF工具搭建教程
网络·安全·web安全·安全架构
сокол1 小时前
【网安-Web渗透测试-内网渗透】局域网ARP攻击与DNS劫持
服务器·网络·网络安全
想唱rap1 小时前
传输层协议TCP
linux·运维·服务器·网络·c++·tcp/ip
winlife_2 小时前
在 Unity Editor 里跑 HTTP MCP server:主线程边界与请求 marshal 的实现要点
http·unity·游戏引擎·多线程·mcp
许彰午2 小时前
政务远程帮办部署踩坑实录——从互联网到政务外网
开发语言·网络·政务
一只小白0003 小时前
一篇讲清TCP的三次握手&四次挥手
服务器·网络·tcp/ip
tang777893 小时前
2026年国内代理IP服务商横向测评:企业级爬虫如何选型?
运维·服务器·网络·爬虫·python·代理
上海云盾-小余3 小时前
网站木马植入原理与彻底清除、长效防御方案
网络·网络协议·tcp/ip·系统安全
Be reborn3 小时前
用 Playwright 做自动化测试:如何验证网络请求并做断言
网络·python·自动化·pytest