derive-options-mcp
# derive-options-mcp
An MCP server for [Derive](https://derive.xyz) options. Describe a view; get real
option structures, priced against the live order book, sized to your budget,
with the payoff and the worst case spelled out.
```
you: I think BTC goes up over the next month. I'd risk $500.
agent: BTC is 85,376.
## Up, capped — Price goes up, but not enormously.
Costs $500 for 0.46 contracts, expiring Fri, Oct 30 (37 days).
- Most you can lose: $500
- Most you can make: $1,347
- Breaks even at: 91,083
Legs: buy 1× 90,000C @ $2,354 · sell 1× 94,000C @ $1,271
$1,347 ┤ ▀▀▀▀▀▀▀▀▀▀▀▀
┤ ▀│
┤ ▀│
$0 ┼···························▀│···········
-$500 ┤▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄│
└─────────────────┬──────────────────────
now 85,376
```
No API key. No account. No wallet. It reads Derive's public API and does the
arithmetic locally.
## Install
**Claude Code**
```bash
claude mcp add derive-options -- npx -y derive-options-mcp
```
**Claude Desktop / Cursor / Codex** — add to the MCP config:
```json
{
"mcpServers": {
"derive-options": {
"command": "npx",
"args": ["-y", "derive-options-mcp"]
}
}
}
```
**Remote** — `npm run serve` starts a streamable-HTTP endpoint on `:8080/mcp`.
To mount it inside an existing app, export the handler from any route that
speaks Web `Request`/`Response` (a Next.js route handler, for instance):
```ts
import { handleMcpRequest } from "derive-options-mcp/dist/transports/http.js";
export const POST = handleMcpRequest;
```
## Tools
| Tool | Answers |
|---|---|
| `propose_trades` | "I think X goes up / stays flat / moves hard — what should I trade?" |
| `propose_hedge` | "I hold this. How do I protect it?" |
| `price_structure` | "What does an iron condor on ETH cost right now?" |
| `list_strategies` | Every shape, what it bets on, and its trade-off |
| `list_currencies` · `list_expiries` · `get_option_chain` | The market |
| `get_spot` · `get_ticker` · `get_recent_trades` | Prices and the tape |
Every tool returns two things: **text** with an ASCII payoff diagram for the
model and the chat window, and **`structuredContent`** carrying the full payoff
curve, every leg with its fill price and its quote, breakevens, both extremes
and a handoff link — enough for a host app to render its own chart without
re-deriving anything and disagreeing with what the user was just told.
## How a proposal is chosen
1. **Enumerate.** Every shape that can express the view, at the three expiries
nearest your horizon, at three distances from the money — about a hundred
candidates.
2. **Price against the book.** Buys cross the ask, sells hit the bid. Priced off
mark, every spread looks free, and the sell legs are exactly where these
books are thinnest. A leg with no price on its side is a **rejection**, not a
number to soften — so nothing is ever proposed that cannot be traded.
3. **Size to the risk.** Debit structures size on cost. Credit structures are
constrained by what they can *lose*, not what they cost, so they size on
that — otherwise a $500 budget quietly opens a $5,000 exposure.
4. **Rank.** By what each pays if the market moves one standard deviation by
that expiry — the market's own implied volatility, not a guess — per dollar
at risk. Each expiry is scored against *its own* one-sigma move, so a
nine-day structure isn't flattered by a thirty-seven-day move.
It costs three network requests: the chain is cached and a whole expiry's book
arrives in one call, so the hundred candidates are priced from three responses.
**Structures whose loss has no limit are excluded** unless you pass
`allow_uncapped`. They can't be sized against a budget, and their real
constraint is margin this server cannot see.
## What it will not do
**It does not trade.** It holds no key, signs nothing, and has no account.
Every result carries a link where you review and sign it yourself.
This is deliberate rather than unfinished. A Derive session key is not
scope-limited — the protocol grants it the same authority as the account owner,
withdrawals included — so a server holding one would be custodial. Building the
trade and signing it are separate jobs, and only one of them belongs here.
**Prices move.** Everything is a snapshot. Treat a result more than a minute old
as stale and ask again.
**It is not advice.** It tells you what a structure costs and what it can lose.
What to do about that is yours.
## Configuration
| Variable | Default | |
|---|---|---|
| `DERIVE_NETWORK` | `mainnet` | `v3-testnet` to point at testnet |
| `DERIVE_HANDOFF_URL` | `https://tacticalls.xyz` | Where trade links point |
| `PORT` · `MCP_PATH` | `8080` · `/mcp` | HTTP transport only |
Mainnet is Derive v2 (`api.lyra.finance`) — v3 mainnet has not launched, and its
option books read bid 0 / ask 0.
## Development
```bash
npm install && npm run build
npm test # pricing core, against a book under test
npx @modelcontextprotocol/inspector node dist/transports/stdio.js
```
MIT.
TDQS
Scored across 10 tools
Each tool targets a distinct resource and action: trade proposals, hedging, pricing specific structures, listing strategies, currencies, expiries, option chains, spot, tickers, and recent trades. No two tools have overlapping purposes; even the two proposal tools are clearly separated by intent (expressing a view vs. protecting a holding).
All tools follow a consistent verb_noun pattern with lowercase snake_case: propose_trades, propose_hedge, price_structure, list_strategies, list_currencies, list_expiries, get_option_chain, get_spot, get_ticker, get_recent_trades. Verbs (propose, price, list, get) clearly indicate the action, and the pattern is uniform across the set.
With 10 tools, the server is well-scoped for its domain of options analysis and trade generation. Each tool serves a clear purpose—generating ideas, hedging, pricing, listing available instruments, and retrieving market data—without redundancy or bloat.
The surface covers the core workflow: generating trade ideas, hedging existing holdings, pricing specific structures, listing strategies and market metadata, and accessing detailed market data. A minor gap is the lack of trade execution (the server seems focused on analysis and pricing), but this is likely intentional given the server's name and description. Overall, the domain is well-covered.