AI模型协议服务器

Spring Boot构建的生产级AI模型协议服务器,支持实时通信、JWT认证和Docker容器化部署。

  • by nagachary
  • Java
  • 本地部署
  • 更新于
在 GitHub 查看 nagachary/spring_boot_ai_mcp_server

使用说明

Spring Boot AI MCP服务器

Java 21 | 弹簧靴3.4.2 | 码头工人 | MIT许可证

生产准备就绪 模型上下文协议(MCP)服务器 采用Spring Boot构建,具有反应式架构、带滑动过期的JWT身份验证和完整的Docker容器化,可实现无缝部署。

特性

核心能力

  • MCP服务器发送事件(SSE) 实时人工智能模型通信的传输
  • GitHub API集成 使用反应式WebClient进行非阻塞拉取请求管理
  • 高级安全:
    • 双层认证(API密钥+JWT)
    • 滑动窗口令牌刷新用于连续会话
    • 无状态设计,支持水平扩展
  • 反应式体系结构:基于Spring WebFlux构建,用于高性能、非阻塞操作
  • 生产监控:带有健康检查和指标的执行器端点

Docker部署

  • 完全码头化:使用Docker Compose进行单命令部署
  • 多阶段构建:通过分离的构建和运行时环境优化了图像大小
  • 基于环境的配置:通过以下方式进行安全的凭据管理 .env 文件
  • 零停机:自动重启策略和优雅的关机处理
  • 便携的:在开发、暂存和生产环境中一致运行

开发者体验

  • 专业测井:使用性能指标进行结构化请求/响应跟踪
  • 错误处理:具有优雅降级的全面错误恢复
  • 热重新加载:即时代码更改的开发模式(非Docker)
  • 整洁架构:将关注点与服务层、控制器层和配置层分离

先决条件

  • Docker&Docker编写 (推荐)
    • Docker引擎20.10+
    • Docker Compose 2.0+
  • 或用于当地发展:
    • Java 21+
    • Maven 3.9+

快速开始

选项1:Docker部署(推荐)

  1. 克隆仓库
git clone https://github.com/yourusername/spring_boot_ai_mcp_server.git
cd spring_boot_ai_mcp_server
  1. 配置环境变量
cp .env.example .env
# Edit .env with your credentials
nano .env
  1. 使用Docker Compose构建和运行
docker-compose up -d --build
  1. 验证部署
docker-compose logs -f
curl http://localhost:8088/actuator/health

就是这样! 您的MCP服务器正在运行 http://localhost:8088

方案2:地方发展

  1. 设置环境变量
export GITHUB_API_BEARER_TOKEN=your_github_token
export MCP_SERVER_SHARED_API_KEY=your_api_key
export MCP_AUTH_JWT_SECRET=your_jwt_secret_min_32_chars
  1. 构建并运行
mvn clean install
mvn spring-boot:run

配置

环境变量

创建一个 .env 项目根目录中的文件:

# GitHub API Configuration
GITHUB_API_BEARER_TOKEN=ghp_your_github_personal_access_token

# MCP Server Authentication
MCP_SERVER_SHARED_API_KEY=your-secure-api-key
MCP_AUTH_JWT_SECRET=your-jwt-secret-at-least-32-characters-long

️ 安全说明:从不承诺 .env 版本控制。使用 .env.example 对于模板。

应用程序属性

关键配置 application.properties:

# Server
server.port=8088

# MCP Server
spring.ai.mcp.server.enabled=true
spring.ai.mcp.server.transport=sse

# GitHub Repository
github.owner=your-github-username
github.repo=your-repository-name

# JWT Configuration
mcp.auth.jwt-ttl-seconds=3600
mcp.auth.refresh-window-seconds=300

身份验证体系结构

双层安全模型

此MCP服务器实现了 纵深防御 结合API密钥和JWT令牌认证的认证策略:

┌─────────────────────────────────────────────────────────────────┐
│                     Authentication Flow                         │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  1. Initial Authentication (API Key)                            │
│     Client → POST /mcp/auth/token                               │
│              Header: X-API-KEY: shared-secret                   │
│              ↓                                                  │
│     Server validates API key                                    │
│              ↓                                                  │
│     Server generates JWT token                                  │
│              ↓                                                  │
│     Response: { "accessToken": "eyJ..." }                       │
│                                                                 │
│  2. Subsequent Requests (JWT)                                   │
│     Client → POST /mcp/tools/call                               │
│              Header: Authorization: Bearer <jwt-token>          │
│              ↓                                                  │
│     Server validates JWT signature & expiration                 │
│              ↓                                                  │
│     Server processes request                                    │
│              ↓                                                  │
│     Server generates NEW JWT (sliding window)                   │
│              ↓                                                  │
│     Response: Data + Header: X-Refresh-Token: <new-jwt>         │
│                                                                 │
│  3. Token Refresh (Automatic)                                   │
│     Client stores new token from X-Refresh-Token header         │
│     Next request uses the refreshed token                       │
│     Active sessions never expire!                               │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

为什么选择双层身份验证?

层次 目的 好处
API密钥 初始身份验证 简单、可撤销、跨团队共享
JWT代币 按请求授权 无状态、可扩展、自动过期

滑动窗口令牌刷新

问题:固定过期令牌需要重新身份验证,从而中断用户体验。

解决方案:滑动窗口刷新使活动会话无限期保持活动状态。

它是如何工作的:

  1. JWT的有效期为1小时(可配置)
  2. 刷新窗口(最后5分钟)内的每个有效请求都会获得一个新令牌
  3. 客户端自动将新令牌用于后续请求
  4. 非活动会话在1小时后自然过期
  5. 活动会话无限期继续,无需重新身份验证

