@tradecafe-ai/mcp
v1.1.1
Published
Official TradeCafe MCP server. Trade with TradeCafe from Claude Desktop, Cursor, VS Code, and any MCP-compatible client.
Maintainers
Readme
TradeCafe MCP
Official Model Context Protocol server for TradeCafe. Trade with TradeCafe from Claude Desktop, Cursor, VS Code, Claude Code, and any MCP-compatible client.
Status: v1.1 — live against pwa-be. 10 tools (8 read, 2 safety-gated write), stdio transport, real user data. Mock mode still available for development. Full architecture & roadmap:
docs/ARCHITECTURE.md.
What this is
A façade over TradeCafe's production backend (pwa-be) that lets any MCP client read your real account state, signals, positions, PnL, pool, subscription, and referral data — and approve pending semi-auto trades or close positions through TradeCafe's existing risk engine. The LLM operates the bot; it does not place arbitrary trades. Every write tool routes back through the existing TradeCafe risk engine (5-position cap, 30% drawdown circuit breaker, trailing stops, etc.) — that engine remains the source of truth on whether anything actually fires.
Two modes, one server:
- Interactive — human dev at Claude Desktop / Cursor, LLM as the UI, human-in-the-loop.
- Agentic — autonomous agents (Virtuals, Eliza, Olas, etc.) using TradeCafe as their headless execution layer, gated by spending envelopes. Ships in Phase 4.
Install
Quick start (live, real data)
Until pwa-be ships long-lived Personal Access Tokens (per docs/BACKEND_SPEC.md), the MCP authenticates with your existing TradeCafe session token. One-time setup:
- Log into tradecafe.ai in your browser.
- Open DevTools → Application → Cookies →
https://tradecafe.ai. - Copy the value of the
authcookie (it starts witheyJ…). - Paste it into your MCP client config as
TRADECAFE_PAT:
{
"mcpServers": {
"tradecafe": {
"command": "npx",
"args": ["-y", "@tradecafe-ai/mcp"],
"env": {
"TRADECAFE_PAT": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIi..."
}
}
}
}The MCP decodes the token's sub claim to know which user is calling, then talks to https://api.tradecafe.ai/api on your behalf. The session expires when your browser session expires (typically several hours); when it does, log in again and re-copy. Once pwa-be ships true PATs, this whole step goes away — same env var, longer-lived value.
No backend changes required. The MCP maps to existing pwa-be endpoints that already power the dashboard.
Mock mode (no auth, no network)
For demos, screenshots, or offline development:
{
"mcpServers": {
"tradecafe": {
"command": "npx",
"args": ["-y", "@tradecafe-ai/mcp"],
"env": { "TRADECAFE_MODE": "mock" }
}
}
}Mock returns deterministic synthetic data — obviously fake numbers, the same every time. Useful for testing tools and demos without touching real accounts.
Browser OAuth (future)
/oauth/authorize + /oauth/token endpoints wrapping the existing TradeCafe session are spec'd in docs/BACKEND_SPEC.md for the next phase. When they ship, no copy/paste — first tool call opens the browser, tokens auto-refresh.
Local install
npm install -g @tradecafe-ai/mcp
tradecafe-mcp # speaks JSON-RPC over stdioTools (v1.1)
Read tools (8) — no financial impact
| Tool | Description |
|---|---|
| get_account_summary | User ID, email, tier, subscription status, connected exchanges, referral code, free-trial days remaining. |
| get_recent_signals | Recently fired TradeCafe signals — entry, TP ladder, SL, strategy alias, timeframe, market type, status. Live by default; include_history=true to add closed/expired. Filter by symbol or side. |
| get_signal_details | Drill-down on a single signal: realized PnL (USDT and %), strategy alias, timeframe. |
| get_positions | Open and closed positions — entry, current, size, PnL, SL/TP, strategy, timestamps. Filter by status. |
| get_pnl_history | Daily realized PnL series over 7d / 30d / 90d / 365d, with totals and win-rate (fraction of positive days). |
| get_pool_status | Trading Pool stakes — user allocation, active stake count, lifetime + pending rewards, per-stake breakdown. |
| get_subscription_status | Tier, overall status, and per-product breakdown (signal_bot / trading_bot / terminal / card). |
| get_referral_stats | Partner program: code, link, total turnover, direct + total referrals, lifetime reward. |
Write tools (2) — safe by default
Both default to dry_run: true. To execute, call once to preview and receive an action_token, then call again with dry_run: false plus that token and the same args. Tokens are single-use and expire in 5 minutes.
| Tool | Description |
|---|---|
| approve_pending_trade | For semi-auto users: approve a pending bot signal so the bot fires the position. Size/entry/SL/TP come from the user's bot config — this tool just OKs the pending fire. FULL_AUTO bypasses this gate; MANUAL has no pending signals. Maps to PUT /trade/approve/{id}. |
| close_position | Manually close an open position at market. Normally the risk engine manages lifecycle — use this for explicit intervention. Maps to PUT /trade/close/{id}. |
What the dry-run / commit round-trip looks like, end to end:
1. → approve_pending_trade { signal_id: "sig_2026060402" }
← { dry_run: true, preview: { size_usdt: 100, strategy_alias: "Trend Reversion v3", … }, action_token: "abc…" }
2. → approve_pending_trade { signal_id: "sig_2026060402", dry_run: false, action_token: "abc…" }
← { dry_run: false, committed: { signal_id: "sig_…", approved_at: "…" } }Anything else fails — token expiry, args mismatch (changed signal_id), replay (reused token), wrong tool, or attempts to commit without a token. The pwa-be risk engine remains the final authority on whether a trade actually opens.
Migration from v1.0:
subscribe_to_signalwas renamed toapprove_pending_tradeand itssize_usdtparameter removed. The v1.0 tool surface was based on a fictional "subscribe to one signal at this size" endpoint that pwa-be doesn't expose — the real workflow is approving pending semi-auto bot trades, where the bot's config (set elsewhere) determines size. If you were calling the v1.0 tool, dropsize_usdtfrom your call and rename the tool.
Authentication
The MCP supports two auth modes. The right choice depends on what the TradeCafe backend has ready to expose.
PAT (Personal Access Token)
- User generates a token at
tradecafe.ai/settings/tokenswhile logged in. - Token is set via
TRADECAFE_PATenv var in the MCP client config. - The MCP sends
Authorization: Bearer <token>on every API call. - No refresh — if the token is revoked or expires, the MCP surfaces a clear error pointing the user back to settings.
Pros: minimum backend work, headless-friendly (CI, containers, SSH), same pattern as every dev tool the user has used before. Cons: copy/paste UX, plaintext in MCP client config.
OAuth 2.1 + PKCE
- First tool call opens the browser to TradeCafe's authorization page.
- User logs in with their existing TradeCafe account and approves scopes.
- The MCP captures the auth code on a loopback redirect (
http://127.0.0.1:<random>/callback) — never exposed to the network. - Tokens are persisted at
~/.tradecafe/tokens.jsonwith0600permissions, refreshed transparently. - 401 from the API auto-triggers re-consent.
Pros: zero copy/paste, scoped consent screen, granular permissions, free distribution surface (consent page = brand impression). Cons: requires two thin backend endpoints (see below).
Scopes requested at v1.1: read:account, read:signals, read:positions, read:billing, read:pool, read:referrals, write:trades. Phase 3+ scopes (write:bot_config, write:pool_allocation) require fresh consent when added.
To reset auth (OAuth mode): rm ~/.tradecafe/tokens.json and the next tool call re-prompts.
To rotate auth (PAT mode): revoke the old token at tradecafe.ai/settings/tokens, generate a new one, update the config.
Configuration
For most users: none required. Defaults target production TradeCafe.
| Env var | Default | When you'd set it |
|---|---|---|
| TRADECAFE_PAT | none | Set to a Personal Access Token to skip OAuth and use bearer-token auth. Setting this any value switches the MCP to PAT mode. |
| TRADECAFE_MODE | live | Set to mock for offline / demo mode (no auth, synthetic data). |
| TRADECAFE_API_BASE_URL | https://api.tradecafe.ai | Point at staging or a local backend. |
| TRADECAFE_AUTH_URL | https://tradecafe.ai/oauth/authorize | OAuth staging override. |
| TRADECAFE_TOKEN_URL | https://tradecafe.ai/oauth/token | OAuth staging override. |
| TRADECAFE_CLIENT_ID | tradecafe-mcp | OAuth staging or partner-specific client. |
| TRADECAFE_SCOPES | read:account read:signals read:positions | Override the requested scope set. |
| TRADECAFE_REQUEST_TIMEOUT_MS | 10000 | Per-request HTTP timeout. |
Mock mode bypasses all auth:
TRADECAFE_MODE=mock npx -y @tradecafe-ai/mcpSee examples/ for full Claude Desktop config snippets per mode.
What the backend needs to expose
There are two paths. Pick based on which is easier to ship.
Minimal path — PAT only (~1 day backend)
- Tokens settings page at
tradecafe.ai/settings/tokens— create / list / revoke. Tokens prefixedtc_pat_, stored hashed (bcrypt or argon2), bound to auser_idand an optional list of scopes. - API middleware that validates
Authorization: Bearer tc_pat_*against the tokens table, attaches the user to the request, updateslast_used_at. - API endpoints at
api.tradecafe.ai:GET /v1/account/summary,GET /v1/signals/recent,GET /v1/positions. Shapes matchsrc/client/types.ts.
That's it. The MCP works end-to-end. Users paste a token, the MCP makes API calls.
Polished path — add OAuth (~1-2 days more backend, on top of PAT)
The OAuth flow is a thin wrapper over the existing TradeCafe login session. It doesn't replace anything — it reuses what's already there.
GET /oauth/authorize— checks the existing TradeCafe session cookie. If logged in, shows a consent screen ("TradeCafe MCP wants access to: read your account, read your signals, read your positions") with Authorize / Cancel. If not logged in, redirects to the existing login page and back. On approve, mints an auth code, 302s to the loopback redirect with?code=...&state=....POST /oauth/token— acceptsgrant_type=authorization_code, validates the code + PKCE challenge, returns{ access_token, refresh_token, expires_in, token_type, scope }. Also handlesgrant_type=refresh_token.- OAuth client registration — a static public client named
tradecafe-mcpwith redirect-URI patternhttp://127.0.0.1:*/callbackand no client secret (PKCE handles it).
The validated tokens flow through the same API middleware as PATs — both are just bearer tokens to the API.
Optional (Phase 1)
/.well-known/oauth-authorization-server(RFC 8414) for endpoint discovery./.well-known/oauth-protected-resource(RFC 9728) for MCP resource metadata.POST /oauth/revoke(RFC 7009) for revocation from TradeCafe account settings.
See src/client/LiveTradeCafeClient.ts for the exact API paths consumed.
Roadmap
| Phase | Surface | Status |
|---|---|---|
| 0 | 3 read tools, stdio, PAT + OAuth | shipped (v0.3) |
| 1 | Full read:* surface (8 tools), safety-gated write tools (subscribe-to-signal, close-position) | shipped (v1.0) |
| 1.5 | Live pwa-be backend, tool surface aligned with real endpoints, subscribe_to_signal → approve_pending_trade | shipped (v1.1) |
| 2 | Long-lived PATs per BACKEND_SPEC.md, settings UI for token management | next (pending pwa-be) |
| 3 | write:bot_config, write:pool_allocation, streamable HTTP transport, well-known discovery | planned |
| 4 | Verified Agent Program — spending envelopes, agent identity, partner revenue share | planned |
| 4 | Verified Agent Program + spending envelopes (agentic mode) | planned |
Full design: docs/ARCHITECTURE.md.
Development
git clone https://github.com/TradeCafe-AI/mcp.git
cd mcp
npm install
TRADECAFE_MODE=mock npm run dev # run against MockTradeCafeClient
npm test # vitest
npm run lint
npm run typecheck
npm run build # tsc → ./distSpeak JSON-RPC directly (with mock mode so no OAuth is required):
TRADECAFE_MODE=mock node dist/index.jsArchitecture
The MCP is a façade over services TradeCafe already runs. It is not a new exchange integration. Three layers:
- MCP Server — auth, schema validation, scope & cap enforcement, idempotency, audit logging.
- API Gateway — internal mTLS to TradeCafe services.
- Risk Engine — final authority on every trade. Same rules as the web app.
See docs/ARCHITECTURE.md for the full system diagram, OAuth scopes, tool surface, safety layers, phased rollout, and the agentic-mode design.
Contributing
See CONTRIBUTING.md.
License
MIT © TradeCafe
