Schwab MCP
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Schwab MCP show me my portfolio summary and today's P&L"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Schwab MCP
一个只读的 Charles Schwab(嘉信理财)Model Context Protocol 服务器。 Claude、GPT 等 AI agent 可以通过它查询你的持仓、账户余额、实时报价、K 线、期权链、订单和交易记录。
本项目不能下单、改单、撤单,代码里也没有任何交易接口,只负责把 Schwab 的数据安全地交给 agent。 非 Schwab 官方项目,也不构成投资建议。
特性
持仓 + 实时价格:
get_positions(include_quotes=true)一次调用返回每个持仓的成本、市值、浮盈亏、当日盈亏、 仓位占比,并附带实时报价组合总览:
get_portfolio_summary汇总所有账户的总资产、现金、当日盈亏、资产类别配置和前 N 大持仓 (同一只股票在多个账户里的持仓会合并)行情:实时报价(股票、ETF、指数、期货、期权及希腊值)、K 线、期权链、开闭市时间、涨跌榜、基本面搜索
隐私:账号默认脱敏成
****1234,Schwab 的 account hash 不会出现在输出里;agent 可以用尾号或昵称指定账户为 LLM 优化的输出:snake_case 字段、去掉空值、数字取整、时间统一为美东时间、预先算好百分比,既省 token 又不容易算错
自动续期:access token(30 分钟)自动刷新;refresh token 7 天后过期,重新执行
schwab-mcp auth即可, 正在运行的 server 不需要重启两种传输方式:stdio(Claude Desktop / Claude Code / Codex CLI / OpenAI Agents SDK)和 Streamable HTTP (必须配置 Bearer token)
Related MCP server: Schwab MCP Server
工具一览
工具 | 说明 |
| 全部账户总览:总资产、现金、当日/浮动盈亏、资产配置、前 N 大持仓、各账户占比 |
| 各账户持仓明细; |
| 账户列表:类型(MARGIN/CASH)、昵称、总资产、现金、购买力等 |
| 实时报价:最新价、买卖盘、涨跌幅、成交量、日内/52 周区间;期权带希腊值;可选基本面 |
| K 线(1 分钟到月线)+ 区间统计(涨跌幅、最高最低、均量),支持预设周期或起止日期 |
| 期权链:bid/ask/mark、成交量、未平仓量、IV、希腊值,按到期日排序 |
| 某个标的的所有期权到期日 |
| 开闭市时间(盘前/盘中/盘后),并标出当前所处时段 |
| 指数/交易所的涨跌榜、成交量榜 |
| 按代码或公司名搜索; |
| 最近 60 天内的订单(含成交明细和平均成交价),只读 |
| 交易流水:买卖、分红、利息、出入金、费用 |
| 登录状态,以及距离 7 天过期还剩多久 |
| 当前美东时间和 UTC 时间(方便模型做日期计算) |
另外提供一个 prompt 模板 portfolio_review,一键生成组合复盘。
快速开始
1. 申请 Schwab 开发者 App(只需一次)
用你的 Schwab 账号登录 https://developer.schwab.com,进入 Dashboard → Apps → Create App。
API Product 选 Accounts and Trading Production(如果能选,再加上 Market Data Production)。
Callback URL 填
https://127.0.0.1:8182(末尾不要加/,后续配置必须与这里一字不差)。创建后的状态通常是
Approved - Pending,要等变成Ready For Use(可能需要几天)才能使用。在 App 详情页拿到 App Key 和 Secret。
2. 安装
需要 Python ≥ 3.10,推荐使用 uv:
git clone https://github.com/<you>/Schwab-MCP.git
cd Schwab-MCP
uv sync # 或者:python -m venv .venv && .venv/bin/pip install -e .3. 配置凭据
mkdir -p ~/.config/schwab-mcp
cp .env.example ~/.config/schwab-mcp/.env
chmod 600 ~/.config/schwab-mcp/.env
# 编辑该文件,填入 SCHWAB_CLIENT_ID(App Key)和 SCHWAB_CLIENT_SECRET(Secret)配置的读取顺序(先读到的优先):真实环境变量 → --env-file / $SCHWAB_MCP_ENV_FILE → 当前目录的 .env
→ ~/.config/schwab-mcp/.env。
4. 登录(每 7 天一次)
uv run schwab-mcp auth浏览器会打开 Schwab 登录页 → 登录并勾选要授权的账户 → 浏览器跳转到 https://127.0.0.1:8182/?code=...,
页面打不开是正常的 → 把地址栏里的完整 URL 粘贴回终端。Token 保存在 ~/.config/schwab-mcp/token.json(权限 600)。
uv run schwab-mcp status # 查看登录状态,并测试 API 连通性5. 接入你的 agent
把下面的 /ABS/PATH/Schwab-MCP 换成仓库的绝对路径。如果凭据已经写在 ~/.config/schwab-mcp/.env 里,
env 部分可以省略。
编辑 claude_desktop_config.json(macOS 位于 ~/Library/Application Support/Claude/):
{
"mcpServers": {
"schwab": {
"command": "uv",
"args": ["--directory", "/ABS/PATH/Schwab-MCP", "run", "schwab-mcp"],
"env": {
"SCHWAB_CLIENT_ID": "your-app-key",
"SCHWAB_CLIENT_SECRET": "your-app-secret"
}
}
}
}Claude Desktop 可能找不到 uv。如果启动失败,把 "command" 改成 which uv 输出的绝对路径。
claude mcp add schwab --scope user -- uv --directory /ABS/PATH/Schwab-MCP run schwab-mcp~/.codex/config.toml:
[mcp_servers.schwab]
command = "uv"
args = ["--directory", "/ABS/PATH/Schwab-MCP", "run", "schwab-mcp"]import asyncio
from agents import Agent, Runner
from agents.mcp import MCPServerStdio
async def main():
async with MCPServerStdio(
params={"command": "uv", "args": ["--directory", "/ABS/PATH/Schwab-MCP", "run", "schwab-mcp"]},
) as schwab:
agent = Agent(name="Portfolio assistant", mcp_servers=[schwab],
instructions="用中文回答,只使用工具返回的数据。")
result = await Runner.run(agent, "我今天的持仓表现怎么样?哪只股票拖累最大?")
print(result.final_output)
asyncio.run(main())export SCHWAB_MCP_HTTP_TOKEN=$(python -c "import secrets; print(secrets.token_urlsafe(32))")
uv run schwab-mcp serve --transport http --port 8765 # 端点:http://127.0.0.1:8765/mcp
# 通过隧道或反向代理暴露时,加上 --allowed-host your.domain.com所有请求都必须带 Authorization: Bearer $SCHWAB_MCP_HTTP_TOKEN,否则返回 401。
from openai import OpenAI
resp = OpenAI().responses.create(
model="gpt-5", # 任意支持远程 MCP 工具的模型
tools=[{
"type": "mcp",
"server_label": "schwab",
"server_url": "https://your.domain.com/mcp",
"headers": {"Authorization": "Bearer <SCHWAB_MCP_HTTP_TOKEN>"},
"require_approval": "never",
}],
input="列出我的前五大持仓和它们今天的涨跌幅",
)
print(resp.output_text)⚠️ 这相当于把你的券商数据暴露到公网。只在确实需要时使用:token 要足够长,放在 HTTPS 后面,用完就关。 ChatGPT 网页版的自定义连接器只支持 OAuth 或无认证,所以不建议直接接入。GPT 用户请优先使用 Codex CLI 或 Agents SDK(本地 stdio,数据只会发给模型,不会暴露在公网上)。
6. 试一试
「我的组合今天表现如何?」→
get_portfolio_summary「列出我所有持仓的实时价格和浮盈」→
get_positions(include_quotes=true)「NVDA 和 AAPL 现在多少钱?」→
get_quotes「AAPL 过去 6 个月的走势」→
get_price_history(period="6M")「我的 Roth IRA 这个月收到多少分红?」→
get_transactions(account="Roth IRA", types=["DIVIDEND_OR_INTEREST"])「现在美股开盘了吗?」→
get_market_hours
配置项
环境变量 | 默认值 | 说明 |
| — | App Key(必填) |
| — | App Secret(必填) |
|
| 必须与开发者后台填写的完全一致 |
|
| Token 文件位置 |
|
| 账号脱敏;设为 |
| — | HTTP 传输使用的 Bearer token(HTTP 模式必填) |
|
| 单次请求超时(秒) |
|
| 日志级别(日志只写 stderr,不会干扰 stdio 协议) |
命令行:schwab-mcp [serve] [--transport stdio|http] [--host] [--port] [--allowed-host HOST]、
schwab-mcp auth [--no-browser]、schwab-mcp status,以及全局参数 --env-file PATH。
安全与隐私
只读:客户端只实现了 GET 接口,所有工具都带 MCP 的
readOnlyHint注解。Token 存储:
token.json以0600权限原子写入,所在目录为0700。不要把它和.env提交到 git(.gitignore已排除)。账号脱敏:输出中的完整账号会被替换成
****1234,交易描述之类的自由文本也不例外;hash 值从不输出。数据流向:agent 调用工具后,返回的数据会发给你所用的模型提供方(Anthropic、OpenAI 等),请按自己的隐私要求取舍。
HTTP 模式:未设置
SCHWAB_MCP_HTTP_TOKEN时拒绝启动;--insecure-no-auth只允许绑定回环地址。 绑定 127.0.0.1 时默认开启 DNS rebinding 防护。
常见问题
现象 | 处理方法 |
工具提示 | 运行 |
登录时 Schwab 提示 callback/redirect 不匹配 |
|
HTTP 401 | App 还没到 |
HTTP 403 | App 没有开通对应的 API Product(账户或行情) |
HTTP 429 | 触发了 Schwab 的频率限制(约 120 次/分钟),server 会自动退避重试 |
Claude Desktop 里看不到工具 | 检查 |
开发
uv sync
uv run pytest # 针对模拟的 Schwab API 运行,不需要真实账户
uv run ruff check src tests
npx @modelcontextprotocol/inspector uv run schwab-mcp # 在浏览器里交互式调试工具代码结构和设计取舍见 docs/DESIGN.md。
参考项目
设计参考了以下开源项目,具体借鉴点见 docs/DESIGN.md:
jkoelker/schwab-mcp:Python,基于 schwab-py;交易需要审批,
--json精简输出sudowealth/schwab-mcp:TypeScript + Cloudflare Workers;账号脱敏、日志脱敏
alexgolec/schwab-py:社区 Schwab API 客户端,OAuth 流程和接口参数的权威参考
License
MIT
Available Tools
14 toolsget_auth_statusARead-onlyIdempotent
Check whether the Schwab login is valid and when it expires (Schwab requires a new browser login every 7 days). Call this first if other tools report authentication errors.
Inputs: no named parameters. Returns: object
get_current_timeARead-only
Current date and time in US/Eastern (the exchange clock) and UTC. Useful before date math.
Inputs: no named parameters. Returns: object
get_market_hoursARead-onlyIdempotent
Trading sessions (pre-market, regular, post-market) for a day and whether the market is open.
For today it also reports which session is active right now (session_now).
Inputs: date, markets. Returns: object
get_moversCRead-onlyIdempotent
Top movers in an index or exchange, sorted by volume, trades or % change.
Inputs: sort, index, frequency. Returns: object
get_option_chainARead-onlyIdempotent
Option chain with bid/ask/mark, volume, open interest, implied volatility and greeks, nearest expirations first. Use get_option_expirations to pick dates.
Inputs: symbol (required), to_date, from_date, strike_count, +2 more. Returns: object
get_option_expirationsBRead-onlyIdempotent
All listed option expiration dates for an underlying, with days to expiration.
Inputs: symbol (required). Returns: object
get_ordersBRead-onlyIdempotent
Recent orders (open, filled, cancelled...) with legs, fills and average fill price. Read-only.
Inputs: days, status, account, max_results. Returns: object
get_portfolio_summaryARead-onlyIdempotent
One-shot overview across all accounts: total value, cash, today's P/L, unrealized P/L, allocation by asset type, top holdings (merged across accounts) and per-account totals.
Inputs: top_n. Returns: object
get_positionsARead-onlyIdempotent
Holdings per account: quantity, average cost, market value, unrealized and today's P/L, and weight in the account. Sorted by market value. Set include_quotes=true for live last/mark prices.
Inputs: symbol, account, include_quotes. Returns: object
get_price_historyBRead-onlyIdempotent
OHLCV candles plus a summary (change, % change, high/low, average volume) for a period.
Inputs: symbol (required), period, end_date, interval, +3 more. Returns: object
get_quotesBRead-onlyIdempotent
Real-time quotes: last, bid/ask, day change and %, volume, day range, 52-week range, plus greeks for options and optional fundamentals.
Inputs: symbols (required), include_fundamentals. Returns: object
get_transactionsBRead-onlyIdempotent
Account history: trades, dividends, interest, deposits/withdrawals and fees, newest first.
Inputs: days, types, symbol, account, +1 more. Returns: object
list_accountsARead-onlyIdempotent
List the linked Schwab accounts with type, nickname and key balances (total value, cash,
buying power). Use the returned account labels with the other tools.
Inputs: no named parameters. Returns: object
search_instrumentsBRead-onlyIdempotent
Look up instruments by symbol or company name, or get fundamentals for a symbol.
Inputs: query (required), search_type. Returns: object
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 14 tools
Most tools target distinct resource/action pairs, and descriptions clarify boundaries. There is some conceptual overlap between get_positions and get_portfolio_summary, and between get_orders and get_transactions, but they are distinguished by detail level and scope.
All tool names use snake_case with a consistent verb_noun pattern such as get_*, list_*, and search_*. The naming is predictable throughout the set.
14 tools is well-scoped for a read-only Schwab brokerage and market-data server. Each tool covers a clear area such as accounts, quotes, options, orders, or time, without excessive duplication.
The read-only surface is strong: auth, accounts, positions, portfolio, orders, transactions, quotes, price history, options, market hours, movers, instruments, and time are all covered. Missing write/trading operations like placing or cancelling orders and minor extras like watchlists or news are the main gaps.
Maintenance
Related MCP Connectors
Trading MCP server for AI agents, with live market data, account reads and controlled execution.
Agentic brokerage access to a US brokerage account: quotes, orders, positions, cash and documents.
Connect brokerage accounts to AI assistants: holdings, orders, asset lookup, and approved trading.
Read-only finance MCP server. Connects your banks, cards, payment apps, books and payroll into one ledger for your AI. Can't move money. Open source (AGPL-3.0), free during beta.
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceA server that implements the Model Context Protocol for Schwab API, allowing access to account information, positions, stock quotes, and order/transaction history designed for integration with Large Language Models.68MIT
- AlicenseAqualityDmaintenanceA read-only MCP server that provides access to Charles Schwab account data and market information, including portfolio positions, real-time quotes, options chains, price history, and account balances through AI assistants.9MIT
- AlicenseNot gradedqualityDmaintenanceA read-only Model Context Protocol server that connects your Schwab brokerage account to LLM applications for portfolio monitoring and market data retrieval.MIT
- FlicenseNot gradedqualityDmaintenanceA read-only MCP server that exposes Interactive Brokers and Moomoo brokerage accounts as tools, enabling natural-language queries across positions, trade history, realized P&L, and sector exposure in one merged view.-