内容
# Questrade MCP 服务器
Questrade 交易 API 的 MCP 服务器。使用它从兼容 MCP 的客户端(Claude、ChatGPT、Cursor 等)检查投资组合数据、报价、市场历史、订单和账户活动。
该服务器围绕结果导向的工具设计:每个工具都执行必要的 Questrade API 协调工作,以便代理可以更少的往返次数获得完整的结果。
## 目录
- [快速入门](#快速入门)
- [MCP 功能](#mcp-功能)
- [工具](#工具)
- [配置](#配置)
- [令牌管理](#令牌管理)
- [实时数据说明](#实时数据说明)
- [开发设置](#开发设置)
- [项目结构](#项目结构)
- [Docker](#docker)
- [CI/CD](#cicd)
- [安全](#安全)
- [贡献](#贡献)
- [安全策略](#安全策略)
- [发布流程](#发布流程)
- [许可证](#许可证)
## 快速入门
### 前提条件
- Node.js 22+
- 具有启用 API 访问权限的 Questrade 账户
### 1) 克隆、安装、构建
```bash
git clone https://github.com/DrWheelicus/questrade-mcp-server.git
cd questrade-mcp-server
npm install
npm run build
```
### 2) 获取 Questrade 刷新令牌
1. 打开 Questrade API 中心
2. 注册个人应用(或重用现有应用)
3. 输入设备名称和描述
4. 点击 **创建**
5. 选择 **新设备**
6. 选择 **生成新令牌**
7. 复制刷新令牌并将其粘贴到 .env 文件中
> [!WARNING]
> 刷新令牌是机密的,不应共享。如果丢失,需要生成新的令牌。(步骤 5-7)
### 3) 将服务器添加到 MCP 客户端
使用以下配置(替换为本地绝对路径):
```json
{
"mcpServers": {
"questrade": {
"command": "node",
"args": ["/absolute/path/to/Questrade/dist/index.js"],
"env": {
"QUESTRADE_REFRESH_TOKEN": "<your-token>"
}
}
}
}
```
常见位置:
- Claude Desktop:`~/Library/Application Support/Claude/claude_desktop_config.json`(macOS)或 `%APPDATA%\Claude\claude_desktop_config.json`(Windows)
- Claude Code:项目 `.mcp.json` 或 `~/.claude/mcp.json`
- Cursor:设置 -> MCP 服务器
> [!NOTE]
> 在某些 Windows MSIX 安装中,Claude Desktop 可能读取虚拟配置路径而不是:`%LOCALAPPDATA%\Packages\Claude_pzs8sxrjxfjjc\LocalCache\Roaming\Claude\claude_desktop_config.json`。
### 4) 验证
重启 MCP 客户端并询问:
> 显示我的投资组合
## MCP 功能
- **工具**:专为投资组合和市场数据操作而设计的工具
- **传输支持**:`stdio` 用于本地客户端,Streamable HTTP 用于远程客户端
- **验证**:使用 Zod 模式验证工具输入
- **令牌生命周期管理**:加密持久性和自动刷新
此服务器当前公开 MCP **工具**(不是提示/资源)。
## 工具
| 工具 | 描述 |
| ---- | ----------- |
| `getPortfolio` | 跨账户的完整投资组合概览,包括仓位和余额 |
| `getPositions` | 特定账户中持有的仓位 |
| `getBalances` | 账户的现金余额和购买力 |
| `lookupSymbol` | 按 ticker/名称搜索并返回符号详细信息和实时报价 |
| `getQuotes` | 按 ticker 名称或符号 ID 批量获取一级报价 |
| `getPriceHistory` | 历史 OHLCV 蜡烛,间隔从 1 分钟到每年 |
| `getOrders` | 订单历史记录,包含状态和日期筛选器 |
| `getAccountActivity` | 组合活动和执行时间线 |
## 配置
所有运行时配置均基于环境:
| 变量 | 必需 | 默认值 | 描述 |
| -------- | -------- | ------- | ----------- |
| `QUESTRADE_REFRESH_TOKEN` | 是(首次运行) | - | Questrade 的 OAuth 刷新令牌 |
| `QUESTRADE_ENVIRONMENT` | 否 | `production` | `production` 或 `practice` |
| `QUESTRADE_MCP_TRANSPORT` | 否 | `stdio` | `stdio` 或 `http` |
| `QUESTRADE_MCP_PORT` | 否 | `3100` | HTTP 传输端口 |
| `QUESTRADE_ENCRYPTION_KEY` | 否 | 机器导出 | 覆盖令牌存储的加密密钥 |
| `LOG_LEVEL` | 否 | `info` | `fatal`, `error`, `warn`, `info`, `debug`, `trace` |
CLI 标志 `--transport` 覆盖 `QUESTRADE_MCP_TRANSPORT`。
### HTTP 模式(远程客户端)
```bash
QUESTRADE_REFRESH_TOKEN=<your-token> node dist/index.js --transport=http
```
服务器端点:
- `http://localhost:3100/mcp`
## 令牌管理
Questrade 使用一次性刷新令牌。该服务器:
1. 在首次启动时交换初始刷新令牌
2. 使用 AES-256-GCM 加密和存储令牌材料
3. 在到期前主动刷新访问权限
4. 在刷新后重试 `401` 响应
令牌存储路径:
| 平台 | 路径 |
| -------- | ---- |
| Windows | `%APPDATA%\questrade-mcp\token.enc` |
| macOS | `~/Library/Application Support/questrade-mcp/token.enc` |
| Linux | `~/.config/questrade-mcp/token.enc` |
首次成功启动后,`QUESTRADE_REFRESH_TOKEN` 仅在缓存令牌过期时需要再次使用。
## 实时数据说明
Questrade 需要付费的市场数据订阅才能获取实时报价。没有订阅,`getQuotes` 返回具有每日交换限制的快照报价,并可能回落到延迟数据。使用 `isDelayed` 在报价响应中检测这一点。
## 开发设置
```bash
npm install
npm run dev
npm run build
npm run lint
npm run typecheck
npm test
```
### MCP 检查器
```bash
npx @modelcontextprotocol/inspector node dist/index.js
```
## 项目结构
```text
.
├── src/
│ ├── index.ts # 服务器入口点和传输选择
│ ├── server.ts # MCP 服务器和工具注册
│ ├── config.ts # 环境/配置解析
│ ├── log.ts # 记录器设置
│ ├── auth/ # 令牌持久性和刷新
│ ├── client/ # Questrade API 客户端和速率限制
│ ├── tools/ # MCP 工具实现
│ ├── transports/ # stdio 和 HTTP 传输处理程序
│ └── types/ # 共享 API/域类型
├── tests/ # 单元/集成测试
├── .github/workflows/ # CI/CD 工作流
└── Dockerfile
```
## Docker
构建并运行 HTTP 传输:
```bash
docker build -t questrade-mcp .
docker run -p 3100:3100 -e QUESTRADE_REFRESH_TOKEN=<your-token> questrade-mcp
```
## CI/CD
- **CI** 在推送/拉取请求到 `main`:类型检查、lint、构建、测试、`npm audit`、依赖项审查
- **CD** 在与 `v*.*.*` 匹配的标签上:多架构 Docker 镜像到 GHCR 和 GitHub 发布
## 安全
- 令牌材料加密存储(AES-256-GCM)
- 刷新令牌按设计轮换(Questrade 行为)
- 从日志中删除令牌值
- 只读服务器范围(无交易工具)
- 所有工具参数的输入验证(Zod)
- HTTP 传输使用每个客户端的会话隔离
- Docker 镜像以非 root 用户运行
## 贡献
参见 `CONTRIBUTING.md` 获取贡献者设置、质量检查和 PR 流程。
GitHub 问题和 PR 模板位于 `.github/` 中,以保持报告和审查的一致性。
## 安全策略
参见 `SECURITY.md` 获取如何私密报告漏洞的信息。
## 发布流程
参见 `RELEASE.md` 获取基于标签的发布检查清单和验证步骤。
## 许可证
专有 - 保留所有权利。
未经版权所有者的明确书面许可,不得复制、修改、重新分配、 sublicense 或使用此代码。