内容
# 施瓦布MCP服务器
一个模型上下文协议(MCP)服务器,使像Claude这样的AI助手能够安全地与施瓦布账户和市场数据进行交互, 通过官方施瓦布API。
## 你可以做的事情
询问Claude:
- "显示我的施瓦布账户余额和持仓"
- "获取AAPL、GOOGL和MSFT的实时报价"
- "今天的$SPX市场动向是什么?"
- "显示TSLA的期权链,包含希腊字母"
- "获取过去30天的交易记录"
- "搜索与技术相关的ETF"
- "检查市场是否开放"
## 非官方MCP服务器
这是一个非官方的、社区开发的TypeScript MCP服务器,适用于施瓦布。它未经施瓦布的批准、认可或认证。它按原样提供,其功能可能不完整或不稳定。请自担风险,特别是在处理财务数据或交易时。
## 概述
该MCP服务器作为AI助手和施瓦布API之间的桥梁,提供:
- **安全OAuth认证**:使用PKCE实施施瓦布的OAuth 2.0流程, 实现安全认证
- **全面的交易工具**:访问账户、订单、报价和交易
- **市场数据工具**:实时报价、价格历史、市场时间、市场动向和期权链
- **账户隐私**:内置账户标识符清洗,保护敏感信息
- **仅限本地**:在您的机器上运行,带有本地HTTPS服务器和基于文件的令牌存储
## 功能
### 交易工具
- **账户管理**
- `getAccounts`:检索所有账户信息,包括持仓和余额
- `getAccountNumbers`:获取账户标识符列表
- **订单管理**
- `getOrder`:按ID获取订单
- `getOrders`:获取订单,并按状态、时间范围和符号过滤
- `getOrdersByAccountNumber`:按账户编号获取订单
- `cancelOrder`:取消订单(实验性)
- `placeOrder`:下订单(实验性)
- `replaceOrder`:替换订单(实验性)
- **市场报价**
- `getQuotes`:获取多个符号的实时报价
- `getQuoteBySymbolId`:获取单个符号的详细报价
- **交易历史**
- `getTransactions`:检索所有账户的交易历史, 并带有日期过滤
- **用户偏好**
- `getUserPreference`:检索用户交易偏好和设置
### 市场数据工具
- **仪器搜索**
- `searchInstruments`:搜索具有基本/参考数据的证券符号
- **价格历史**
- `getPriceHistory`:获取具有可自定义周期和频率的历史价格数据
- **市场时间**
- `getMarketHours`:按日期检查市场营业时间
- `getMarketHoursByMarketId`:获取特定市场信息
- **市场动向**
- `getMovers`:按指数查找顶级市场动向($SPX,$COMPX,$DJI)
- **期权链**
- `getOptionChain`:检索具有希腊字母的完整期权链数据
- `getOptionExpirationChain`:获取期权到期日期
## 先决条件
1. **施瓦布开发者账户**:在[施瓦布开发者门户](https://developer.schwab.com)注册
2. **Node.js**:版本20.x或更高(推荐22.x)
## 开始使用
### 快速设置
```bash
git clone <仓库网址>
cd schwab-mcp
npm install
# 配置环境
cp .env.example .env
# 使用施瓦布应用凭证编辑.env
# 启动MCP服务器(首次运行时将提示OAuth)
npm run start
```
### 配置
#### 1. 创建施瓦布应用
1. 登录[施瓦布开发者门户](https://developer.schwab.com)
2. 创建一个新应用,包含:
- **应用名称**:您的MCP服务器名称(例如“My Schwab MCP”)
- **回调网址**:`https://localhost:3000/callback`
- **应用类型**:个人
3. 记录您的**应用密钥**(客户端ID)并生成**应用密钥**
#### 2. 配置环境变量
复制`.env.example`文件到`.env`并填写您的凭证:
```bash
cp .env.example .env
```
编辑`.env`:
```env
# 施瓦布OAuth配置
SCHWAB_CLIENT_ID=您的施瓦布应用密钥
SCHWAB_CLIENT_SECRET=您的施瓦布应用密钥
# OAuth重定向URI(必须与您在施瓦布开发者门户配置的URI匹配)
SCHWAB_REDIRECT_URI=https://localhost:3000/callback
# 可选:HTTPS服务器端口(默认:3000)
PORT=3000
# 可选:日志级别(trace,debug,info,warn,error,fatal)
LOG_LEVEL=info
# 可选:环境(development,staging,production)
ENVIRONMENT=production
```
#### 3. 首次运行 - OAuth认证
在首次运行时,服务器将:
1. 在`.certs/`目录中生成自签名证书(无需OpenSSL)
2. 在`https://localhost:3000`启动HTTPS服务器
3. 打开浏览器到施瓦布授权页面
4. 授权后,令牌将保存到`.auth/`目录
5. MCP服务器将启动并准备使用
```bash
npm run start
```
**注意**:您可能需要信任浏览器或系统中的自签名证书。证书仅用于本地OAuth回调,并使用Node.js加密库自动生成。
## 用法
### 克劳德桌面配置
将服务器添加到您的克劳德桌面配置文件:
**macOS**:`~/Library/Application Support/Claude/claude_desktop_config.json`
**Windows**:`%APPDATA%\Claude\claude_desktop_config.json`
```json
{
"mcpServers": {
"schwab": {
"command": "npx",
"args": [
"tsx",
"/path/to/schwab-mcp/src/index.ts"
],
"env": {
"SCHWAB_CLIENT_ID": "您的应用密钥",
"SCHWAB_CLIENT_SECRET": "您的应用密钥",
"SCHWAB_REDIRECT_URI": "https://localhost:3000/callback"
}
}
}
}
```
或者,如果您更喜欢先构建然后运行编译后的JavaScript:
```json
{
"mcpServers": {
"schwab": {
"command": "node",
"args": [
"/path/to/schwab-mcp/dist/index.js"
],
"env": {
"SCHWAB_CLIENT_ID": "您的应用密钥",
"SCHWAB_CLIENT_SECRET": "您的应用密钥",
"SCHWAB_REDIRECT_URI": "https://localhost:3000/callback"
}
}
}
}
```
注意:第一个使用`tsx`的选项是推荐的,因为它不需要构建步骤。
重启克劳德桌面。服务器将通过stdio传输连接。
### 示例命令
连接后,您可以要求克劳德:
- "显示我的施瓦布账户余额"
- "获取AAPL的报价"
- "今天的$SPX市场动向是什么?"
- "显示TSLA的期权链"
- "获取过去一周的交易记录"
## 架构
### 技术栈
- **运行时**:Node.js与TypeScript
- **认证**:使用`@sudowealth/schwab-api`的OAuth 2.0与PKCE
- **API客户端**:`@sudowealth/schwab-api`用于类型安全的施瓦布API访问
- **MCP框架**:`@modelcontextprotocol/sdk`与stdio传输
- **状态管理**:`.auth/`目录中的基于文件的令牌存储
- **OAuth服务器**:带有HTTPS的Express,用于OAuth回调处理
### 安全功能
1. **OAuth 2.0与PKCE**:防止授权代码拦截的安全认证流程
2. **本地令牌存储**:令牌存储在本地`.auth/`目录(从未发送到外部服务器)
3. **HTTPS本地主机**:用于安全OAuth回调的自签名证书
4. **自动令牌刷新**:令牌在过期前5分钟刷新
5. **账户清洗**:敏感账户标识符自动替换为显示名称
6. **机密遮蔽**:日志中自动遮蔽敏感数据
## 开发
### 可用脚本
```bash
npm run start # 启动MCP服务器
npm run dev # 以开发模式启动(与启动相同)
npm run build # 将TypeScript编译为JavaScript
npm run typecheck # 运行TypeScript类型检查
npm run lint # 运行ESLint
npm run format # 使用Prettier格式化代码
npm run validate # 运行类型检查和linting
```
### 项目结构
```
schwab-mcp/
├── .auth/ # OAuth令牌(git-ignored)
├── .certs/ # 自签名证书(git-ignored)
├── src/
│ ├── index.ts # 主要MCP服务器入口点
│ ├── auth/ # OAuth认证客户端
│ ├── server/ # OAuth HTTP服务器和证书生成
│ ├── shared/ # 共享实用程序(日志记录,令牌存储)
│ └── tools/ # MCP工具实现
├── .env # 环境变量(git-ignored)
└── .env.example # 环境变量示例
```
### 调试
服务器包含具有可配置级别的综合日志记录:
- **日志级别**:trace,debug,info,warn,error,fatal
- 通过`.env`中的`LOG_LEVEL`环境变量设置
启用调试日志记录以查看详细的OAuth流程和API交互:
```env
LOG_LEVEL=debug
```
### 错误处理
服务器实施了强大的错误处理,包含特定的错误类型:
- **认证错误(401)**:提示重新认证
- **客户端错误(400)**:无效参数,缺少数据
- **服务器错误(500)**:API失败,配置问题
- 所有错误都包含请求ID,用于施瓦布API故障排除
## 贡献
1. 分叉仓库
2. 创建一个功能分支(`git checkout -b feature/amazing-feature`)
3. 提交您的更改(`git commit -m 'Add amazing feature'`)
4. 推送到分支(`git push origin feature/amazing-feature`)
5. 打开拉取请求
## 许可证
MIT
## 故障排除
### 常见问题
1. **浏览器中的“证书错误”**
- 这是自签名证书的预期行为
- 在OAuth流程期间接受证书警告
- 证书仅用于`https://localhost:3000/callback`
2. **“找不到模块”错误**
- 运行`npm install`以确保所有依赖项都已安装
- 确保您使用的是Node.js 20.x或更高版本
3. **认证失败**
- 验证您的重定向URI是否完全匹配:`https://localhost:3000/callback`
- 检查`.env`中的施瓦布应用凭证是否正确
- 启用调试日志记录:`.env`中的`LOG_LEVEL=debug`
4. **“端口已被占用”错误**
- 在`.env`中将PORT更改为其他值
- 确保没有其他进程使用端口3000
## 最近更新
- **仅限本地架构**:从Cloudflare Workers迁移到本地Node.js服务器
- **基于文件的令牌存储**:令牌安全地存储在本地`.auth/`目录中
- **HTTPS OAuth流程**:自签名证书,用于安全的本地OAuth回调
- **_stdio传输**:使用标准的MCP SDK与stdio进行Claude Desktop集成
## 致谢
- 使用[模型上下文协议](https://modelcontextprotocol.io/)
- 由[`@sudowealth/schwab-api`](https://www.npmjs.com/package/@sudowealth/schwab-api)提供支持
- 使用[`@modelcontextprotocol/sdk`](https://www.npmjs.com/package/@modelcontextprotocol/sdk)构建