MCP server
ParlayLedger MCP server
Connect Claude, Cursor or any MCP client to ParlayLedger with your API key. Agents get two tools: search the RDK network for strategies and picks published by ParlayLedger users, and backtest a strategy on ParlayLedger's historical odds and results.
https://api.parlayledger.com/mcp- Transport Streamable HTTP
- Sessions Stateless
- Responses JSON
- Server name parlayledger-rdk
The server is stateless: every request stands alone, there is no session id and no event stream to resume. Clients send JSON-RPC over POST. GET and DELETE on /mcp return 405.
Authentication
Use the same customer API key as the REST API, from your dashboard. Send it either way:
X-API-Key: <apiKey>Authorization: Bearer <apiKey>
The key must belong to a ParlayLedger account. Every request, including initialize and tools/list, needs a valid key.
Metering
- Each
tools/callis metered as one API call against your monthly quota, with the same quota headers and the same 429 when it runs out. initialize,tools/listandpingare not metered.- Send one
tools/callper HTTP request. A JSON-RPC batch with more than one is rejected with 400. - On top of the API call,
rdk_search_strategiesuses one search andbacktest_strategyuses one backtest from your plan's monthly RDK limits.
Connect a client
Put your key in an environment variable, for example PARLAYLEDGER_API_KEY, rather than in a file you commit.
Claude Code
Add it with the CLI, or commit a project .mcp.json that reads the key from the environment. Add --scope user to the CLI command to use it in every project.
claude mcp add --transport http parlayledger https://api.parlayledger.com/mcp \
--header "X-API-Key: $PARLAYLEDGER_API_KEY"Cursor
Add the server to ~/.cursor/mcp.json, or to .cursor/mcp.json in a project.
{
"mcpServers": {
"parlayledger": {
"url": "https://api.parlayledger.com/mcp",
"headers": {
"X-API-Key": "${env:PARLAYLEDGER_API_KEY}"
}
}
}
}Claude Desktop
Two ways to connect. Use whichever your account supports.
Other clients
Most clients that support remote HTTP servers take a URL and headers:
{
"mcpServers": {
"parlayledger": {
"url": "https://api.parlayledger.com/mcp",
"headers": {
"Authorization": "Bearer YOUR_API_KEY"
}
}
}
}Try it with cURL
curl https://api.parlayledger.com/mcp \
-H "X-API-Key: $PARLAYLEDGER_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "rdk_search_strategies",
"arguments": { "query": "NHL home underdogs after a loss", "league": "NHL", "verifiedOnly": true }
}
}'The result is a JSON-RPC response whose result.content[0].text holds the tool output as JSON.
rdk_search_strategies
Search sports betting strategies and picks published by ParlayLedger users on the RDK knowledge network. Results include ParlayLedger-verified records.
Arguments
querystring, 1 to 2000 charactersrequiredWhat to look for, in plain words, for example "NHL home underdogs after a loss".
leaguestringoptionalOnly this league, for example NFL, NBA, NHL, MLB or NCAAB.
verifiedOnlybooleanoptionaltrue for verified winning work only.
Needs an activated RDK account
Activate RDK in your ParlayLedger dashboard first. Each search runs as your linked RetroDeck account, so retrieval tips are paid from your own RetroDeck balance, capped per search. Results only include work published through ParlayLedger, up to 8 per search. How RDK works on ParlayLedger.
Result
| Field | Type | Description |
|---|---|---|
requestId | string | Id of this search. |
results[].title | string | Title of the publication. |
results[].type | string | null | pick or strategy. |
results[].publicationId | string | null | Pass it to backtest_strategy to backtest a strategy. |
results[].publisher | string | null | Publisher handle, for example @handle. |
results[].rulesText | string[] | null | A strategy's rules in plain English. |
results[].forwardRecord | object | null | Record on games graded since the strategy was published. |
results[].backtest | object | null | Backtest summary shown as context. |
results[].pick | object | null | For a pick: event, selection, odds and status. |
results[].attestation | object | null | ParlayLedger verification: status and record. |
results[].content | string | null | The retrieved text. null when the result was not retrieved. |
results[].skippedReason | string | null | Why content is null, for example tip_cap. |
backtest_strategy
Backtest a sports betting strategy against ParlayLedger historical odds and results. Accepts Rule DSL v1 JSON or the id of a published strategy.
Arguments
Send exactly one of the two.
rulesobject (Rule DSL v1)optionalThe strategy:
version1,league,market(moneyline, spread or total),side, up to sixconditionson pregame fields,priceandstake.publicationIdstringoptionalThe id of a published ParlayLedger strategy, for example from an
rdk_search_strategiesresult.
{
"rules": {
"version": 1,
"sport": "icehockey",
"league": "NHL",
"market": "moneyline",
"side": "home",
"conditions": [
{
"field": "home_is_favorite",
"op": "eq",
"value": false
},
{
"field": "home_prev_result",
"op": "eq",
"value": "loss"
}
],
"price": {
"source": "consensus"
},
"stake": {
"units": 1
}
}
}Rules use pregame information only, so a backtest never sees the result of the game it is betting on.
Result
| Field | Type | Description |
|---|---|---|
sample | number | Graded bets, pushes included. Voids are not bets. |
wins, losses, pushes | number | Results at 1 unit per bet. |
winRate | number | null | Wins over wins plus losses. |
units, roi | number, number | null | Profit in units, and units per bet. |
maxDrawdownUnits | number | Largest peak to trough fall, in units. |
byMonth | array | { month, bets, units } per month. |
window | object | null | { from, to }: the first and last game in the sample. |
warnings | string[] | Codes such as sample_below_minimum or legacy_pricing. |
rulesHash, dataVersion | string | Identify the exact rules and data the run used. |
rules, rulesText | object, string[] | The normalized rules and their plain-English text. |
publicationId | string | Present when you backtested a published strategy. |
Errors and limits
A tool that cannot run returns a result with isError: true and one of these messages:
| Message | What to do |
|---|---|
| Activate RDK in your ParlayLedger dashboard to search the RDK network. | Activate RDK in the dashboard, then search again. |
| Your RetroDeck balance is too low to retrieve more results. Add funds in RetroDeck. (followed by a link) | Add funds to your RetroDeck balance. |
| You've used this month's searches. | Wait for next month or upgrade your plan. |
| You've used this month's backtests. | Wait for next month or upgrade your plan. |
| Send either rules or publicationId. | Pass rules or publicationId, not both. |
| MCP tools need the API key of a ParlayLedger account. | Use the key from your ParlayLedger dashboard. |
HTTP errors come before the tool runs:
- 400Send one tools/call per request.
- 401Valid X-API-Key required, or Invalid API key
- 405GET or DELETE on /mcp
- 429Monthly API quota exceeded