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项目

  1. 使用Spring Initializr创建新项目访问 Spring Initializr

  2. 选择Spring Boot 3.1.x版本

  3. 添加"Spring Web"依赖

  4. 生成项目并导入IDE

  5. 添加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助手,以下是调用步骤:

  1. 安装Cherry Studio
    参考官方教程安装Cherry Studio:Cherry Studio 下载和安装教程

  2. 配置MCP服务器
    打开Cherry Studio,进入设置页面,找到"MCP服务"配置项,添加MCP服务器:服务器名称:double-color-ball-mcp-server(可自定义)

  3. 服务器URL:http://localhost:8080/mcp/message

  4. 调用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服务:

  1. 配置MCP服务器
    打开Cursor,进入设置页面(Settings),找到"MCP Servers"配置项,添加以下JSON配置:{ "mcpServers": { "double-color-ball-mcp-server": { "url": "http://localhost:8080/mcp/message" } } }如果需要配置多个MCP服务器,可以在mcpServers对象中添加多个键值对,用逗号分隔。

  2. 调用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协议的应用价值分析

  1. 打破AI生态壁垒
    MCP协议最大的价值在于打破了不同AI助手之间的生态壁垒。传统开发模式中,每个AI平台(如 ChatGPT、Claude、文心一言等)都有自己独特的工具调用方式,开发者需要为不同平台重复开发功能类似的接口。而基于MCP协议开发的服务,可以被所有支持MCP协议的AI助手调用,实现了"一次开发,多端适配",极大降低了开发成本。

  2. 提升AI助手能力边界
    MCP协议让AI助手能够轻松扩展各种专业能力:实时数据获取:如天气查询、股票行情、新闻资讯等

  3. 专业计算能力:如科学计算、数据分析、工程模拟等

  4. 业务系统集成:如CRM查询、订单管理、库存查询等

  5. 创意生成工具:如图片生成、文案创作、代码生成等

  6. 保护数据隐私与安全
    MCP服务运行在开发者自己的服务器上,所有数据处理都在本地完成,避免了敏感数据上传到第三方AI平台的风险。这对于企业级应用尤为重要,能够满足数据合规和隐私保护的要求。

  7. 标准化的通信接口
    MCP协议定义了标准化的通信接口,包括:工具元数据描述格式

  8. 请求/响应数据结构

  9. 错误处理机制

  10. 日志记录规范

07 MCP协议的应用价值分析

MCP与主流通信协议对比分析

特性 MCP协议 gRPC OpenAPI
传输格式 JSON-RPC (文本) Protobuf (二进制) JSON/XML (文本)
通信模式 双向持续交互 请求-响应/流式 请求-响应
上下文支持 内置会话上下文跟踪 无原生支持 无状态
AI交互特性 动态工具发现、结构化输出
认证机制 OAuth 2.1原生支持 需额外实现 OAuth 2.0/API Key
适用场景 AI助手工具调用 高性能微服务通信 传统API接口
学习曲线 低(JSON基础) 中(需学 Protobuf) 中(需定义规范)

未来展望

  1. 异步工具调用支持
    当前MCP SDK主要支持同步工具调用,未来可以扩展异步调用能力,支持处理耗时较长的任务,如:视频处理

  2. 大数据分析

  3. 长时间运行的模拟计算

  4. 更丰富的认证授权机制
    目前MCP协议的安全机制相对简单,未来可以引入更完善的认证授权功能:OAuth 2.0认证

  5. API Key管理

  6. 细粒度权限控制

  7. 请求频率限制

  8. 资源管理功能扩展
    MCP协议已支持基本的资源管理功能,未来可以进一步扩展:文件存储与管理

  9. 数据库集成

  10. 知识库管理

  11. 版本控制

  12. 多语言SDK支持
    目前MCP SDK主要支持Java语言,未来可以开发更多语言的SDK:Python SDK:适合数据科学和AI领域的开发者

  13. TypeScript/JavaScript SDK:适合前端和全栈开发者

  14. Go SDK:适合高性能服务开发

  15. Rust SDK:适合系统级开发

  16. 服务发现与注册中心
    随着MCP服务数量的增加,需要引入服务发现机制:集中式服务注册中心

  17. 服务健康检查

  18. 负载均衡

  19. 服务熔断与降级

08 总结

MCP协议为AI助手与外部服务之间提供了标准化的通信方式,通过本文介绍的步骤,你已经掌握了MCP服务的开发方法。从环境准备、项目搭建、核心代码实现,到工具注册和多场景调用,我们一步步构建了一个完整的双色球号码生成MCP服务。

MCP协议的价值不仅在于技术层面的标准化,更在于它为AI应用开发带来了新的思路。通过 MCP,我们可以将AI助手的能力无限扩展,同时保持开发的灵活性和安全性。

未来,随着MCP协议的不断完善和普及,我们有理由相信,它将成为AI应用开发的重要基础设施,为AI赋能各行各业提供强有力的技术支持。

Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