内容
<div align="center">
# grpc-mcp — 通用MCP桥接器,适用于任何gRPC服务
<p>
<img src="https://img.shields.io/badge/Java-21-007396?style=for-the-badge&logo=openjdk&logoColor=white">
<img src="https://img.shields.io/badge/Spring_Boot-3.4-6DB33F?style=for-the-badge&logo=springboot&logoColor=white">
<img src="https://img.shields.io/badge/Gradle-8.x-02303A?style=for-the-badge&logo=gradle&logoColor=white">
<img src="https://img.shields.io/badge/gRPC-1.76-2441E0?style=for-the-badge&logo=grpc&logoColor=white">
</p>
**将任何gRPC服务桥接到MCP生态系统** — 通过反射或`.proto`文件自动发现方法,生成参数的JSON模式,并作为MCP工具暴露,提供健康监测、重试和TLS支持。
</div>
---
## 功能特点
- **4个MCP工具** — `list_methods`、`get_method_schema`、`invoke_method`、`health`
- **2种发现模式** — gRPC反射或protoc编译的`.proto`文件
- **弹性** — 通道健康监测、自动重连、指数退避重试
- **安全** — X-Api-Key认证、TLS gRPC、自定义元数据头
- **配置驱动** — 所有设置均通过环境变量、单个通用Docker镜像
## 快速入门
```bash
docker run -p 8080:8080 \
-e GRPC_ADDRESS=your-grpc-host:port \
-e MCP_NAME="我的服务" \
-e MCP_API_KEY=your-api-key \
grpc-mcp:1.0
```
然后连接任何MCP客户端:
```json
{
"mcpServers": {
"my-service": {
"type": "remote",
"url": "http://localhost:8080/mcp",
"headers": {
"X-API-Key": "<your-api-key>"
}
}
}
}
```
## MCP工具
| 工具 | 描述 |
|---|---|
| `list_methods` | 列出所有已发现的gRPC方法,格式为`ServiceName/methodName` |
| `get_method_schema` | 输入参数的JSON模式 + 示例。参数:`method` |
| `invoke_method` | 调用gRPC方法。参数:`method`、`arguments`(JSON) |
| `health` | gRPC通道状态:`READY` / `IDLE` / `CONNECTING` / `TRANSIENT_FAILURE` |
## 发现模式
根据`GRPC_PROTO_FILE`自动选择:
- **文件** — 指定`.proto`文件 → 在启动时通过`protoc`编译,提取模式和源代码注释
- **反射** — 没有proto文件 → 使用gRPC `ServerReflectionService`(服务器必须支持)
## 环境变量
### MCP
| 变量 | 描述 | 默认值 |
|---|---|---|
| `MCP_NAME` | MCP服务器显示名称 | — |
| `MCP_API_KEY` | `X-Api-Key`头的认证密钥 | — |
### gRPC连接
| 变量 | 描述 | 默认值 |
|---|---|---|
| `GRPC_ADDRESS` | gRPC目标`host:port` | — |
| `GRPC_NEGOTIATION_TYPE` | `PLAINTEXT`或`TLS` | `PLAINTEXT` |
| `GRPC_PROTO_FILE` | `.proto`文件路径(为空时使用反射) | — |
| `GRPC_METADATA` | 额外的gRPC头部的JSON | `{}` |
### 超时和重试
| 变量 | 描述 | 默认值 |
|---|---|---|
| `GRPC_CALL_TIMEOUT` | 单次调用超时 | `10s` |
| `GRPC_MAX_RETRIES` | 最大重试次数(总尝试次数 = 值 + 1) | `2` |
| `GRPC_BACKOFF_INITIAL` | 初始重试延迟 | `500ms` |
| `GRPC_RETRY_BACKOFF_MULTIPLIER` | 退避乘数 | `2.0` |
| `GRPC_RETRY_MAX_DELAY` | 最大重试延迟 | `3s` |
### 保活
| 变量 | 描述 | 默认值 |
|---|---|---|
| `GRPC_KEEPALIVE_TIME` | 保活ping间隔 | `10s` |
| `GRPC_KEEPALIVE_TIMEOUT` | 保活ping超时 | `5s` |
| `GRPC_KEEPALIVE_WITHOUT_CALLS` | 即使没有活动调用也ping | `true` |
### 发现
| 变量 | 描述 | 默认值 |
|---|---|---|
| `GRPC_REFLECTION_TIMEOUT` | 反射发现/重新发现超时 | `5s` |
| `GRPC_PROTOC_TIMEOUT` | Protoc编译超时 | `10s` |
| `GRPC_SCHEMA_MAX_DEPTH` | JSON模式生成最大深度 | `8` |
### 健康检查
| 变量 | 描述 | 默认值 |
|---|---|---|
| `GRPC_HEALTH_CHECK_INTERVAL` | gRPC通道健康检查间隔 | `30s` |
## 架构
```
┌──────────────┐ MCP ┌────────────────────┐ gRPC ┌──────────────────┐
│ │ ◄────────────────── │ │ ◄─────────── │ │
│ MCP客户端 │ │ grpc-mcp │ │ gRPC服务 │
│ (opencode, │ ──────────────────► │ │ ───────────► │ (您的应用) │
│ Claude, …) │ ├────────────────────┤ │ │
└──────────────┘ │ 发现层 │ └──────────────────┘
│ ├─ 反射 │
│ └─ protoc .proto │
│ 健康监测 │
│ 重试策略 │
│ 元数据注入 │
└────────────────────┘
```
## 构建和测试
```bash
# 构建
./gradlew build
# 测试
./gradlew test
```
## Docker
```bash
# 构建镜像
docker build -t grpc-mcp .
# 运行
docker run -p 8080:8080 \
-e GRPC_ADDRESS=your-grpc-host:port \
-e MCP_NAME="我的服务" \
-e MCP_API_KEY=your-api-key \
grpc-mcp
```
## 安全
- 所有请求都需要`X-Api-Key`头(通过`MCP_API_KEY`配置)
- 没有有效密钥的请求被拒绝,返回`401 Unauthorized`
- gRPC连接通过`GRPC_NEGOTIATION_TYPE=TLS`支持TLS
- 通过`GRPC_METADATA` JSON配置自定义gRPC元数据头
---
<div align="center">
<sub>使用Spring Boot、gRPC-Java和模型上下文协议SDK构建</sub>
</div>