SmartScheduler MCP服务器
概念验证 模型上下文协议(MCP)服务器 使用Spring Boot和Spring AI构建,将智能日程安排功能作为MCP工具公开,可供Claude、Cursor或任何兼容MCP的AI客户端使用。
______________________________________________________________________
目录
______________________________________________________________________
什么是MCP?
模型上下文协议(MCP) 是一个开放标准(由Anthropic于2025年3月发布),定义了人工智能模型如何通过结构化JSON-RPC接口与外部工具和数据源通信。将其视为AI的USB-C端口:MCP提供了一种通用协议,而不是每个LLM集成都需要自定义插件或函数调用模式。
一 MCP服务器 是一个轻量级的过程,它:
- 声明一组 工具 (AI可以调用的函数)。
- 接受来自的工具调用请求 客户端 (例如Claude Desktop、Cursor、自定义代理)。
- 执行工具逻辑并将结果传回。
运输选项包括 标准 (本地过程), HTTP与SSE,以及较新的 可流式传输的HTTP (无状态POST)-此项目使用 可流式传输的HTTP 结束 POST /mcp.
______________________________________________________________________
这个POC做什么
此服务器演示了如何包装一个真实的业务域-- 日历和会议日程安排 --在MCP界面后面,AI助手可以通过自然语言对其进行管理。
一个“日历所有者”帐户在启动时被播种。连接到此服务器的AI客户端可以:
- 创建事件 自动防止重复预订
- 检查可用性 适用于任何时间段
- 改期 会议(根据现有事件检查冲突)
- 取消 会议
- 添加参与者 (外部与会者)参加现有活动
- 搜索事件 按标题分页
- 注册用户 并列出它们
通过Claude Desktop进行交互示例:
*“安排明天下午3点进行1小时的设计审查,并邀请sara@design.com"*\ → 克劳德打电话来check_availability那么create_event那么add_participant自主。
______________________________________________________________________
演示
下面的屏幕截图显示了连接到Claude Desktop的SmartScheduler MCP服务器的运行情况。
将智能调度程序连接到Claude
Claude认可的所有7种MCP工具
通过克劳德获取本周活动
检查可用性——运行中的冲突检测
通过自然语言重新安排会议
向活动添加参与者
验证H2控制台中的持久事件(开发人员)
验证H2控制台中的持久参与者(开发版)
______________________________________________________________________
建筑
┌─────────────────────────────────────────────────────┐
│ AI Client │
│ (Claude Desktop / Cursor / custom agent) │
└────────────────────┬────────────────────────────────┘
│ POST /mcp (Streamable HTTP)
│ Authorization: Bearer
┌────────────────────▼────────────────────────────────┐
│ Spring Boot MCP Server │
│ │
│ ┌──────────────────────────────────────────────┐ │
│ │ Spring AI MCP Layer │ │
│ │ (tool discovery, JSON-RPC dispatch, │ │
│ │ schema generation from @Tool annotations) │ │
│ └──────────────┬───────────────────────────────┘ │
│ │ │
│ ┌──────────────▼───────────────────────────────┐ │
│ │ SchedulingTools (MCP tool entrypoints) │ │
│ │ UserTools │ │
│ └──────────────┬───────────────────────────────┘ │
│ │ │
│ ┌──────────────▼───────────────────────────────┐ │
│ │ SchedulingService (business logic) │ │
│ └──────────────┬───────────────────────────────┘ │
│ │ │
│ ┌──────────────▼───────────────────────────────┐ │
│ │ JPA Repositories → H2 (dev) / PostgreSQL │ │
│ └──────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────┘请求流程:
- AI客户端向发送JSON-RPC 2.0消息
POST /mcp. ApiKeyFilter验证Authorization: Bearer头球- Spring AI的MCP层将调用路由到适当的
@Tool-注释方法。 SchedulingTools/UserTools解析并验证参数,然后委托给SchedulingService.SchedulingService执行业务规则(冲突检测、所有权)并通过JPA持久化。- 结果被序列化为JSON并流式传输回客户端。
______________________________________________________________________
MCP工具参考
所有工具均暴露在 POST /mcp参数以JSON对象的形式在 arguments JSON-RPC请求的字段。ISO-8601日期时间使用以下格式 yyyy-MM-ddTHH:mm:ss (例如。 2025-06-01T10:00:00).
计划工具
| 工具 | 描述 | 必需参数 | 可选参数 |
|---|---|---|---|
create_event | 创建日历事件。自动防止重复预订。 | title, startTime, endTime | description, timezone (IANA,默认UTC), participantEmails |
get_events | 返回日期范围内按开始时间排序的所有事件。 | startDate, endDate | — |
check_availability | 退货 available: true/false 再加上所有者的任何冲突事件。 | startTime, endTime | — |
reschedule_meeting | 将事件移动到新的时间段。检查目标位置是否存在冲突。 | eventId, newStartTime, newEndTime | — |
cancel_meeting | 删除事件并删除其所有参与者。 | eventId | — |
add_participant | 将外部参与者添加到现有事件中。Idempotent(返回 ALREADY_PRESENT 状态(如果重复)。 | eventId, name, email | — |
search_events | 分页不区分大小写的标题搜索。 | title | page (从0开始,默认为0), size (1–100,默认值10) |
用户工具
| 工具 | 描述 | 必需参数 |
|---|---|---|
create_user | 注册新用户。电子邮件必须是唯一的。 | name, email |
get_users | 返回所有注册用户。 | — |
示例:check_availability响应
{
"available": false,
"startTime": "2025-06-01T10:00:00",
"endTime": "2025-06-01T11:00:00",
"conflictingEvents": [
{
"id": 3,
"title": "Client Call — Acme Corp",
"startTime": "2025-06-01T10:30:00",
"endTime": "2025-06-01T11:30:00",
"timezone": "UTC",
"participants": []
}
]
}______________________________________________________________________
技术栈
| 层 | 技术 |
|---|---|
| 语言 | Java 21 |
| 框架 | Spring Boot 3.4.3 |
| MCP | 春季AI 1.1.3(spring-ai-starter-mcp-server-webmvc) |
| MCP传输 | 流式HTTP(POST /mcp) |
| 持久性 | Spring数据JPA+Hibernate |
| 开发/测试数据库 | 内存中的H2 |
| 生产数据库 | PostgreSQL |
| 验证 | 雅加达Bean验证 |
| 锅炉板减少 | 龙目岛 |
| 构建 | Maven(包括Maven包装器) |
| 测试 | JUnit5+Spring引导测试(集成,H2) |
______________________________________________________________________
项目结构
src/
├── main/java/com/mcp/smartScheduler/
│ ├── SmartSchedulerMcpServer.java # Spring Boot entry point
│ ├── config/
│ │ ├── ApiKeyFilter.java # Bearer-token auth filter
│ │ ├── DataInitializer.java # Seeds owner + sample events on startup
│ │ ├── McpToolConfig.java # Registers tool beans with Spring AI
│ │ └── OwnerProperties.java # Binds app.owner.* config
│ ├── dto/ # Request / response DTOs
│ │ ├── EventRequest.java
│ │ ├── EventResponse.java
│ │ ├── UserRequest.java
│ │ ├── AddParticipantsResponse.java
│ │ ├── JsonRpcRequest.java
│ │ └── JsonRpcResponse.java
│ ├── entity/
│ │ ├── User.java # Calendar user / owner
│ │ ├── Event.java # Calendar event
│ │ └── Participant.java # External attendee on an event
│ ├── exception/
│ │ ├── ConflictException.java # 409 – double-booking / duplicate
│ │ ├── ResourceNotFoundException.java # 404 – event/user not found
│ │ ├── ValidationException.java # 400 – bad input
│ │ └── GlobalExceptionHandler.java # Maps exceptions → JSON errors
│ ├── repository/
│ │ ├── EventRepository.java # Overlap-detection JPQL queries
│ │ ├── UserRepository.java
│ │ └── ParticipantRepository.java
│ ├── service/
│ │ └── SchedulingService.java # All business logic lives here
│ └── tools/
│ ├── SchedulingTools.java # @Tool methods for scheduling
│ └── UserTools.java # @Tool methods for user management
├── main/resources/
│ └── application.yaml
└── test/
├── java/com/mcp/smartScheduler/service/
│ └── SchedulingServiceTest.java # Integration tests (H2, transactional rollback)
└── resources/
└── application-test.yml______________________________________________________________________
入门指南
先决条件
- Java 21+ (
java -version) - Maven 3.9+ 或使用包含的
./mvnw - 本地开发不需要数据库设置——H2在内存中运行
1.克隆和构建
git clone https://github.com/your-username/smart-scheduler-mcp-server.git
cd smart-scheduler-mcp-server
./mvnw clean package -DskipTests2.设置环境变量(dev可选)
export OWNER_EMAIL=you@example.com # defaults to owner@example.com
export MCP_API_KEY=your-secret-key # defaults to negi-secret-key-mcp-server3.跑步
./mvnw spring-boot:run或者:
java -jar target/smart-scheduler-*.jar服务器启动于 http://localhost:8080.
在启动时, DataInitializer 种子:
- 1个所有者帐户(电子邮件来自
OWNER_EMAIL) - 5个示例事件(晨会、产品评审、客户电话、设计评审、Sprint计划)
- 5名样本参与者
4.验证
curl -s -X POST http://localhost:8080/mcp \
-H "Authorization: Bearer negi-secret-key-mcp-server" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list"
}'您应该收到一个JSON-RPC响应,其中列出了所有9个已注册的工具。
H2控制台(仅限开发人员)
浏览至 http://localhost:8080/h2-console\ JDBC网址: jdbc:h2:mem:calendardb\ 用户名: sa |密码: *(空)*
______________________________________________________________________
配置
所有配置都在 src/main/resources/application.yaml。您需要在生产中设置两个环境变量驱动的属性:
| 环境变量 | yaml键 | 默认值 | 目的 |
|---|---|---|---|
OWNER_EMAIL | app.owner.email | owner@example.com | 日历所有者帐户的电子邮件 |
MCP_API_KEY | app.api-key | negi-secret-key-mcp-server | 每次请求都需要承载令牌 |
切换到PostgreSQL
替换 datasource 和 jpa 部分在 application.yaml (或使用 application-prod.yaml 配置文件):
spring:
datasource:
url: jdbc:postgresql://localhost:5432/smartscheduler
username: ${DB_USER}
password: ${DB_PASSWORD}
driver-class-name: org.postgresql.Driver
jpa:
hibernate:
ddl-auto: validate # use Flyway / Liquibase for migrations in prod
properties:
hibernate:
dialect: org.hibernate.dialect.PostgreSQLDialect______________________________________________________________________
连接AI客户端
克劳德桌面
将以下内容添加到您的Claude Desktop MCP配置中(claude_desktop_config.json):
{
"mcpServers": {
"smart-scheduler": {
"type": "http",
"url": "http://localhost:8080/mcp",
"headers": {
"Authorization": "Bearer negi-secret-key-mcp-server"
}
}
}
}重新启动克劳德桌面。调度工具将出现在工具列表中,Claude将根据与调度相关的提示自动调用它们。
克劳德代码/任何HTTP MCP客户端
claude mcp add smart-scheduler \
--transport http \
--url http://localhost:8080/mcp \
--header "Authorization: Bearer negi-secret-key-mcp-server"直接JSON-RPC调用(curl)
# Create an event
curl -s -X POST http://localhost:8080/mcp \
-H "Authorization: Bearer negi-secret-key-mcp-server" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "create_event",
"arguments": {
"title": "Q3 Planning",
"startTime": "2025-09-01T10:00:00",
"endTime": "2025-09-01T11:30:00",
"timezone": "Asia/Kolkata",
"participantEmails": ["alice@team.com", "bob@team.com"]
}
}
}'______________________________________________________________________
运行测试
./mvnw test测试使用 test 以H2为目标的弹簧轮廓(application-test.yml).每个测试类都在测试后回滚的事务中运行,因此测试是完全隔离的。
保险范围包括:
- 创建用户时重复拒绝电子邮件
- 与参与者一起创建快乐之路活动
- 时间范围无效(开始前结束)
- 双重预订冲突检测
- 日期范围筛选
get_events - 忙/闲
check_availability - 成功的
reschedule_meeting
______________________________________________________________________
未来范围
当前的实现被有意地定义为POC。以下是生产版本所需的优先列表:
核心功能
- 周期性事件 --每日/每周/每月重复规则(RFC 5545 RRULE)
- 多所有者支持 --现在只有一个所有者被播种;使用auth扩展到每个用户的日历
- 与会者可用性 —
check_availability目前只检查所有者;扩展以检查所有受邀者 - 时区感知冲突检测 --目前,冲突是在原始状态下进行比较的
LocalDateTime;在重叠检查之前转换为UTC - 事件提醒/通知 --事件发生前的电子邮件或webhook通知
MCP/AI增强功能
- MCP资源 --将日历作为可读资源公开(
calendar://events/today)这样AI就可以订阅它 - MCP提示 --预构建的提示模板(例如“本周找到下一个可用的1小时时段”),用于引导互动
- 流媒体工具响应 --对于长时间运行的查询,使用SSE流式传输部分结果
- 工具结果缓存 --高速缓存
get_events和check_availabilityTTL较短的结果
集成
- 谷歌日历/Outlook同步 -通过Google Calendar API或Microsoft Graph进行双向同步
- Slack/团队通知 --在事件创建、更新或取消时通知参与者
- iCal导出 --揭露事件
.ics用于导入标准日历应用程序的文件
基础设施和生产准备
- 数据库迁移 --替换
ddl-auto: create-drop使用Flyway版本的迁移 - 认证 -将单个静态API密钥替换为JWT/OAuth 2.0(Spring Security)
- 速率限制 --对每个客户端请求进行限制
/mcp端点 - 可观测性 --千分尺度量、分布式跟踪(OpenTetry)、结构化JSON日志记录
- Docker/Kubernetes —
Dockerfile,docker-compose.yml对于本地开发,适用于K8s的Helm chart - CI/CD --GitHub操作管道(构建→ test → Docker镜像→ push)
- API版本控制 --版本化的MCP工具模式,以避免在更新时中断客户端
______________________________________________________________________
已知限制
| 限制 | 影响 |
|---|---|
| 单个日历所有者 | 所有事件都属于一个种子所有者;无多用户调度 |
| 内存DB中的H2 | 重启时所有数据丢失;PostgreSQL配置已提供,但不是默认配置 |
| 无时区规范化 | startTime/endTime 按原样存储;不同时区的两个事件可以悄无声息地重叠 |
| 静态API键 | 无键旋转;使用密钥的任何请求都具有完全访问权限 |
没有分页 get_events | 大日期范围在单个响应中返回所有事件 |
UserTools 未注册 | UserTools 类存在,但未连接到 McpToolConfig;仅 SchedulingTools 处于活动状态 |
______________________________________________________________________
许可证
该项目根据 Apache许可证2.0.
