HTTP to MCP Protocol Bridge
让任何 HTTP 客户端无缝调用 MCP 工具
MCP HTTP Proxy 是一个协议桥接服务,将标准的 HTTP POST 请求转换为 Model Context Protocol (MCP) 工具调用。
核心场景:你的应用只会发 HTTP 请求,但需要调用远端 MCP Server 上的工具 —— 这个代理帮你完成协议转换。
┌──────────┐ HTTP POST ┌──────────────┐ MCP Protocol ┌────────────┐
│ Client │ ───────────────→│ MCP HTTP │ ──────────────────→│ MCP Server │
│ (any app) │ ←───────────────│ Proxy │ ←──────────────────│ (tools) │
└──────────┘ JSON Response └──────────────┘ Tool Result └────────────┘
项目采用经典分层架构,职责清晰:
| Layer | Package | Responsibility |
|---|---|---|
| Interfaces | interfaces.rest |
REST 控制器、请求路由、异常处理 |
| Domain | domain.service |
业务逻辑:验证、安全检查、工具调用编排 |
| Infrastructure | infrastructure.* |
MCP SDK 集成、客户端缓存池、重试引擎、监控指标 |
每个工具调用请求经历以下处理流程:
- Parameter Validation —
@Valid注解 + 深度/大小约束检查 - Security Check — 域名白名单匹配、内网 IP 拦截、协议限制(仅 HTTP/HTTPS)
- Cache Lookup — LRU 缓存池复用 MCP 客户端连接,避免重复握手
- Retry with Backoff — 指数退避重试,区分可重试(连接超时)和不可重试(协议错误)异常
- MCP Tool Execution — 通过官方 Java SDK 执行工具调用
- Response + Metrics — 统一 JSON 响应,Micrometer 指标采集
- JDK 25+
- Maven 3.6+
# 编译
mvn clean compile
# 启动
mvn spring-boot:run
# 服务启动在 http://localhost:8080/api/v1# 健康检查
curl http://localhost:8080/api/v1/management/health
# 调用 MCP 工具
curl -X POST http://localhost:8080/api/v1/mcp/tools/call \
-H 'Content-Type: application/json' \
-d '{
"serverUrl": "https://your-mcp-server.com",
"toolName": "get_weather",
"parameters": { "location": "Beijing" },
"transport": "http"
}'调用远端 MCP 服务器上的工具。
Request Body:
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
serverUrl |
string | Yes | — | MCP 服务器 URL(http/https) |
toolName |
string | Yes | — | 工具名称 |
parameters |
object | Yes | — | 工具参数 |
transport |
string | No | "http" |
传输协议:http(Streamable HTTP)或 sse(SSE) |
timeout |
number | No | 30000 |
超时时间(毫秒) |
headers |
object | No | — | 转发给 MCP 服务器的额外请求头 |
Success Response 200:
{
"success": true,
"data": [{ "type": "text", "text": "Tool result here" }],
"requestId": "a94b7a0a-9e22-4ffb-a712-23656b180d5c",
"processingTime": 1500,
"timestamp": "2026-03-31T14:42:00"
}Error Responses:
| HTTP Status | errorCode |
Scenario |
|---|---|---|
400 |
INVALID_REQUEST |
参数验证失败 |
403 |
ACCESS_DENIED |
服务器不在白名单内 |
500 |
MCP_ERROR |
MCP 协议错误 |
500 |
TIMEOUT |
调用超时 |
500 |
CONNECTION_ERROR |
无法连接 MCP 服务器 |
| Endpoint | Description |
|---|---|
GET /api/v1/management/health |
健康检查 |
GET /api/v1/management/status |
系统状态 + 调用指标 + 缓存统计 |
GET /api/v1/management/cache/stats |
客户端缓存详情 |
GET /actuator/prometheus |
Prometheus 格式指标 |
核心配置项(application.yml 或环境变量):
mcp:
proxy:
allowed-domains: # 域名白名单
- "localhost"
- "*.your-domain.com"
connection-timeout: 10000 # 连接超时 (ms)
request-timeout: 30000 # 请求超时 (ms)
client-cache:
max-size: 100 # 客户端缓存池上限
expire-after-access: 30 # 空闲过期 (分钟)
retry:
max-attempts: 3 # 最大重试次数
backoff-multiplier: 2.0 # 指数退避倍数
security:
max-parameter-depth: 10 # 参数最大嵌套深度
max-parameter-size: 1048576 # 参数最大体积 (1MB)Environment Variables:
| Variable | Default | Description |
|---|---|---|
MCP_PROXY_ALLOWED_DOMAINS |
localhost,*.example.com |
域名白名单 |
MCP_PROXY_CONNECTION_TIMEOUT |
10000 |
连接超时 (ms) |
MCP_PROXY_REQUEST_TIMEOUT |
30000 |
请求超时 (ms) |
MCP_PROXY_CLIENT_CACHE_MAX_SIZE |
100 |
缓存池上限 |
内置多层安全防护:
- Domain Whitelist — 仅允许白名单内的 MCP 服务器域名
- Internal IP Block — 自动拦截
10.x、172.16-31.x、192.168.x等内网地址(防 SSRF) - Protocol Restriction — 仅允许
http://和https://协议 - Parameter Depth Guard — 递归检查参数嵌套深度,防止栈溢出攻击
- Parameter Size Limit — 限制请求体大小,防止内存耗尽
src/main/java/com/example/mcpproxy/
├── McpHttpProxyApplication.java # Spring Boot 入口
├── interfaces/rest/
│ ├── McpProxyController.java # 工具调用 API
│ ├── McpManagementController.java # 管理 API
│ └── GlobalExceptionHandler.java # 统一异常处理
├── domain/
│ ├── model/
│ │ ├── ToolCallRequest.java # 请求模型
│ │ └── ToolCallResponse.java # 响应模型
│ └── service/
│ ├── McpProxyService.java # 业务接口
│ ├── DefaultMcpProxyService.java # 核心实现
│ └── AsyncMcpProxyService.java # 异步支持
└── infrastructure/
├── config/
│ ├── McpConfiguration.java # 配置绑定
│ └── AsyncConfiguration.java # 线程池配置
├── mcp/
│ ├── McpClientManager.java # 客户端管理接口
│ ├── DefaultMcpClientManager.java # 缓存池实现
│ ├── ClientWrapper.java # 客户端包装器
│ └── ClientCacheStats.java # 缓存统计
├── monitoring/
│ └── McpMetricsService.java # Micrometer 指标
└── util/
└── RetryTemplate.java # 指数退避重试
mvn clean package
docker build -t mcp-http-proxy:latest .
docker run -p 8080:8080 \
-e MCP_PROXY_ALLOWED_DOMAINS=your-mcp-server.com \
mcp-http-proxy:latestdocker-compose up -dapiVersion: apps/v1
kind: Deployment
metadata:
name: mcp-http-proxy
spec:
replicas: 3
selector:
matchLabels:
app: mcp-http-proxy
template:
metadata:
labels:
app: mcp-http-proxy
spec:
containers:
- name: mcp-http-proxy
image: mcp-http-proxy:latest
ports:
- containerPort: 8080
env:
- name: MCP_PROXY_ALLOWED_DOMAINS
value: "your-mcp-server.com"
resources:
requests: { memory: "512Mi", cpu: "250m" }
limits: { memory: "1Gi", cpu: "500m" }
livenessProbe:
httpGet: { path: /api/v1/management/health, port: 8080 }
initialDelaySeconds: 60
readinessProbe:
httpGet: { path: /api/v1/management/health, port: 8080 }
initialDelaySeconds: 30项目内置 Micrometer 指标,兼容 Prometheus + Grafana:
| Metric | Type | Description |
|---|---|---|
mcp.tool.calls.total |
Counter | 总调用次数 |
mcp.tool.calls.success |
Counter | 成功次数 |
mcp.tool.calls.error |
Counter | 失败次数 |
mcp.tool.call.duration |
Timer | 调用耗时(P50/P95/P99) |
mcp.client.cache.size |
Gauge | 当前缓存连接数 |
mcp.client.cache.hit_rate |
Gauge | 缓存命中率 |
Prometheus Alert Example:
groups:
- name: mcp-proxy
rules:
- alert: HighErrorRate
expr: rate(mcp_tool_calls_error_total[5m]) / rate(mcp_tool_calls_total[5m]) > 0.1
for: 5m
annotations:
summary: "MCP Proxy error rate > 10%"| Component | Version | Purpose |
|---|---|---|
| Java | 25 | Runtime |
| Spring Boot | 3.5.3 | Web Framework |
| MCP Java SDK | 0.12.1 | MCP Protocol Client |
| Micrometer | — | Metrics & Monitoring |
| Jackson | — | JSON Serialization |
| JUnit 5 + Mockito | — | Testing |


