MCP服务开发实战应用
MCP协议为AI助手与外部服务之间提供了标准化的通信方式
01 MCP服务核心概念解析
MCP(Model Context Protocol)即模型上下文协议,是连接AI助手与外部服务的标准化通信协议。简单来说,它就像是为AI助手打造的"USB接口",让不同的AI系统能够无缝调用你开发的工具服务。
MCP协议的核心价值在于解决了AI模型与外部功能模块的通信难题。在传统开发模式中,每个AI 助手都有自己独特的工具调用方式,开发者需要为不同平台重复开发功能类似的接口。而MCP协议通过统一的通信标准,实现了"一次开发,多端适配"的目标。
当前MCP协议主要支持三大核心能力:
-
工具调用(Tools):让AI能够调用外部功能模块,如本文将实现的双色球号码生成工具
-
资源管理(Resources):支持AI对文件、数据等资源的访问与操作
-
提示词管理(Prompts):允许AI获取预定义的提示词模板,优化回答质量
MCP协议采用Streamable HTTP传输机制作为主要通信方式,这是一种基于HTTP的增强型服务器推送技术,能够实现AI助手与MCP服务之间的实时双向通信。2025-06-18最新版MCP协议新增了多项重要特性,包括结构化输出(outputSchema字段)、OAuth 2.1认证、Streamable HTTP传输(替代SSE)和工具注解(annotations)等功能,进一步提升了协议的安全性和交互能力。
02 MCP服务开发环境准备
开发MCP服务需要以下环境支持:
基础环境要求
-
JDK 17及以上:MCP SDK基于Java 17开发,低版本JDK可能导致兼容性问题
-
Maven 3.6及以上:用于项目构建和依赖管理
-
开发工具:推荐使用IntelliJ IDEA或VS Code,需安装Java插件和Maven插件
-
网络环境:需要联网下载MCP SDK及相关依赖
环境验证命令
安装完成后,可通过以下命令验证环境是否准备就绪:
# 验证JDK版本
java -version # 应显示17.0.x或更高版本
# 验证Maven版本
mvn -version # 应显示3.6.x或更高版本
03 MCP服务完整开发流程
1. 项目搭建
方式一:从零创建Spring Boot项目
-
使用Spring Initializr创建新项目访问 Spring Initializr
-
选择Spring Boot 3.1.x版本
-
添加"Spring Web"依赖
-
生成项目并导入IDE
-
添加MCP SDK依赖
打开pom.xml文件,添加以下MCP相关依赖:
<!-- MCP核心SDK (2025-06-18最新版) -->
<dependency>
<groupId>io.modelcontextprotocol.sdk</groupId>
<artifactId>mcp</artifactId>
<version>2.0.0</version>
</dependency>
<!-- MCP与Spring Web集成 (支持Streamable HTTP) -->
<dependency>
<groupId>io.modelcontextprotocol.sdk</groupId>
<artifactId>mcp-spring-web</artifactId>
<version>2.0.0</version>
</dependency>
<!-- MCP安全认证模块 -->
<dependency>
<groupId>io.modelcontextprotocol.sdk</groupId>
<artifactId>mcp-security</artifactId>
<version>2.0.0</version>
</dependency>
方式二:使用官方示例项目(推荐新手)
如果是初次接触MCP开发,推荐直接克隆官方示例项目:
# 克隆项目
git clone https://github.com/beilingai/simple-mcp-server.git
cd simple-mcp-server
# 查看项目结构
tree -L 2 # 确保已安装tree命令,或手动在IDE中查看
项目主要结构如下:
simple-mcp-server/
src/
├── main/
│ ├── java/com/example/mcp/
│ └── resources/
└── test/
pom.xml
README.md
2. 核心配置实现
创建MCP配置类McpConfig.java,这是MCP服务的核心配置:
package com.example.mcp.config;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.modelcontextprotocol.sdk.spring.web.StreamableHttpTransportProvider;
import io.modelcontextprotocol.sdk.security.OAuth2Config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.server.RouterFunction;
@Configuration
public class McpConfig {
/**
* @param mapper JSON序列化/反序列化工具
* @return StreamableHttpTransportProvider实例
* 创建MCP传输提供者,使用Streamable HTTP传输机制(替代SSE)
*/
@Bean
public StreamableHttpTransportProvider streamableHttpTransportProvider(ObjectMapper mapper) {
// 配置OAuth 2.1认证
OAuth2Config oauthConfig = OAuth2Config.builder()
.clientId("your-client-id")
.clientSecret("your-client-secret")
.tokenEndpoint("https://auth.modelcontextprotocol.io/token")
.build();
// "/mcp/message"是MCP服务的通信端点,使用Streamable HTTP传输
return new StreamableHttpTransportProvider(mapper, "/mcp/message")
.withOAuth2Config(oauthConfig);
}
/**
* @param transportProvider 传输提供者实例
* @return RouterFunction实例
* 注册MCP路由函数,将MCP端点添加到Spring Web路由中
*/
@Bean
public RouterFunction<?> mcpRouterFunction(StreamableHttpTransportProvider transportProvider) {
return transportProvider.getRouterFunction();
}
}
3. MCP服务器创建与启动
创建McpServerApplication.java作为应用入口:
package com.example.mcp;
import com.example.mcp.config.McpConfig;
import com.example.mcp.tools.DoubleColorBallTool;
import io.modelcontextprotocol.sdk.McpServer;
import io.modelcontextprotocol.sdk.spring.web.StreamableHttpTransportProvider;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication(scanBasePackageClasses = {McpApplication.class, McpConfig.class})
public class McpApplication {
public static void main(String[] args) {
// 启动Spring Boot应用
ConfigurableApplicationContext context = SpringApplication.run(McpApplication.class, args);
// 获取Streamable HTTP传输提供者实例
StreamableHttpTransportProvider transportProvider =
context.getBean(StreamableHttpTransportProvider.class);
// 创建MCP同步服务器,使用Streamable HTTP传输
var server = McpServer.sync(transportProvider)
// 设置服务基本信息(名称和版本)
.serverInfo("double-color-ball-mcp-server", "2.0.0")
// 配置服务能力,支持结构化输出
.capabilities(io.modelcontextprotocol.sdk.schema.McpSchema.ServerCapabilities.builder()
.tools(true) // 支持工具调用
.resources(true, true) // 支持资源的读取和写入
.prompts(true) // 支持提示词管理
.logging() // 启用日志功能
.structuredOutput(true) // 启用结构化输出
.build())
.build();
// 注册自定义工具(双色球号码生成工具)
server.addTool(new DoubleColorBallTool().getSpecification());
System.out.println("MCP服务启动成功!服务名称: double-color-ball-mcp-server v2.0.0");
System.out.println("通信端点: http://localhost:8080/mcp/message (Streamable HTTP)");
}
}
4. 核心工具实现
创建DoubleColorBallTool.java,实现双色球号码生成工具:
package com.example.mcp.tools;
import io.modelcontextprotocol.sdk.McpServerFeatures;
import io.modelcontextprotocol.sdk.schema.McpSchema;
import io.modelcontextprotocol.sdk.annotations.ToolAnnotation;
import io.modelcontextprotocol.sdk.annotations.RiskLevel;
import io.modelcontextprotocol.sdk.annotations.PrivacyImpact;
import org.springframework.stereotype.Component;
import java.util.*;
import java.util.stream.Collectors;
@Component
public class DoubleColorBallTool {
/**
* 创建双色球号码生成工具规范
* @return SyncToolSpecification工具规范对象
*/
@ToolAnnotation(
riskLevel = RiskLevel.LOW,
privacyImpact = PrivacyImpact.NONE,
description = "生成随机双色球号码,无隐私数据处理",
complianceRequirements = {"GDPR-COMPLIANT", "CCPA-COMPLIANT"}
)
public McpServerFeatures.SyncToolSpecification getSpecification() {
// 1. 定义工具元数据(名称、描述和参数 schema)
String toolName = "double-color-ball-numbers";
String description = "生成真实随机的双色球号码,包含6个红球(1-33)和1个蓝球(1-16)";
// 参数schema定义(使用JSON Schema格式)
String schema = "{\n" +
" \"type\": \"object\",\n" +
" \"properties\": {\n" +
" \"count\": {\n" +
" \"type\": \"integer\",\n" +
" \"description\": \"生成的组数,默认1组,最多5组\",\n" +
" \"minimum\": 1,\n" +
" \"maximum\": 5,\n" +
" \"default\": 1\n" +
" }\n" +
" }\n" +
"}";
// 2025-06-18新增:结构化输出定义
String outputSchema = "{\n" +
" \"type\": \"object\",\n" +
" \"properties\": {\n" +
" \"groups\": {\n" +
" \"type\": \"array\",\n" +
" \"items\": {\n" +
" \"type\": \"object\",\n" +
" \"properties\": {\n" +
" \"redBalls\": {\n" +
" \"type\": \"array\",\n" +
" \"items\": {\"type\": \"integer\"},\n" +
" \"minItems\": 6,\n" +
" \"maxItems\": 6\n" +
" },\n" +
" \"blueBall\": {\"type\": \"integer\"}\n" +
" },\n" +
" \"required\": [\"redBalls\", \"blueBall\"]\n" +
" }\n" +
" },\n" +
" \"disclaimer\": {\"type\": \"string\"}\n" +
" },\n" +
" \"required\": [\"groups\", \"disclaimer\"]\n" +
"}";
// 2. 实现工具调用逻辑
McpServerFeatures.SyncToolCallHandler handler = (exchange, arguments) -> {
// 解析参数(获取要生成的组数)
int count = arguments.get("count") != null ? Integer.parseInt(arguments.get("count").toString()) : 1;
// 确保组数在有效范围内
count = Math.min(Math.max(count, 1), 5);
// 生成双色球号码内容(结构化数据)
Map<String, Object> result = generateStructuredResult(count);
// 返回结果,包含结构化输出
return new McpSchema.CallToolResult(
Collections.singletonList(new McpSchema.TextContent(
"您的双色球号码已生成:\n\n" + formatResultForDisplay(result)
)),
outputSchema, // 2025新增:结构化输出schema
false, // 是否为最终结果
result // 2025新增:结构化输出数据
);
};
// 创建并返回工具规范
return new McpServerFeatures.SyncToolSpecification(
new McpSchema.Tool(toolName, description, schema, outputSchema), // 添加outputSchema参数
handler
);
}
/**
* 生成结构化结果数据
*/
private Map<String, Object> generateStructuredResult(int count) {
Map<String, Object> result = new HashMap<>();
List<Map<String, Object>> groups = new ArrayList<>();
for (int i = 0; i < count; i++) {
Map<String, Object> group = new HashMap<>();
group.put("redBalls", generateRedBalls());
group.put("blueBall", generateBlueBall());
groups.add(group);
}
result.put("groups", groups);
result.put("disclaimer", "💡 温馨提示:彩票号码随机生成,仅供娱乐,不代表中奖预测!");
return result;
}
/**
* 格式化结构化结果为显示文本
*/
private String formatResultForDisplay(Map<String, Object> result) {
StringBuilder sb = new StringBuilder();
List<Map<String, Object>> groups = (List<Map<String, Object>>) result.get("groups");
for (int i = 0; i < groups.size(); i++) {
Map<String, Object> group = groups.get(i);
List<Integer> redBalls = (List<Integer>) group.get("redBalls");
int blueBall = (int) group.get("blueBall");
sb.append(String.format("第 %d 组:\n", i + 1));
sb.append("红球:").append(formatNumbers(redBalls)).append("\n");
sb.append("蓝球:").append(String.format("%02d", blueBall)).append("\n\n");
}
sb.append(result.get("disclaimer"));
return sb.toString();
}
/**
* 生成6个不重复的红球号码(1-33)
*/
private List<Integer> generateRedBalls() {
Set<Integer> balls = new HashSet<>();
Random random = new Random();
while (balls.size() < 6) {
// 生成1-33之间的随机数
int ball = random.nextInt(33) + 1;
balls.add(ball);
}
// 排序并返回
return balls.stream().sorted().collect(Collectors.toList());
}
/**
* 生成1个蓝球号码(1-16)
*/
private int generateBlueBall() {
return new Random().nextInt(16) + 1;
}
/**
* 格式化号码列表,补零并添加分隔符
*/
private String formatNumbers(List<Integer> numbers) {
return numbers.stream()
.map(num -> String.format("%02d", num))
.collect(Collectors.joining(" "));
}
}
5. 项目编译与运行
# 编译项目
mvn clean package -Dmaven.test.skip=true
# 运行服务
java -jar target/mcp-server-1.0-SNAPSHOT.jar
服务启动成功后,将显示类似以下信息:
_| |_\__, |
==============|___/=/_/_/_/ / / / /
:: Spring Boot :: (v3.1.3)
(v3.1.3)
com.example.mcp. McpApplication main]
main] com.example.mcp. McpApplication
2023-10-15 14:30:00.123 INFO 12345 --- [ main] com.example.mcp.McpApplication : Starting McpApplication using Java 17.0.8 with PID 12345
2023-10-15 14:30:01.456 INFO 12345 --- [ main] com.example.mcp.McpApplication : Started McpApplication in 2.345 seconds (process running for 2.678)
MCP服务启动成功!服务名称: double-color-ball-mcp-server v1.0.0
通信端点: http://localhost:8080/mcp/message
04 MCP服务注册与配置方法
服务配置详解
MCP服务的核心配置主要集中在两个方面:服务能力配置和通信端点配置。
1. 服务能力配置
在创建MCP服务器时,通过capabilities()方法配置服务支持的功能:
.capabilities(McpSchema.ServerCapabilities.builder()
.logging() // 是否启用日志功能
.tools(true) // 是否支持工具调用
.resources(true, true) // 是否支持资源读取和写入
.prompts(true) // 是否支持提示词管理
.build())
各参数说明:
-
tools(true):启用工具调用功能,必须设置为true才能让AI调用我们开发的双色球工具
-
resources(readable, writable):设置是否支持资源的读取和写入
-
prompts(true):启用提示词管理功能,允许AI获取预定义的提示词模板
-
logging():启用日志功能,记录MCP服务的通信过程
2. 通信端点配置
通信端点在WebMvcSseServerTransportProvider的构造函数中配置:
@Bean
WebMvcSseServerTransportProvider webMvcSseServerTransportProvider(ObjectMapper mapper) {
// 配置SSE通信端点为"/mcp/message"
return new WebMvcSseServerTransportProvider(mapper, "/mcp/message");
}
此配置将MCP服务的通信端点设置为http://localhost:8080/mcp/message,AI助手将通过该端点与MCP服务进行通信。
工具注册方法
MCP服务支持注册多个工具,每个工具通过addTool()方法注册:
// 注册单个工具
server.addTool(new DoubleColorBallTool().getSpecification());
// server.addTool(new WeatherTool().getSpecification());
// server.addTool(new CalculatorTool().getSpecification());
// 如果有多个工具,可以多次调用addTool()
每个工具都需要实现SyncToolSpecification接口,提供工具的元数据和调用逻辑。
05 MCP服务多场景调用示例
场景一:在Cherry Studio中调用MCP服务
Cherry Studio是一款支持MCP协议的AI助手,以下是调用步骤:
-
安装Cherry Studio
参考官方教程安装Cherry Studio:Cherry Studio 下载和安装教程 -
配置MCP服务器
打开Cherry Studio,进入设置页面,找到"MCP服务"配置项,添加MCP服务器:服务器名称:double-color-ball-mcp-server(可自定义) -
服务器URL:http://localhost:8080/mcp/message
-
调用MCP工具
在Cherry Studio的聊天窗口中输入:请帮我生成3组双色球号码Cherry Studio会自动识别需要调用MCP工具,并显示类似以下结果:您的双色球号码已生成: 第 1 组: 红球:05 12 18 23 29 32 蓝球:08 第 2 组: 红球:03 09 15 22 27 31 蓝球:04 第 3 组: 红球:07 14 20 25 30 33 蓝球:11 温馨提示:彩票号码随机生成,仅供娱乐,不代表中奖预测!
场景二:在Cursor中调用MCP服务
Cursor是一款基于GPT的代码编辑器,也支持通过配置调用MCP服务:
-
配置MCP服务器
打开Cursor,进入设置页面(Settings),找到"MCP Servers"配置项,添加以下JSON配置:{ "mcpServers": { "double-color-ball-mcp-server": { "url": "http://localhost:8080/mcp/message" } } }如果需要配置多个MCP服务器,可以在mcpServers对象中添加多个键值对,用逗号分隔。 -
调用MCP工具
在Cursor的聊天窗口中输入:请调用double-color-ball-mcp-server服务,帮我生成2组双色球号码选择"Agent"模式,Cursor会调用我们的MCP服务,并返回生成的双色球号码。
场景三:使用curl命令测试MCP服务
除了通过AI助手,我们还可以使用curl命令直接测试MCP服务:
# 测试MCP服务是否正常运行
curl http://localhost:8080/mcp/message
正常情况下,会返回一个持续连接的SSE流,表明MCP服务正在运行。
06 MCP协议的应用价值分析
-
打破AI生态壁垒
MCP协议最大的价值在于打破了不同AI助手之间的生态壁垒。传统开发模式中,每个AI平台(如 ChatGPT、Claude、文心一言等)都有自己独特的工具调用方式,开发者需要为不同平台重复开发功能类似的接口。而基于MCP协议开发的服务,可以被所有支持MCP协议的AI助手调用,实现了"一次开发,多端适配",极大降低了开发成本。 -
提升AI助手能力边界
MCP协议让AI助手能够轻松扩展各种专业能力:实时数据获取:如天气查询、股票行情、新闻资讯等 -
专业计算能力:如科学计算、数据分析、工程模拟等
-
业务系统集成:如CRM查询、订单管理、库存查询等
-
创意生成工具:如图片生成、文案创作、代码生成等
-
保护数据隐私与安全
MCP服务运行在开发者自己的服务器上,所有数据处理都在本地完成,避免了敏感数据上传到第三方AI平台的风险。这对于企业级应用尤为重要,能够满足数据合规和隐私保护的要求。 -
标准化的通信接口
MCP协议定义了标准化的通信接口,包括:工具元数据描述格式 -
请求/响应数据结构
-
错误处理机制
-
日志记录规范
07 MCP协议的应用价值分析
MCP与主流通信协议对比分析
| 特性 | MCP协议 | gRPC | OpenAPI |
|---|---|---|---|
| 传输格式 | JSON-RPC (文本) | Protobuf (二进制) | JSON/XML (文本) |
| 通信模式 | 双向持续交互 | 请求-响应/流式 | 请求-响应 |
| 上下文支持 | 内置会话上下文跟踪 | 无原生支持 | 无状态 |
| AI交互特性 | 动态工具发现、结构化输出 | 无 | 无 |
| 认证机制 | OAuth 2.1原生支持 | 需额外实现 | OAuth 2.0/API Key |
| 适用场景 | AI助手工具调用 | 高性能微服务通信 | 传统API接口 |
| 学习曲线 | 低(JSON基础) | 中(需学 Protobuf) | 中(需定义规范) |
未来展望
-
异步工具调用支持
当前MCP SDK主要支持同步工具调用,未来可以扩展异步调用能力,支持处理耗时较长的任务,如:视频处理 -
大数据分析
-
长时间运行的模拟计算
-
更丰富的认证授权机制
目前MCP协议的安全机制相对简单,未来可以引入更完善的认证授权功能:OAuth 2.0认证 -
API Key管理
-
细粒度权限控制
-
请求频率限制
-
资源管理功能扩展
MCP协议已支持基本的资源管理功能,未来可以进一步扩展:文件存储与管理 -
数据库集成
-
知识库管理
-
版本控制
-
多语言SDK支持
目前MCP SDK主要支持Java语言,未来可以开发更多语言的SDK:Python SDK:适合数据科学和AI领域的开发者 -
TypeScript/JavaScript SDK:适合前端和全栈开发者
-
Go SDK:适合高性能服务开发
-
Rust SDK:适合系统级开发
-
服务发现与注册中心
随着MCP服务数量的增加,需要引入服务发现机制:集中式服务注册中心 -
服务健康检查
-
负载均衡
-
服务熔断与降级
08 总结
MCP协议为AI助手与外部服务之间提供了标准化的通信方式,通过本文介绍的步骤,你已经掌握了MCP服务的开发方法。从环境准备、项目搭建、核心代码实现,到工具注册和多场景调用,我们一步步构建了一个完整的双色球号码生成MCP服务。
MCP协议的价值不仅在于技术层面的标准化,更在于它为AI应用开发带来了新的思路。通过 MCP,我们可以将AI助手的能力无限扩展,同时保持开发的灵活性和安全性。
未来,随着MCP协议的不断完善和普及,我们有理由相信,它将成为AI应用开发的重要基础设施,为AI赋能各行各业提供强有力的技术支持。
火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。
更多推荐
所有评论(0)