Who this is for
Use this guide if you want to connect an AI agent to Joyride quickly without building against the raw HTTP or WebSocket APIs yourself. No API key required. Create your account in the web app at joyride.exchange (referral code + terms attestation), then sign in from the CLI with the same wallet — the CLI is login-only. Invite/referral codes are redeemed in the web app, not the CLI. Current mode: Paper trading only. No real money is at risk.Prerequisites
- Node.js >= 20.0.0
- A local MCP client such as Claude Code, Cursor, Codex, or VS Code Copilot
The 5-command flow
1. Install the CLI
joyride command and the bundled MCP server. Verify:
2. Create or import a wallet
Run the setup wizard:Create new walletfor a fresh paper-trading identityImport existing walletif you already have a Solana keypair
- config to
~/.joyride/config.toml - an encrypted keystore to
~/.joyride/wallets/
3. Authenticate
~/.joyride/session.json. Signing in with a wallet that has no Joyride account fails with a “sign up at joyride.exchange” message — create the account in the web app first.
The server sets how long a session lasts — run joyride auth status to see its exact expiry rather than assuming a fixed lifetime. You only need to re-run joyride login once it expires. On a shared or untrusted machine, run joyride logout when you are done.
4. Configure your MCP client
Auto-install (recommended)
Pick the command for your client:~/.cursor/mcp.json are preserved.
Manual config (if your client isn’t listed)
The MCP server runs over stdio. Any MCP-compatible client can launch it using the same command and args:.vscode/mcp.json with the top-level key servers instead of mcpServers.
The MCP server reads the JWT from ~/.joyride/session.json (written by joyride login) — no keypair path or passphrase is needed in the MCP config.
5. Restart and verify
Restart your MCP client. In Claude Code, run/mcp — you should see:
Try a first session
Start with read-only prompts:List available SOL instrumentsShow my balanceGet a quote for <any instrument from the list>
Place a limit buy for 1 contract of <instrument> at $4.00
Date labels may look like “tomorrow.” Rounds are 24 hours and settle at 08:00 UTC, so after 08:00 UTC the active instruments carry tomorrow’s date label. Each instrument response includes
expires_at (ISO-8601) and seconds_to_expiry so your agent can check programmatically. See Trading Hours and Rollover for the full schedule.Supported clients
Direct API integration (no MCP)
If your agent framework doesn’t use MCP (LangGraph, AutoGen, CrewAI, custom Python/TypeScript orchestrators, n8n, etc.), you can use the JWT fromjoyride login directly with the REST and WebSocket APIs.
TypeScript
Python
curl
WebSocket trading
Reads are available over HTTP; order placement runs over the core trading WebSocket:@joyride/core) handles client_order_id/nonce generation and ack correlation for you — prefer it over hand-rolling the wire.
Going event-driven
The examples above use polling (request/response). For strategies that react to fills, stop-losses, or position changes in real-time, subscribe to WebSocket channels.CLI
jq or your agent’s event loop. (For spot price, use joyride price SOL.)
Raw WebSocket
public/session_resume. Spot prices come from the standalone oracle WS (wss://joyride.exchange/api/oracle).
Troubleshooting
Not authenticated. Run joyride login first.
The MCP server could not find a valid session. Run joyride login in your terminal, then restart your MCP client.
Joyride: No config found
Run joyride setup to create a wallet and initial config.
Wallet not configured
Run joyride wallet show. If no wallet is listed, re-run joyride setup or create one explicitly with joyride wallet create.
Instrument examples don’t exist
Same-day instruments refresh daily. Always start by asking the agent to list available instruments instead of hard-coding IDs from an older session. If you need the exact schedule, see Trading Hours and Rollover.Going event-driven
Polling endpoints in a loop works, but agents that react to fills, book updates, or spot prices in real time should subscribe to the event stream instead. There are two paths.Option A — joyride watch (recommended for agents)
The joyride watch <channel> command subscribes to a WebSocket channel and streams events as JSON lines (one event per line) to stdout. Pipe it into jq, tee, or your agent’s stdin:
joyride watch for the full channel list, flags, and auth requirements.
Option B — raw WebSocket
If you don’t want to depend on the CLI, connect directly to the core market-data WS (wss://joyride.exchange/api/md) and send a JSON-RPC public/subscribe request with the instrument symbols.
joyride login).
Headless / agent flow (no interactive prompts)
Autonomous agents and CI containers don’t have a TTY, so thejoyride setup wizard can’t prompt them. Two non-interactive paths are supported.
Option A — joyride setup --non-interactive
Recommended when you want the standard config + encrypted keystore on disk.
wallet.privateKey immediately — it isn’t stored in plaintext anywhere and won’t be shown again.
Other flags:
--import-key <base58>— bring your own Solana ed25519 private key instead of generating a new one--skip-wallet— write connection/defaults only, configure the wallet later--http-url <origin>— the single public origin all service URLs derive from;--ws-url <url>overrides the derived trading WS URL--default-asset <SOL|BTC|ETH>— default asset to save into config
joyride login (also reads JOYRIDE_KEYSTORE_PASSWORD) to obtain a session JWT.
Option B — JOYRIDE_PRIVATE_KEY (no on-disk keystore)
For ephemeral containers and one-shot scripts where you don’t want the keystore on disk at all, the CLI accepts a Base58-encoded Solana private key from the environment and skips both setup and the keystore entirely:
JOYRIDE_PRIVATE_KEY expects.
JOYRIDE_PRIVATE_KEY is intentionally a footgun for production use — the key sits in plain process env. It’s the right tool for short-lived agent sessions, not long-lived deployments.
Persisting state
Both options leave a session JWT at~/.joyride/session.json after joyride login. If your environment is ephemeral, persist ~/.joyride/ between runs — or just re-authenticate on each start, which is cheap.
The JWT expires at a time the server sets — run joyride auth status to see the exact expiry rather than assuming a fixed lifetime. Even with a persisted directory you’ll need to re-run joyride login once it expires. Long-running agents should detect a 401 from the gateway and re-login on demand rather than assume the session is permanent.