What it exposes
The MCP server gives AI agents access to the Joyride options exchange through 23 tools, 3 resources, and 3 prompts — covering market data, trading, account management, wallet creation, and position analysis. An AI agent can look up options chains, get quotes, place and cancel orders, check balances, and analyze positions — all through natural language. You talk to the agent; the agent calls the tools. Current mode: Paper trading only. No real money at risk. The first successful Joyride authentication creates a paper-trading account with a starting balance of $10,000.00.Quick start
Prerequisites
- Node.js >= 20.0.0
- A Joyride wallet — created via
joyride wallet createorjoyride setup - MCP server executable —
joyride-mcpavailable on your PATH
Setup: Claude Code
Step 1: Create .mcp.json in your project root
.mcp.json file contains your keystore passphrase, so it should stay out of source control. Add it to .gitignore if the config lives in a repo.
Step 2: Restart Claude Code
Exit your current session (/exit or Ctrl+C) and start a new one:
Step 3: Verify
Run/mcp in Claude Code. You should see:
Step 4: Test
Ask Claude:list_instruments and show you the results.
Setup: Other MCP clients
The MCP server runs as a local process over stdio (stdin/stdout). Any MCP-compatible client can launch it.Cursor
Add to.cursor/mcp.json in your project:
VS Code Copilot
Add to.vscode/mcp.json in your project:
Generic / custom agents
Launch the server directly over stdio:Codex and other experimental MCP clients
If a client supports launching local stdio MCP servers but uses a different config format than Claude Code or Cursor, keep the Joyride portion of the configuration the same:- command:
joyride-mcp - env:
JOYRIDE_WS_URL=wss://joyride.exchange/api/v1JOYRIDE_HTTP_URL=https://joyride.exchange/apiJOYRIDE_KEYSTORE_PASSWORD=<your-keystore-passphrase>
Client support
| Client | Status |
|---|---|
| Claude Code | Supported and tested |
| Cursor | Supported and tested |
| VS Code Copilot | Configuration documented; validate before broad alpha rollout |
| OpenClaw | Requires the local wallet-based config from the repo collateral |
| Codex | Experimental; use the generic stdio MCP pattern and validate before calling it supported |
Hosted HTTP mode (preview)
Joyride also exposes an HTTP MCP endpoint for remote agent access, but this path should be treated as preview for now:- Base URL:
https://joyride.exchange/api/v1/mcp - Transport: Streamable HTTP
- Auth: Bearer token / API key mapping on the server side
Auto-approve permissions
By default, Claude Code asks permission before calling each MCP tool. To skip prompts for Joyride tools, add them to.claude/settings.json:
place_order, cancel_order, and cancel_all_orders from the allow list so those still require manual confirmation.
Tool reference
All tools accept and return human-friendly units:- Prices in USD (e.g.,
5.00) — converted to/from USDC micros internally - Sizes in contracts (e.g.,
1,0.5) — converted to/from millicontracts internally - Sides as
"buy"/"sell"— mapped to"bid"/"ask"internally
Market data (8 tools)
list_instruments
List available options contracts with optional filters.
| Parameter | Type | Required | Description |
|---|---|---|---|
asset | string | No | Filter by asset ("SOL", "BTC", "ETH") |
expiry | string | No | Filter by expiry date ("3MAR26") |
type | "call" | "put" | No | Filter by option type |
get_quote
Get real-time bid/ask/mid quote for a specific instrument.
| Parameter | Type | Required | Description |
|---|---|---|---|
instrument_id | string | Yes | e.g., SOL_USDC-3MAR26-75-C |
{ bid, ask, mid, spread } — all in USD. Returns null for empty sides.
Transport: WebSocket
get_orderbook
Get full order book depth for a specific instrument.
| Parameter | Type | Required | Description |
|---|---|---|---|
instrument_id | string | Yes | Instrument ID |
depth | number | No | Price levels per side (default: 10) |
{ bids: [{price, size, count}], asks: [{price, size, count}] }
Transport: HTTP
get_options_chain
Get all options for an asset organized by strike (calls and puts side by side).
| Parameter | Type | Required | Description |
|---|---|---|---|
asset | string | Yes | "SOL", "BTC", "ETH" |
expiry | string | No | Filter by expiry date |
{ asset, expiry, strikes: [{ strike, call?, put? }] }
Transport: WebSocket + HTTP
get_ticker
Get ticker snapshot for a specific instrument.
| Parameter | Type | Required | Description |
|---|---|---|---|
instrument_id | string | Yes | Instrument ID |
{ bestBid, bestBidSize, bestAsk, bestAskSize, spread }
Transport: HTTP
get_all_tickers
Get all tickers in one call.
Returns: Array of { instrumentId, bestBid, bestAsk, midPrice, spotPrice }
Transport: HTTP
get_price_history
Get historical price data for a specific instrument.
| Parameter | Type | Required | Description |
|---|---|---|---|
instrument_id | string | Yes | Instrument ID |
start | number | No | Start timestamp (Unix seconds) |
end | number | No | End timestamp (Unix seconds) |
{ timestamp, bidPrice, askPrice, midPrice, spotPrice }
Transport: HTTP
get_market_config
Get market configuration (round duration and epoch).
Returns: { roundDurationHours, roundEpoch }
Transport: HTTP
Trading (5 tools)
All trading tools require wallet authentication.place_order
Place a limit or market order.
| Parameter | Type | Required | Description |
|---|---|---|---|
instrument_id | string | Yes | Instrument ID |
side | "buy" | "sell" | Yes | Order side |
type | "limit" | "market" | No | Default: "limit" |
price | number | For limit | Limit price in USD (e.g., 5.00) |
size | number | Yes | Number of contracts (e.g., 1, 0.5) |
{ order: {orderId, status, ...}, trades: [{tradeId, price, size, ...}] }
Example prompts:
- “Sell 1 contract of SOL_USDC-3MAR26-75-C at $5”
- “Buy 2 contracts of SOL_USDC-3MAR26-75-P at market”
cancel_order
Cancel a specific order.
| Parameter | Type | Required | Description |
|---|---|---|---|
instrument_id | string | Yes | Instrument ID |
order_id | number | Yes | Order ID to cancel |
cancel_all_orders
Cancel all open orders, optionally for a specific instrument.
| Parameter | Type | Required | Description |
|---|---|---|---|
instrument_id | string | No | Cancel only orders for this instrument |
{ count, orders: [...] }
Transport: WebSocket
get_open_orders
List all active/open orders.
Returns: Array of { orderId, instrumentId, side, orderType, price, size, remaining, status, timestamp }
Transport: WebSocket
get_order_status
Check the status of a specific order. Searches open orders first, then falls back to order history.
| Parameter | Type | Required | Description |
|---|---|---|---|
order_id | number | Yes | Order ID to look up |
Account (6 tools)
All account tools require wallet authentication.get_balance
Get current account balance.
Returns: { available, locked, total } — all in USD.
Transport: WebSocket
get_account
Get full account summary (balance and positions).
Returns: { available, locked, positions: [{instrumentId, quantity, avgPrice}] }
Transport: HTTP
get_positions
Get all open positions.
Returns: Array of { instrumentId, quantity, avgPrice }
Transport: HTTP
get_positions_with_metrics
Get positions enriched with PnL metrics.
Returns: Array of { instrumentId, quantity, avgPrice, midPrice, currentValue, pnl, pnlPercent, breakeven }
Transport: HTTP
get_trade_history
Get recent trade fills/executions.
| Parameter | Type | Required | Description |
|---|---|---|---|
limit | number | No | Maximum number of trades to return |
get_order_history
Get all orders including filled and cancelled.
| Parameter | Type | Required | Description |
|---|---|---|---|
limit | number | No | Maximum number of orders to return |
Wallet & social (2 tools)
create_wallet
Create a new Solana wallet for trading. The wallet is encrypted and stored on the server. Returns the wallet address.
Transport: HTTP
get_profiles
Get all user profiles (usernames and avatars).
Transport: HTTP
Analysis (2 tools)
get_index_price
Get the underlying spot/index price for an asset.
| Parameter | Type | Required | Description |
|---|---|---|---|
asset | string | Yes | "SOL", "BTC", "ETH" |
{ asset, price, timestamp }
Transport: HTTP
get_greeks
Get Greeks (delta, gamma, theta, vega, rho), implied volatility, and mark price for an instrument.
| Parameter | Type | Required | Description |
|---|---|---|---|
instrument_id | string | Yes | Instrument ID |
Resources
MCP resources provide read-only data snapshots that clients can request.| URI | Description |
|---|---|
joyride://portfolio | Current positions, PnL, and account summary |
joyride://markets | Available instruments with current bid/ask/mid/spot |
joyride://config | Connection status, trading mode, server version |
Prompts
MCP prompts are pre-built multi-step workflows that guide the AI agent through structured analysis.analyze-position
Analyze a specific options position: Greeks, PnL scenarios, and risk assessment.
| Argument | Type | Description |
|---|---|---|
instrument_id | string | Instrument ID to analyze |
find-opportunity
Find the best 0DTE options opportunity for an asset.
| Argument | Type | Description |
|---|---|---|
asset | string | Asset to analyze ("SOL", "BTC", "ETH") |
build-strategy
Construct an options strategy based on market outlook (analysis only — each leg must be executed as a separate place_order call).
| Argument | Type | Description |
|---|---|---|
asset | string | Asset to build strategy for |
outlook | string | "bullish", "bearish", "neutral", "volatile" |
Instrument ID format
All instrument IDs follow this pattern:| Component | Description | Examples |
|---|---|---|
ASSET | Underlying asset | SOL, BTC, ETH |
DMMMYY | Expiry date (1- or 2-digit day) | 3MAR26, 27FEB26 |
STRIKE | Strike price (integer USD) | 75, 100, 200 |
C|P | Option type | C (call), P (put) |
list_instruments to discover valid IDs. Instruments are 0DTE (same-day expiry) and refresh daily.
Configuration
The MCP server loads configuration in this order (highest priority first):- Environment variables (set in
.mcp.json) - Config file (
~/.joyride/config.toml) - Defaults
Environment variables
| Variable | Default | Description |
|---|---|---|
JOYRIDE_WS_URL | wss://joyride.exchange/api/v1 | WebSocket URL |
JOYRIDE_HTTP_URL | https://joyride.exchange/api | HTTP REST URL |
JOYRIDE_KEYSTORE_PASSWORD | — | Passphrase to decrypt wallet keystore |
JOYRIDE_PRIVATE_KEY | — | Base58 private key (bypasses keystore) |
JOYRIDE_KEYSTORE_PASSWORD or JOYRIDE_PRIVATE_KEY in your .mcp.json env block. The MCP server runs non-interactively and cannot prompt for a passphrase.
Config file
The MCP server shares~/.joyride/config.toml with the CLI. Run joyride setup to create it interactively:
Example workflows
Discover and quote
Place and manage orders
Guided analysis (using prompts)
Troubleshooting
MCP server doesn’t appear in /mcp
The config must be in .mcp.json at the project root. Restart Claude Code after creating or editing it.
Server shows ✘ failed
Check the server logs:joyride-mcpis not on your PATH- Wallet credentials are missing from MCP env config
- Node.js version too old — requires >= 20.0.0
NOT_AUTHENTICATED errors
The MCP server needs wallet credentials. Make sure your .mcp.json includes either JOYRIDE_KEYSTORE_PASSWORD (to decrypt the keystore created by joyride wallet create) or JOYRIDE_PRIVATE_KEY (Base58 key directly).
The passphrase must match the one you used when creating the wallet. Check which wallet is active with joyride wallet show.
Gateway connection warning
If you seeCould not connect to gateway, the WS gateway is unreachable. The server starts in degraded mode — tools requiring WebSocket will return errors, but HTTP tools still work.
Check that JOYRIDE_WS_URL is wss://joyride.exchange/api/v1.
Permission prompts on every tool call
See auto-approve permissions to pre-approve all Joyride tools.CLI/MCP package version mismatch
If MCP tools error after a CLI upgrade, update both the Joyride CLI and MCP server packages so they are on compatible versions.Quotes show all nulls
The order book is empty. Uselist_instruments to find instruments with activity.
Debug mode
mcp-debug.log for connection warnings and errors.