AI Agent全栈开发MCP实战指南

2026-06-10阅读 0热度 0
ai

先讲几个核心观点:AI应用生态演进至今,提示词优化与Tool Calling已大幅拓展语言模型的能力边界。但工具数量激增、场景复杂度上升后,旧方案开始暴露短板——接口标准不一,模型必须硬编码工具定义。这好比厨房堆满各种制式的厨具,每件都得单独学习操作。好在MCP(模型上下文协议)正好填补了这块空白。

前言

如今,AI应用与外部系统的交互已成常态。我们从最初的提示词工程,逐步过渡到Tool Calling——让模型自主判断是否需要调用工具,以及调用哪个工具。但现实是,随着工具数量膨胀,传统Tool Calling的实现方式面临集中挑战:工具接口格式混乱,模型被迫硬编码工具定义。坦率讲,这些痛点若不解决,每新增一个工具就得修改代码,维护成本直线上升。

MCP正是为收拾这一残局而生。

什么是MCP

MCP(Model Context Protocol)模型上下文协议,核心定位并非替代Tool Calling,而是为Tool Calling搭建一套统一、可扩展的跨平台基础设施。一句话总结:MCP就是Tool Calling的管理中枢

  • Tool Calling:模型决定是否调用工具,调用哪个工具。
  • MCP:规定工具的描述格式、调用方式、结果传递机制。

接入MCP后,AI只需掌握一种通信协议,剩余翻译工作全部交给MCP Server。相当于给所有厨具统一换上标准接口,厨房再混乱也能高效运转。

MCP Java SDK架构

MCP Java SDK提供了Java端的完整实现,支持同步与异步两种通信模式,确保AI模型与工具之间按照标准化流程握手。

  • Client/Server:请求的发起方与接收方,类比顾客与后厨。
  • Session:管理会话生命周期,相当于订单管理系统的核心。
  • Transport:消息传递的底层通道,好比手机订餐加骑手配送。

Transport传输协议

MCP Java SDK支持多种“通信方式”,让AI应用(客户端)能灵活地与各类工具服务(服务器)对话。目前提供三种传输模式:

  1. 基于Stdio的进程间通信传输协议:通过标准输入/输出(stdin和stdout)在进程间传递消息,直接且高效。
  2. 基于Java HttpClient的SSE客户端传输协议:利用Java HttpClient发起HTTP请求,接收服务端持续推送的事件流。
  3. WebFlux SSE客户端传输协议:基于WebFlux非阻塞响应式模型处理SSE流,适用于高并发场景。

MCP Server

MCP Server是协议的服务端实现,对外暴露特定功能。你可以直接访问MCP Server社区查找所需能力——这里聚集了大量技术爱好者,资源丰富。常用社区入口:GitHub MCP Registry、MCP Flow、火山引擎MCP广场。注意,部分服务可能需要注册或申请API Key,请以官方文档为准。

MCP Client

有了服务端,代码里如何调用?答案是MCP Client。它连接开发环境与远程MCP Server。不同客户端对MCP协议的支持程度各异,可根据实际需求选择。

MCP使用

在使用MCP Client前,通常需要先启动一个或多个MCP Server实例。多数MCP Server通过npx或uv命令运行,因此需提前配置好运行环境。以下是一个典型配置,以百度地图MCP Server为例:

{
  "mcpServers": {
    "baidu-map": {
      "command": "npx",
      "args": ["-y", "@baidumap/mcp-server-baidu-map"],
      "env": {
        "BAIDU_MAP_API_KEY": "xxx"
      }
    }
  }
}

配置完成后,在Cursor中可直接看到MCP Server的效果:

除了Cursor这类客户端,也可通过Spring AI代码接入。以Spring AI Alibaba为例,先引入依赖,然后在配置文件中指定MCP Server的地址与超时时间:

spring:
  ai:
    dashscope:
      api-key: ${DASHSCOPE_API_KEY}
    mcp:
      client:
        request-timeout: 60000
        stdio:
          servers-configuration: classpath:/mcp/mcp-servers-config.json

同时,将百度地图配置写入mcp/mcp-servers-config.json

{
  "mcpServers": {
    "baidu-map": {
      "command": "npx.cmd",
      "args": ["-y", "@baidumap/mcp-server-baidu-map"],
      "env": {
        "BAIDU_MAP_API_KEY": "你的Key"
      }
    }
  }
}

然后在Controller中注入ToolCallbackProvider,它会自动将MCP Server的工具注册给AI模型:

@RestController
@RequestMapping("/chat")
public class ChatController {
    private ChatClient chatClient;

    public ChatController(DashScopeChatModel chatModel, ToolCallbackProvider toolCallbackProvider) {
        this.chatClient = ChatClient.builder(chatModel)
                .defaultToolCallbacks(toolCallbackProvider)
                .build();
    }

    @RequestMapping("/generate")
    public String generate(String message) {
        return chatClient.prompt().user(message).call().content();
    }
}

ToolCallbackProvider是Spring AI中用于向AI模型注册可用工具的核心接口。只要MCP配置就位,它就能自动触发调用,完美解决传统Tool Calling中各工具接口不统一的问题,实现动态工具组合。

自定义MCP Server

MCP支持两种通信方式:Stdio与Streamable HTTP。早期版本使用SSE,2025年3月26日协议更新后,官方用更强大的Streamable HTTP取代了SSE(解决了SSE连接易断的痛点)。但为兼容旧版,本文仍保留SSE的实现说明。

使用Stdio自定义MCP Server

先实现一个天气查询服务:

@Service
@Slf4j
public class WeatherService {
    private final Map weatherCache = new ConcurrentHashMap<>();

