内容
# gainium-mcp
Gainium 的 MCP(模型上下文协议)服务器 — 加密货币交易机器人平台。允许 AI 助手通过标准 MCP 接口管理您的机器人、交易、余额等。
详细设置和连接文档请参见 [docs/using-gainium-mcp.md](docs/using-gainium-mcp.md)。
## 快速开始
### 1. 获取您的 API 密钥
前往 [Gainium API 设置](https://app.gainium.io/app/api) 并创建一对 API 密钥。
### 2. 添加到您的 MCP 客户端
将其添加到您的 MCP 配置(VS Code、Claude Desktop 等):
```json
{
"gainium-mcp": {
"command": "npx",
"args": ["-y", "gainium-mcp"],
"env": {
"GAINIUM_API_KEY": "<您的 API 密钥>",
"GAINIUM_API_SECRET": "<您的 API 机密>"
}
}
}
```
就这样。当您的 AI 助手需要时,服务器会自动启动。
此本地 stdio 模式使用来自服务器进程环境的 `GAINIUM_API_KEY` 和 `GAINIUM_API_SECRET`。
### 环境变量
| 变量 | 必需 | 默认值 | 描述 |
|---|---|---|---|
| `GAINIUM_API_KEY` | 是 | — | 您的 Gainium API 公钥 |
| `GAINIUM_API_SECRET` | 是 | — | 您的 Gainium API 机密 |
| `GAINIUM_API_BASE_URL` | 否 | `https://api.gainium.io` | API 基地址 |
| `GAINIUM_MCP_TRANSPORT` | 否 | `stdio` | 传输模式:`stdio`、`http`、`streamable-http`、`sse` 或 `http-sse` |
| `GAINIUM_MCP_HOST` | 否 | `127.0.0.1` | HTTP 模式的绑定主机 |
| `GAINIUM_MCP_PORT` | 否 | `3000` | HTTP 模式的绑定端口 |
| `GAINIUM_MCP_HTTP_PATH` | 否 | `/mcp` | 流式 HTTP 端点路径 |
| `GAINIUM_MCP_SSE_PATH` | 否 | `/sse` | 废弃的 SSE GET 端点路径 |
| `GAINIUM_MCP_MESSAGES_PATH` | 否 | `/messages` | 废弃的 SSE POST 端点路径 |
| `GAINIUM_OAUTH_ISSUER` | 否 | — | 授权服务器基地址。设置此项(与 `MCP_INTROSPECTION_SECRET` 在 HTTP 模式下)启用 OAuth 受保护资源模式 |
| `GAINIUM_INTROSPECTION_URL` | 否 | `<issuer>/oauth/introspect` |令牌自省端点 |
| `MCP_INTROSPECTION_SECRET` | 否 | — | 向自省端点呈现的共享机密(必须与身份验证服务器匹配) |
| `GAINIUM_MCP_PUBLIC_URL` | 否 | 从请求中获取 | 受保护资源元数据中使用的公共基地址 |
| `OPENAI_APPS_CHALLENGE_TOKEN` | 否 | — | 设置后,在 `/.well-known/openai-apps-challenge` 以纯文本形式提供,用于 OpenAI Apps 域名验证 |
## 身份验证模式
`gainium-mcp` 支持三种部署模式:
- **本地 stdio 模式:** MCP 服务器从环境变量中读取 `GAINIUM_API_KEY` 和 `GAINIUM_API_SECRET`。
- **OAuth 2.1 主机模式(推荐用于托管/公共):** 服务器充当 OAuth 受保护资源。客户端(例如 Claude 连接器)从 Gainium 授权服务器获取访问令牌,并将其作为 `Authorization: Bearer <token>` 发送。参见下面的 [OAuth 2.1 主机模式](#oauth-21-主机模式)。
- **头部主机模式(旧版/自托管):** 每个请求都发送 `X-API-Key` 和 `X-API-Secret` 头部,以便一个共享服务器可以为多个用户提供服务。
在头部/_stdio 模式中,请求头优先,默认为 `GAINIUM_API_KEY` / `GAINIUM_API_SECRET`。启用 OAuth 模式后,需要 Bearer 令牌,`X-API-Key`/`X-API-Secret` 头部被忽略。
### OAuth 2.1 主机模式
这是用于公共 `https://mcp.gainium.io/mcp` 端点和 Anthropic Claude 连接器目录的模式(需要 OAuth,不允许 API 密钥头部)。
通过在 HTTP 模式下设置以下内容来启用它:
```bash
export GAINIUM_MCP_TRANSPORT=http
export GAINIUM_OAUTH_ISSUER=https://app.gainium.io # Gainium 授权服务器
export MCP_INTROSPECTION_SECRET=<共享机密> # 必须与身份验证服务器匹配
export GAINIUM_MCP_PUBLIC_URL=https://mcp.gainium.io # 此服务器的公共 URL
# 可选,默认为 <issuer>/oauth/introspect:
# export GAINIUM_INTROSPECTION_URL=https://app.gainium.io/oauth/introspect
node dist/server.js
```
启用后,服务器:
1. 在 `/.well-known/oauth-protected-resource` 和 `/.well-known/oauth-protected-resource/mcp` 处提供 **OAuth 受保护资源元数据**(RFC 9728),宣传授权服务器。
2. 使用 **`401 Unauthorized`** 和 `WWW-Authenticate: Bearer resource_metadata="…"` 头部拒绝未经身份验证的 MCP 请求,以便客户端可以发现身份验证服务器并运行 OAuth 流(动态客户端注册 + PKCE)。
3. 通过身份验证服务器的 **令牌自省** 端点验证每个请求的 Bearer 访问令牌,将其解析为用户的 Gainium `(apiKey, apiSecret)` 和每个密钥的限制(读/写、仅纸张、单机器人),这些限制仍在服务器端强制执行。自省结果被短暂缓存。
本地 stdio 路径不受这些变量的影响。
## HTTP 和 SSE 模式
默认情况下,`gainium-mcp` 通过 stdio 运行,用于生成本地进程的 MCP 客户端。要改为 HTTP 服务器:
```bash
export GAINIUM_MCP_TRANSPORT=http
export GAINIUM_MCP_HOST=127.0.0.1
export GAINIUM_MCP_PORT=3000
node dist/server.js
```
启用 HTTP 模式后,服务器暴露两种传输样式:
- `GET|POST|DELETE /mcp` 用于当前的 Streamable HTTP 传输
- `GET /sse` 加 `POST /messages?sessionId=...` 用于废弃的 HTTP+SSE 客户端
这使得一个服务器进程与现代 MCP HTTP 客户端和旧的 SSE 基集成兼容。在托管模式下,使用 OAuth(参见 [OAuth 2.1 主机模式](#oauth-21-主机模式))或为自托管/旧版设置发送 `X-API-Key` 和 `X-API-Secret` 每个请求。
## 可用工具(17)
截至 v3.0.0,工具集已整合:每个操作使用一个工具,具有 `botType` / `dealType` / `action` 区分器,而不是每个变体使用一个工具。每个工具都带有 MCP 安全注释 — 只读工具设置 `readOnlyHint`,写入工具设置 `destructiveHint`。
### 机器人
| 工具 | 访问权限 | 描述 |
|---|---|---|
| `list_bots` | 只读 | 按类型(`dca`、`combo`、`grid`)列出机器人,并带有过滤器和字段选择 |
| `get_bot` | 只读 | 按 ID 和类型获取单个机器人 |
| `create_bot` | 写入 | 创建机器人(`dca`、`combo` 或 `grid`) |
| `update_bot` | 写入 | 更新机器人设置 |
| `clone_bot` | 写入 | 克隆机器人,并带有可选覆盖 |
| `manage_bot` | 写入 | 生命周期操作:`start`、`stop`、`archive`、`restore`、`changePairs` |
### 交易
| 工具 | 访问权限 | 描述 |
|---|---|---|
| `list_deals` | 只读 | 按类型(`dca`、`combo`、`terminal`)列出交易,并带有过滤器 |
| `get_deal` | 只读 | 按 ID 和类型获取单个交易 |
| `create_deal` | 写入 | 创建交易 |
| `update_deal` | 写入 | 更新活动交易 |
| `manage_deal` | 写入 | 交易操作:`close`、`addFunds`、`reduceFunds` |
### 回测
| 工具 | 访问权限 | 描述 |
|---|---|---|
| `run_backtest` | 写入 | 运行回测:`validate`、`estimate`、异步或同步(`request`/`requestSync` 提交作业 — 非只读) |
| `backtest_info` | 只读 | 列出回测请求或获取 ID |
### 发现、账户和市场
| 工具 | 访问权限 | 描述 |
|---|---|---|
| `discover` | 只读 | 机器人类型和指标的模式发现 |
| `get_account` | 只读 | 余额、连接的交易所、支持的交易所和全局变量 |
| `get_screener` | 只读 | 加密货币筛选器与市场指标 |
| `manage_global_variable` | 写入 | 全局变量操作:`create`、`update`、`delete` |
## 字段选择
所有 GET 端点都支持 `fields` 参数以实现高效的负载:
- **预设:** `minimal`、`standard`(默认)、`extended`、`full`
- **自定义:** 以逗号分隔的点表示法字段(例如 `_id,uuid,settings.name,profit.total`)
使用 `minimal` 可将有效载荷大小减少约 85%。
## API 权限
- **只读密钥:** 仅限只读工具(`list_*`、`get_*`、`discover`、`backtest_info`、`get_screener`、`list_presets`)
- **写入密钥:** 所有工具,包括 `create_*`、`update_*`、`clone_bot`、`manage_bot`、`manage_deal`、`manage_global_variable`、`apply_preset` 和 `run_backtest`
- **只读目录连接器(` /mcp` 且 `GAINIUM_READONLY=true`,在 `mcp.gainium.io/read` 处提供):** 暴露并仅允许 9 个 `readOnlyHint` 工具 — `run_backtest` 和所有写入工具被排除
- **令牌受众绑定(OAuth 模式):** 当设置了 `GAINIUM_MCP_PUBLIC_URL` 时,服务器将 `<public-url><http-path>` 视为其 RFC 8707 资源。内省的访问令牌的 `aud` 是 **不同** 资源时会被拒绝 — 为 `mcp.gainium.io/read` 铸造的令牌不能在 `mcp.gainium.io/mcp` 上重放,反之亦然。没有 `aud` 的令牌(旧版授权)仍然被接受。
## 开发
```bash
# 克隆并安装
git clone https://github.com/gainium/gainium-mcp.git
cd gainium-mcp
npm install
# 构建
npm run build
# 本地运行(用于测试)
export GAINIUM_API_KEY=您的密钥
export GAINIUM_API_SECRET=您的机密
node dist/server.js
# 以 HTTP/SSE 模式运行
export GAINIUM_MCP_TRANSPORT=http
export GAINIUM_MCP_PORT=3000
node dist/server.js
```
## 架构
```
gainium-mcp/
├── src/
│ ├── server.ts # MCP 服务器 + 工具定义(stdio + HTTP/SSE 传输)
│ └── gainium-client.ts # 用于 Gainium API v2 的 HMAC 身份验证 HTTP 客户端
├── dist/ # 编译输出(发布到 npm)
├── package.json
├── tsconfig.json
└── README.md
```
## 许可证
MIT