一、MCP 介绍
MCP(Model Context Protocol,即模型上下文协议)是由 Anthropic(Claude 的母公司)于 2024年11月 开源发布。MCP 可帮助大模型使用外部工具与数据,相比 Function Calling,MCP 更灵活且易于使用。
MCP 是一种开放协议,它标准化了应用程序如何向大模型提供上下文的方式。它本身并不提供什么服务,只是定义好了一套规范,让服务提供者和服务使用者去遵守。
MCP 就是对以前的 Function Calling 进行标准化,早期大模型支持 FunctionCall 都是自家按照自己的路线走,导致不能用,自己家有自己家的标准,导致对接多家 Function Calling 模型麻烦,Claude 发布了 MCP 协议,类似于 jdbc 标准,大家都按照统一的协议进行传输,大家一起开发 MCP 服务供大家使用。
MCP采用JSON-RPC 2.0作为消息格式,支持主要的传输方式:
- 标准输入输出(stdio):STDIO方式是基于进程间通信,MCP Client和MCP Server运行在同一主机,适用本地 MCP 客户端/IDE 接入、命令行工具以及简单的进程间通信场景。依赖:spring-ai-starter-mcp-server
- SSE 流式传输:SSE方式是基于HTTP协议,MCP Client远程调用MCP Server提供的SSE服务。实现客户端和服务端远程通信。依赖:spring-ai-starter-mcp-server-webflux
- Streamable HTTP 传输:。依赖:spring-ai-starter-mcp-server-webmvc
stdio、SSE、Streamable HTTP 的区别
stdio
- 本地进程通信
- 适合 IDE 直接拉起本地 MCP Server
- 最常见于本地工具接入
SSE
- 早期/过渡型的 HTTP 流式方案
- 能让服务端持续推送事件
- 但通信模型相对没那么统一,工程上会稍显别扭
Streamable HTTP
- 现在更推荐
- 也是 HTTP 方案,但比 SSE 方式更适合 MCP 的现代实现
- 很多新版本客户端/服务端都更偏向它
MCP 核心概念
很多同学以为 MCP 协议就只能提供工具给别人调用,但实际上,MCP 协议的本领可大着呢!按照官方的说法,总共有 6 大核心概念:
- Resources 资源:让服务端向客户端提供各种数据,比如文本、文件、数据库记录、API 响应等,客户端可以决定什么时候使用这些资源。使 AI 能够访问最新信息和外部知识,为模型提供更丰富的上下文。
- Prompts 提示词:服务端可以定义可复用的提示词模板和工作流,供客户端和用户直接使用。它的作用是标准化常见的 AI 交互模式,比如能作为 UI 元素(如斜杠命令、快捷操作)呈现给用户,从而简化用户与 LLM 的交互过程。
- Tools 工具:MCP 中最实用的特性,服务端可以提供给客户端可调用的函数,使 AI 模型能够执行计算、查询信息或者和外部系统交互,极大扩展了 AI 的能力范围。
- Sampling 采样:允许服务端通过客户端向大模型发送生成内容的请求(反向请求)。使 MCP 服务能够实现复杂的智能代理行为,同时保持用户对整个过程的控制和数据隐私保护。
- Roots 根目录:MCP 协议的安全机制,定义了服务器可以访问的文件系统位置,限制访问范围,为 - MCP 服务提供安全边界,防止恶意文件访问。
- Transports 传输:定义客户端和服务器间的通信方式,包括 Stdio(本地进程间通信)和 SSE(网络实时通信),确保不同环境下的可靠信息交换。
MCP 服务市场
目前已经有很多 MCP 服务市场,开发者可以在这些平台上找到各种现成的 MCP 服务:
- MCP.so:较为主流,提供丰富的 MCP 服务目录
- GitHub Awesome MCP Servers:开源 MCP 服务集合
- 阿里云百炼 MCP 服务市场
- Spring AI Alibaba 的 MCP 服务市场
- Glama.ai MCP 服务
二、工程搭建:基于 Spring Boot 的后端开发
2.1 创建Maven工程
使用IntelliJ IDEA创建一个Maven工程,完成工程初始化。
2.2 引入核心 pom 依赖
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.4.13</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>org.devpotato</groupId>
<artifactId>java-mcp-server-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<name>java-mcp-server-demo</name>
<description>Minimal Java MCP Server demo based on Spring AI</description>
<packaging>jar</packaging>
<properties>
<java.version>17</java.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring-ai.version>1.1.4</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 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- MCP Server(STDIO 模式) -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-server</artifactId>
</dependency>
<!-- MCP Server(Streamable HTTP 模式) -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-server-webmvc</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<release>${java.version}</release>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.2.5</version>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2.3 工程配置文件
在src/main/resources目录下创建application.yml文件
spring:
application:
name: java-mcp-server-demo
profiles:
active: http
ai:
mcp:
server:
name: java-mcp-server-demo # 服务名
version: 0.0.1 # 版本号
type: SYNC
instructions: |
This server provides demo tools for Java MCP development.
Use getCityTime for timezone lookup, sumNumbers for calculation,
and projectSummary for quick project scaffolding summaries.
application-http.yml文件
spring:
config:
activate:
on-profile: http
main:
web-application-type: servlet # 启用Web
ai:
mcp:
server:
protocol: STREAMABLE
streamable-http:
mcp-endpoint: /mcp
server:
port: 8080
application-stdio.yml文件
spring:
config:
activate:
on-profile: stdio
main:
web-application-type: none # STDIO必须禁用web应用类型
banner-mode: off # STDIO禁用banner
ai:
mcp:
server:
stdio: true # 启用stdio模式
2.4 MCP工具类
import org.springframework.ai.tool.annotation.ToolParam;
import org.springframework.stereotype.Service;
/**
* 天气服务
* MCP 核心是暴露工具(Tool),供 AI 客户端调用
* @Tool:标记方法为 MCP 工具,description描述工具功能(AI 理解用)
* @ToolParam:标记参数,description描述参数含义
* 方法返回值:支持String、Map、List、自定义对象等
* 支持同步 / 异步:异步返回Mono/Flux(Reactor)
*/
@Service
public class WeatherService {
/**
* 根据城市查询天气(MCP工具)
*
* @param city 城市名
* @return 天气信息
*/
@Tool(name = "getWeather", description = "根据城市名称获取天气信息")
public String getWeather(@ToolParam(description = "城市名称", required = true) String city) {
// 业务逻辑:调用天气 API
return "城市: " + city + ", 温度: 25°C, 天气: 晴";
}
/**
* 根据经纬度查询天气(MCP工具)
*
* @param latitude 纬度
* @param longitude 经度
* @return 天气信息
*/
@Tool(name = "getWeatherByLocation", description = "根据经纬度获取天气预报")
public String getWeatherByLocation(
@ToolParam(description = "纬度") double latitude,
@ToolParam(description = "经度") double longitude) {
return "纬度: " + latitude + ", 经度: " + longitude + ", 温度: 22°C";
}
}
2.5 工具配置类
package org.devpotato.config;
import org.devpotato.mcp.WeatherService;
import org.springframework.ai.tool.ToolCallbackProvider;
import org.springframework.ai.tool.method.MethodToolCallbackProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 将 WeatherService 中的 @Tool 方法注册为 MCP 工具
*/
@Configuration
public class ToolRegistrationConfiguration {
@Autowired
private WeatherService weatherService;
@Bean
public ToolCallbackProvider toolCallbackProvider() {
return MethodToolCallbackProvider.builder()
.toolObjects(new Object[]{weatherService})
.build();
}
}
2.6 启动类开发
package org.devpotato;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.function.context.config.ContextFunctionCatalogAutoConfiguration;
@SpringBootApplication(exclude = {
ContextFunctionCatalogAutoConfiguration.class
})
public class StartServer {
public static void main(String[] args) {
SpringApplication.run(StartServer.class, args);
System.out.println(">>> start");
}
}
三、运行测试
3.1 使用 Postman 测试
创建一个 MCP 请求
点击右侧 Connect 按钮,查看 MCP 工具列表
发起 MCP 请求
3.2 使用 Cursor 接入本地 MCP Server
Cursor 是一款 AI 编辑器和编码智能体。用它来理解你的代码库、规划和构建功能、修复错误、审查更改,以及配合你已在使用的工具工作。
打开 Cursor -> Settings -> Tools & MCPs -> New MCP Server
填入相关信息
在聊天中使用 MCP
智能体会在相关时自动使用 Available Tools 下列出的 MCP 工具。你可以直接说出特定工具的名称,或描述你的需求。也可以在设置中启用或禁用工具。
工具批准 默认情况下,智能体在使用 MCP 工具前会请求批准。点击工具名称旁的箭头可查看参数。
自动运行 启用自动运行后,智能体无需询问即可使用 MCP 工具。其工作方式与终端命令类似。有关自动运行设置的更多信息,请参阅此处。
如需预先配置哪些 MCP 工具可在不通过设置 UI 的情况下自动运行,请将它们添加到
~/.cursor/permissions.json