
Schwab Mcp
io.github.lonniev由 GitHub 帳號 lonniev 發布v0.14.0更新於 Oct 24, 2026
Multi-tenant FastMCP server for Charles Schwab brokerage data, monetized via DPYC Tollbooth
概覽
遠端 MCP 伺服器,讓 AI 助理以唯讀方式存取你的嘉信理財(Charles Schwab)帳戶資料,依每次呼叫以比特幣閃電網路 sats 付費。
- 可以做什麼
- 讀取持倉(自動辨識選擇權價差)、餘額、購買力與當日損益
- 取得報價、市場漲跌排行、交易時段、歷史價格與標的搜尋
- 抓取含希臘值、隱含波動率、價外百分比與未平倉量門檻的選擇權鏈
- 檢視委託與成交紀錄,支援多腳價差與單筆明細
- 管理付費工作階段:查詢餘額與價格、用閃電網路購買額度、證明 npub 身分、完成 Schwab OAuth 並儲存帳戶雜湊
- 適用情境
- 適合想用自然語言討論自己的嘉信持倉、篩選選擇權價差、依策略規則檢視當日交易,或取得收盤報告,而不必切換到券商網頁介面的情境。
- 執行需求
- 遠端端點 schwab-mcp.fastmcp.app,透過 Streamable HTTP 與 OAuth 連線。需要 Nostr 金鑰對(npub;簽章需 nsec,或透過 Nostr 私訊做一次性證明)以及 Nostr 用戶端(如 Oxcart)。需以閃電錢包預先購買 api_sats 餘額,並透過瀏覽器 OAuth 授權連結 Schwab 帳戶;Schwab 更新權杖 7 天後過期。
安裝
在 SourceWeft 中
- 開啟 儀表板中的 Schwab Mcp,將其新增到工作區。
- 連接 所需的 憑證。它們會被私密儲存,絕不會在公開頁面上展示。
- 為需要使用其工具的對話啟用該服務。
Web executable,透過 Streamable HTTP。 遠端服務在工作區中設定後即可從網頁執行環境執行。
交給代理程式安裝
把這段提示詞貼上到 Claude Code、Codex、Cursor 等代理程式,或 SourceWeft 對話中。代理程式會讀取該伺服器的安裝指南,先向你展示發布者、端點和登入方式,經你同意後再把它新增到你的客戶端。金鑰不會寫進任何命令。
閱讀 https://sourceweft.com/mcp/io.github.lonniev%2Fschwab-mcp/install.md,並按其中說明把這個 MCP 伺服器接入我的客戶端。修改任何設定之前,先告訴我它的發布者、端點和登入方式,等我確認。不要把 API 金鑰寫進命令或我會提交的檔案;問我金鑰應從哪裡取得。其他 MCP 客戶端
把它新增到你客戶端的 mcpServers 設定中。 客戶端會在首次連接時完成 OAuth 登入。
{
"mcpServers": {
"schwab": {
"type": "http",
"url": "https://schwab-mcp.fastmcp.app/mcp"
}
}
}README
schwab-mcp
[Open Positions — Options Risk Profile]
Your brokerage data, conversationally. Ask your AI assistant about your positions, screen option spreads, audit today's trades against your strategy rules, and get end-of-day reports — all from natural language. The data cost? About 6 sats per session (~$0.005).
Why This Exists
The data in schwab-mcp is nothing you can't get from ThinkOrSwim, OptionAlpha, or Schwab's own web UI. What you can't get from those tools is a personal trading assistant that blends:
- Your live positions and account balances
- Real-time option chains with Greeks, IV, and OTM%
- Your trading strategy rules (credit floors, RWR targets, sector concentration limits)
- Market context (earnings calendars, VIX levels, sector rotation)
- All of the above in a single conversational turn
Ask "How would you judge my new trades for the day?" and get a structured audit against your criteria. Ask "What are three SPS candidates aligned with my strategy and balanced with my current book?" and get sector-aware, earnings-aware, IV-aware suggestions — grounded in your actual positions, not generic advice.
The AI does the synthesis. schwab-mcp provides the data bridge. You pay per-call in Bitcoin Lightning sats — no subscription, no KYC, no vendor lock-in. A full day of morning report + evening report + follow-up analysis costs about 6 sats (< $0.01).
Multi-tenant MCP server exposing Charles Schwab brokerage data to AI agents via FastMCP. Monetized via Tollbooth DPYC™ Lightning micropayments. Serves over Streamable HTTP with direct async httpx calls to api.schwabapi.com.
Don't Pester Your Customer™ (DPYC™) — API monetization for Entrepreneurial Bitcoin Advocates
Inspired by The Phantom Tollbooth by Norton Juster, illustrated by Jules Feiffer (1961).
The DPYC™ Economy
DPYC™ stands for Don't Pester Your Customer. It is a philosophy and protocol for API monetization that eliminates mid-session payment popups, subscription nag screens, and KYC friction.
How it works
-
Pre-funded balances -- Users buy credits (api_sats) via Bitcoin Lightning before using tools. Each tool call silently debits from their balance. No interruptions, no "please upgrade" modals. Credits expire after a
tranche_lifetimewindow set by the operator's pricing model. -
Nostr keypair identity -- Users are identified by a Nostr public key (
npub), not an email or password. One keypair per role, managed by the user. No account creation forms. -
Identity on the connection -- Every paid tool call names the patron's
npub; the connection proves it. A client holding the nsec signs each request (NIP-98). A client holding no key connects with OAuth and proves the npub once throughrequest_npub_proof/receive_npub_proof-- a human-in-the-loop Secure Courier exchange the patron approves in their Nostr client. The connection then holds the npub for the duration the patron chose, across MCP restarts. -
UUID-keyed tool identity -- Every tool is a
ToolIdentityobject with a deterministic UUID v5 derived from a capability name. Pricing hints come from thecategoryfield:Actual prices (api_sats) are set dynamically by the operator's pricing model in Neon.
-
Rollback on failure -- If the downstream API fails after a debit, credits are automatically rolled back via a compensating tranche. The user never pays for a failed call.
-
Social Contract -- The DPYC™ ecosystem is a voluntary community:
- Citizens -- Users who consume API services
- Operators -- Developers who run MCP services (like this one)
- Authorities -- Certify operators and collect a small tax on purchases
- First Curator -- The root of the chain, mints the initial cert-sat supply
Tools
Brokerage (paid -- credit-gated)
All paid tools take the patron's npub; the connection proves it.
Free
All brokerage tools are read-only. No orders are placed.
Architecture
- Multi-tenant: operator delivers
btcpay_host+btcpay_api_key+btcpay_store_id+app_key+secretvia Secure Courier (service="schwab-operator"); each patron authenticates via OAuth2 browser flow. Sessions are keyed by npub. No Schwab credentials in env vars - Direct httpx: thin
SchwabClientwrapper with bearer auth and proactive token refresh (no third-party Schwab SDK) - Tollbooth DPYC™: pre-funded Lightning balances, Authority-certified purchase orders, NeonVault (Postgres) for ledger persistence
- Registry discovery: OAuth2 collector URL resolved from DPYC™ registry at runtime (no
OAUTH_COLLECTOR_URLenv var needed) - Credential validation: operator credentials are validated at receive time --
btcpay_host,app_key, andsecretmust all be present before vaulting - Identity on the connection: a request signed with the npub's key (NIP-98), or an OAuth connection that holds the npub after one Secure Courier DM. Survives restarts; patron-chosen duration. Restricted tools (operator-only) need the operator's npub proven the same way.
Getting Started
This guide covers the full Tollbooth onboarding path -- from generating a Nostr identity to making your first brokerage data call. It applies to both Operators (who deploy schwab-mcp) and Patrons (who consume it through Claude.ai or another MCP client).
1. Get a Nostr Identity (npub)
Every participant in the DPYC™ ecosystem is identified by a Nostr keypair -- no email, no password, no vendor lock-in.
What is an npub? It is a public key in the Nostr protocol, encoded as a bech32 string starting with npub1.... Your corresponding private key (nsec1...) stays on your device. The npub is safe to share -- it is how the system knows who you are.
How to generate one:
- Install Oxcart (the preferred Nostr client for DPYC™ workflows; other clients have not been tested)
- Create an account -- the app generates your keypair automatically
- Find your npub in the app's profile/settings screen (it starts with
npub1...)
Alternatively, use a CLI key generator like nak: nak key generate
Operators should keep a separate npub for their service identity, distinct from their personal Nostr account.
2. Register as a DPYC™ Citizen
Before you can buy credits or operate a service, register your npub with the DPYC™ community:
- In Claude.ai (with the DPYC Oracle connected), call
how_to_join()to learn about citizenship - Follow the Oracle's instructions to register your npub
Citizenship is free and gives you a portable identity across the entire Tollbooth network.
3. For Operators -- Set Up Your BTCPay Store
The Operator collects Lightning payments from Patrons via BTCPay Server. You need:
- A BTCPay Server instance (self-hosted or hosted by your Authority)
- A Store ID and API Key with invoice creation permissions
These credentials are delivered via Secure Courier (see step 6), not set as environment variables.
4. For Operators -- Register with a Tollbooth Authority
Every Operator is sponsored by an Authority in the DPYC™ trust chain. The Authority certifies your purchase orders and collects a small fee (default 2%).
- On your own Schwab MCP, call
request_adoption(authority_npub=<your Authority's npub>, service_url=<your MCP endpoint>), signing the request with your operator nsec (NIP-98; Pricing Studio does this for you) - The Authority's owner approves it (
approve_operator_request), which creates your ledger entry and provisions your Neon database adoption_status(authority_npub=...)on your MCP readsprovisionedonce it is done
5. For Operators -- Fund Your Certification Balance
Before your service can issue credits to Patrons, you need cert-sats:
- Call
authority_purchase_credits(amount_sats=1000)on your Authority -- returns a Lightning invoice - Pay the invoice with any Lightning wallet
- Call
authority_check_payment(invoice_id="...")-- confirms settlement and credits your balance
Your cert-sat balance is consumed automatically when Patrons purchase credits from your service.
6. For Operators -- Deliver Credentials (Secure Courier)
The Operator must register a Schwab Developer app and deliver both BTCPay and Schwab API credentials via Secure Courier. Credentials never appear in chat.
Schwab Developer apps use app_key and secret as the vendor field names (these map to OAuth client_id and client_secret internally). The redirect_uri registered with Schwab should have no /callback suffix -- use the base collector URL exactly as shown in the registry.
The Secure Courier is a human-in-the-loop exchange: the operator consciously replies in their Nostr client. The relay is drained destructively after pickup -- messages are consumed, not left on the wire.
- Call
request_credential_channel(service="schwab-operator", sender_npub=<operator_npub>)-- it returns anonce, and a welcome DM arrives in your Nostr client (Oxcart) - In Oxcart, reply to the DM with:
- Call
receive_credentials(sender_npub=<operator_npub>, service="schwab-operator", nonce=<that nonce>)-- credentials are validated (btcpay_host,app_key, andsecretmust all be present) and vaulted
This is a one-time setup per deployment. Operator credentials are encrypted and stored in the NeonVault, persisting across server restarts.
7. For Patrons -- Buy Credits (api_sats)
Patrons pre-fund a satoshi balance and consume brokerage tools against it -- no per-request payment interruptions. This is the Don't Pester Your Customer™ philosophy in action. Credits are denominated in api_sats and expire after the operator-configured tranche_lifetime.
- Call
purchase_credits(amount_sats=500)-- returns a Lightning invoice with a checkout link - Pay the invoice with any Lightning wallet (Phoenix, Breez, Zeus, etc.)
- Call
check_payment(invoice_id="...")-- confirms settlement and credits your balance
Your balance depletes as you call paid tools. Recharge anytime with another purchase_credits call. Check your balance at any time with check_balance (free). Preview any tool's cost with check_price (free).
8. For Patrons -- Connect Your Schwab Account
You need to authorize schwab-mcp to read your Schwab account:
- Call
begin_oauth(npub=<your_npub>)to get an authorization URL - Open the URL in your browser and log in to Schwab
- Call
check_oauth_status(npub=<your_npub>)to confirm session activation - Call
get_account_numbers(npub=<your_npub>)to list your accounts and hashes - Call
update_patron_credential(npub=<your_npub>, field="account_hash", value=<hash>)to set your preferred account
9. Using Schwab Tools in Conversation
Once your session is active, ask your AI agent naturally:
- "Show me my positions" -- calls
get_brokerage_positions - "What's my account balance?" -- calls
get_brokerage_balances - "Get a quote for AAPL and MSFT" -- calls
get_stock_quote - "What are today's biggest gainers?" -- calls
get_market_movers - "Is the market open tomorrow?" -- calls
get_market_hours - "Look up the ticker for Berkshire Hathaway" -- calls
search_instruments - "Show me the GLD option chain for next month" -- calls
get_option_chain - "What are my recent orders?" -- calls
get_brokerage_orders - "Show me my trade history for the last week" -- calls
get_brokerage_transactions
Free tools are always available:
- "What's my schwab-mcp balance?" -- calls
check_balance - "Show me my account statement" -- calls
account_statement
Security
- npub identity -- All sessions are keyed by a Nostr public key. No email, no username, no password.
- Identity on the connection -- Tools carry no proof argument. A client holding the nsec signs each HTTP request (NIP-98, kind 27235); an OAuth client proves the npub once into its connection with
request_npub_proof/receive_npub_proof, which the patron approves in their Nostr client for a duration they choose (up to 30 days). - Secure Courier -- Credentials are exchanged over NIP-44 encrypted Nostr DMs. The relay is drained destructively after pickup; messages do not persist on the wire.
- NeonVault -- Credentials (
token_json) and ledger state are stored in Postgres with per-operator row isolation. No secrets in environment variables or chat history. - Operator credential isolation -- BTCPay and Schwab API credentials (
app_key,secret) are delivered via Secure Courier withservice="schwab-operator", validated at receive time, and never exposed in logs or responses.
Troubleshooting
Cold start / first tool call fails: The Horizon runtime may cold-start on the first request. Retry the tool call inline -- the server warms up within a few seconds and the second call succeeds.
"proof is required": Call request_npub_proof, reply to the DM, then receive_npub_proof(patron_npub, nonce) once. Your connection then holds the npub; pass only npub on later calls. Duration is patron-chosen. The proof survives MCP restarts.
"Insufficient credit balance": Call purchase_credits to top up. Use check_balance to see your current api_sats balance and tranche_lifetime expiry.
"Operator credentials not configured": This is an operator setup issue, not the patron's problem. The operator must complete the Secure Courier flow (step 6) to deliver app_key and secret.
Credential lifecycle states: Credentials move through pending (channel opened) -> delivered (DM sent by human) -> vaulted (picked up and validated). If receive_credentials returns a lifecycle state instead of success, it is not an error -- it is telling you where in the flow you are. Follow the guidance in the response.
OAuth token stored in vault: After a successful OAuth2 flow, the token_json is persisted in NeonVault. Sessions survive server restarts via the wheel's restore_oauth_session -- which detects expiration, refreshes the token via the provider, and persists the rotated pair back to vault. If the refresh token itself expires (Schwab: 7 days), the patron must re-run begin_oauth.
DPYC™ Community Resources
Deployment
schwab-mcp runs on Horizon. Any MCP client (Claude.ai, Claude Desktop, Cursor, your own agent) can connect:
Patron identity is on the connection (a NIP-98 signed request, or an OAuth connection that holds the npub after request_npub_proof / receive_npub_proof). The Schwab account is linked separately with begin_oauth / check_oauth_status. Sessions are keyed by npub.
Operator Environment Variables
Required
This is the only env var required to start. Certified operators bootstrap their Neon database URL from the Authority via encrypted Nostr DM -- NEON_DATABASE_URL is not read from the environment. The relay set comes from the shared dpyc-community registry and tranche lifetime from the operator's pricing model -- neither is an env var.
Optional Tuning
Credentials via Secure Courier (NOT env vars)
BTCPay credentials (btcpay_host, btcpay_api_key, btcpay_store_id) and Schwab API credentials (app_key, secret) are delivered exclusively through Secure Courier (service="schwab-operator"), validated at receive time, and stored in the encrypted vault. No secrets in env vars or chat.
Development
Prerequisites
- Python 3.12+
- A Schwab Developer app with API credentials
- Oxcart Nostr client for Secure Courier credential delivery
Install & Test
Project Structure
Prior Art & Attribution
The methods, algorithms, and implementations contained in this repository may represent original work by Lonnie VanZandt, first published in April 2026. This public disclosure establishes prior art under U.S. patent law (35 U.S.C. 102).
All use, reproduction, or derivative work must comply with the Apache License 2.0 included in this repository and must provide proper attribution to the original author per the NOTICE file.
How to Attribute
If you use or build upon this work, please include the following in your documentation or source:
Visit the technologist's virtual cafe for Bitcoin advocates and coffee aficionados at stablecoin.myshopify.com.
Patent Notice
The author reserves all rights to seek patent protection for the novel methods and systems described herein. Public disclosure of this work establishes a priority date of April 2026. Under the America Invents Act, the author retains a one-year grace period from the date of first public disclosure to file patent applications.
Note to potential filers: This public repository and its full Git history serve as evidence of prior art. Any patent application covering substantially similar methods filed after the publication date of this repository may be subject to invalidation under 35 U.S.C. 102(a).
Further Reading
The Phantom Tollbooth on the Lightning Turnpike -- the full story of how we're monetizing the monetization of AI APIs, and then fading to the background.
Trademarks
DPYC™, Tollbooth DPYC™, and Don't Pester Your Customer™ are trademarks of Lonnie VanZandt. See the TRADEMARKS.md in the dpyc-community repository for usage guidelines.
License
Apache License 2.0 -- see LICENSE and NOTICE for details.
Because in the end, the tollbooth was never the destination. It was always just the beginning of the journey.
來源:README.md,提交 13aa3b1
工具
0版本歷史
2- v0.14.0最新Oct 21, 2026
- v0.13.6Sep 16, 2026
評分
已滿足適用檢查項的 85%
該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。
- 近 30 天內可連通必需25 分
- 已宣告認證方式必需10 分
- 已列出工具15 分
請讓伺服器在無憑證時回應 tools/list,或發布可在沙箱中無憑證啟動的軟體包。
- 描述必需15 分
- 圖示10 分
- 文件15 分
- 授權條款10 分