    public WeatherService() {
        weatherCache.put("北京", new WeatherInfo("晴转多云", "22~28", "南风2级", "78"));
        weatherCache.put("上海", new WeatherInfo("小雨", "18~24", "东风3级", "52"));
        weatherCache.put("广州", new WeatherInfo("晴朗", "25~33", "微风", "45"));
        weatherCache.put("深圳", new WeatherInfo("多云", "24~30", "东北风2级", "60"));
    }

    @Tool(description = "查询指定城市的天气信息,返回天气状况、温度范围、风力、空气质量")
    public String queryWeather(@ToolParam(description = "城市名称,如:北京、上海、广州、深圳") String city) {
        log.info("[HTTP MCP] queryWeather 调用,城市: {}", city);
        if (!weatherCache.containsKey(city)) {
            return String.format("未找到「%s」的天气信息,支持的城市:%s", city, weatherCache.keySet());
        }
        WeatherInfo info = weatherCache.get(city);
        return String.format("""
                ???? %s天气报告
                ─────────────────
                ☁️ 天气:%s
                ????️ 温度:%s°C
                ???? 风力:%s
                ???? AQI:%s
                ─────────────────
                ???? 更新时间:%s
                """, city, info.weather, info.temp, info.wind, info.aqi,
                LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
    }

    record WeatherInfo(String weather, String temp, String wind, String aqi) {}
}

然后通过ToolConfig将其暴露给MCP Server:

@Configuration
public class ToolConfig {
    @Bean
    public ToolCallbackProvider getWeather(WeatherService weatherService) {
        return MethodToolCallbackProvider.builder().toolObjects(weatherService).build();
    }
}

在Stdio模式下,MCP Server是一个独立的命令行应用,无需Web容器。配置如下:

spring:
  ai:
    mcp:
      server:
        name: stdio-server
        version: 0.0.1
  main:
    web-application-type: none
    banner-mode: off

打包成jar后,客户端通过mcp-servers-config.json引用即可:

{
  "mcpServers": {
    "stdio-server": {
      "command": "ja va",
      "args": [
        "-Dfile.encoding=UTF-8",
        "-Dspring.ai.mcp.server.stdio=true",
        "-Dlogging.pattern.console=",
        "-jar",
        "E:/springAI/mcp/mcp-stdio-server/target/mcp-stdio-server-1.0-SNAPSHOT.jar"
      ]
    }
  }
}

启动后,客户端可像调用本地函数一样使用天气查询工具。

使用SSE自定义MCP Server

SSE模式的MCP Server需要运行在Web容器中。注意,不同Starter对应不同角色:

Starter角色被谁调用
spring-ai-starter-mcp-serverMCP Server本地MCP Client(通过Stdio)
spring-ai-starter-mcp-server-webmvcMCP Server远程MCP Client(通过HTTP/SSE)
spring-ai-starter-mcp-server-webfluxMCP Server远程MCP Client(通过HTTP/SSE/WebFlux)
spring-ai-starter-mcp-clientMCP ClientStdio/SSE客户端
spring-ai-starter-mcp-client-webfluxMCP ClientWebFlux客户端

这里有个易踩的坑:如果在Web项目中同时引入spring-boot-starter-webspring-ai-starter-mcp-server-webflux,会导致MCP端点(/sse)失效。原因是两个Servlet/Reactive的Dispatcher共存时,Spring Boot默认优先使用Servlet堆栈。解决方案是在配置文件中明确指定使用Reactive:

server:
  port: 8081
spring:
  ai:
    mcp:
      server:
        name: sse-server
        version: 0.0.1
  main:
    web-application-type: reactive

pom.xml需要包含WebFlux Starter:


    org.springframework.boot
    spring-boot-starter-web


    org.springframework.ai
    spring-ai-starter-mcp-server-webflux


    org.projectlombok
    lombok
    true


    org.springframework.boot
    spring-boot-starter-test
    test

Service与Config的代码与Stdio模式类似,此处不再重复。Service中的@Tool方法与Config中的MethodToolCallbackProvider充当“扫描器”,自动将工具注册给MCP Server。

启动SSE Server后,在Cursor中配置即可直接使用:

{
  "mcpServers": {
    "sse-server": {
      "url": "http://127.0.0.1:8081/sse"
    }
  }
}

若要在Spring AI中作为MCP Client调用SSE Server,Controller里需注入SyncMcpToolCallbackProvider

@RestController
@RequestMapping("/chat")
public class ChatController {
    private final ChatClient chatClient;

    @Autowired
    public ChatController(DashScopeChatModel chatModel,
                          SyncMcpToolCallbackProvider mcpToolProvider) {
        this.chatClient = ChatClient.builder(chatModel)
                .defaultToolCallbacks(mcpToolProvider.getToolCallbacks())
                .build();
    }

    @RequestMapping("/generate")
    public String generate(String message) {
        return chatClient.prompt().user(message).call().content();
    }
}

完结撒花!????

从Tool Calling到MCP,本质上是将“临时拼凑的传话筒”升级为“标准化的服务总线”。MCP的出现大幅降低了AI应用与工具之间的耦合度,未来你只需专注业务逻辑,通信细节全交给协议处理。希望本文能帮你理清MCP的来龙去脉,下次写代码时,不妨亲手搭一个自定义MCP Server体验一下。

免责声明

本网站新闻资讯均来自公开渠道,力求准确但不保证绝对无误,内容观点仅代表作者本人,与本站无关。若涉及侵权,请联系我们处理。本站保留对声明的修改权,最终解释权归本站所有。

相关阅读

更多
欢迎回来 登录或注册后,可保存提示词和历史记录
登录后可同步收藏、历史记录和常用模板
注册即表示同意服务条款与隐私政策