配置:

mcp.auth.jwt-ttl-seconds=3600           # Token lifetime: 1 hour
mcp.auth.refresh-window-seconds=300     # Refresh if <5 min remaining

安全属性

无状态:无会话存储,支持水平扩展
自动过期:非活动会话自动超时
可撤销的:更改JWT密钥以使所有令牌无效
耐重播:每个令牌都有唯一的发行时间戳
零停机轮换:API密钥可以在不重新启动服务的情况下更改

身份验证流程(逐步)

1.获取JWT Token

curl -X POST http://localhost:8088/mcp/auth/token \
  -H "X-API-KEY: your-api-key"

答复:

{
  "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}

2.对API请求使用令牌

curl http://localhost:8088/mcp/tools/call \
  -H "Authorization: Bearer <your-jwt-token>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "getAllPullRequests",
    "arguments": {"state": "open"}
  }'

答复:

HTTP/1.1 200 OK
X-Refresh-Token: refershedToken...  ← New token!

{
  "status": "success",
  "result": [...]
}

3.自动令牌刷新

服务器在 X-Refresh-Token 刷新窗口内每个成功请求的标头。活动会话永远不会过期。

4.令牌到期处理

如果令牌过期(在1小时不活动后),请重新进行身份验证:

# Token expired (401 Unauthorized)
curl http://localhost:8088/mcp/tools/call \
  -H "Authorization: Bearer <expired-token>"

# Response:
{
  "error": "JWT token expired",
  "status": 401
}

# Re-authenticate
curl -X POST http://localhost:8088/mcp/auth/token \
  -H "X-API-KEY: your-api-key"

API终点

健康与监测

GET /actuator/health          # Health check
GET /actuator/info            # Application info
GET /actuator/metrics         # Performance metrics

认证

POST /mcp/auth/token          # Obtain JWT token
  Header: X-API-KEY: <api-key>

MCP工具

POST /mcp/tools/call          # Execute MCP tools
  Header: Authorization: Bearer <jwt-token>
  Body: {
    "name": "getAllPullRequests",
    "arguments": {"state": "open|closed|all"}
  }

SSE流

GET /mcp/sse                  # Server-Sent Events stream
  Header: Authorization: Bearer <jwt-token>

优点:

  • 较小的图像:运行时映像~270MB(使用构建工具时为500MB+)
  • 更快的部署:优化了层缓存
  • 安全:生产映像中没有构建工具
  • 可重复性:跨环境的一致构建

Docker编写管理

# Start services
docker-compose up -d

# View logs
docker-compose logs -f

# Stop services
docker-compose down

# Rebuild after code changes
docker-compose up -d --build

# View running containers
docker-compose ps

性能优化

  • 响应式WebFlux:高并发的非阻塞I/O
  • 连接池:高效的HTTP客户端连接重用
  • 超时配置:防止资源耗尽
  • Docker层缓存:3分钟→ 30秒重建时间
  • Docker先生:655 MB→ 5MB构建上下文(减少100倍)

测量性能:

  • 服务器处理时间:500-800ms
  • GitHub API延迟:400-600ms
  • 总响应时间:<2秒(p95)

监控和记录

结构化日志记录

10:28:01.911 INFO  ▶ REQUEST: tool=getAllPullRequests, args={state=open}
10:28:02.450 INFO  → GitHub API: Fetching PRs state=open
10:28:02.996 INFO  ← GitHub API: Retrieved 24 PRs, api=546ms, total=546ms
10:28:02.996 INFO  ✓ SUCCESS: tool=getAllPullRequests, items=24, duration=1085ms

健康检查

# Application health
curl http://localhost:8088/actuator/health

# Detailed metrics
curl http://localhost:8088/actuator/metrics/http.server.requests

部署场景

发展

docker-compose up --build

暂存

docker-compose -f docker-compose.yml -f docker-compose.staging.yml up -d

生产

# With custom environment
docker-compose -f docker-compose.prod.yml up -d

# Or with Kubernetes
kubectl apply -f k8s/deployment.yml

安全最佳实践

  • 基于环境的秘密(从未硬编码)
  • .env 排除在版本控制之外
  • 带滑动过期窗口的JWT
  • API密钥认证层
  • HTTPS就绪(配置反向代理)
  • 已启用安全标头
  • 在所有端点上进行输入验证

技术栈

技术 目的
弹簧靴3.4.2 应用框架
Spring WebFlux 反应式web堆栈
Spring Security 身份验证和授权
JWT(jjwt 0.11.5) 基于令牌的身份验证
春季AI MCP 模型上下文协议集成
网络客户端 非阻塞HTTP客户端
执行器 生产监控
码头工人 集装箱化
梅文 构建自动化

许可证

此项目根据MIT许可证获得许可-请参阅 许可证 文件以获取详细信息。

故障排除

Docker构建失败

问题: error: release version 21 not supported

解决方案: 确保Dockerfile使用Java 21:

FROM maven:3.9-eclipse-temurin-21 AS build
FROM eclipse-temurin:21-jre

端口已在使用中

问题: Bind for 0.0.0.0:8088 failed: port is already allocated

解决方案: 更改端口 docker-compose.yml:

ports:
  - "8089:8088"  # Change external port

环境变量未加载

问题: 应用程序找不到环境变量

解决方案: 验证 .env 文件存在并重新启动:

docker-compose down
docker-compose up -d

使用Spring Boot和Docker制作