EmidLabs Backtest
by emidlabs · remote · no sign-in to list tools · v0.1.0 · published by GitHub user emidlabs
Run crypto trading strategy backtests through EmidLabs's Backtesting API.
9 tools: 3 change things and 6 only read.
Scanned Oct 21, 2026
- Deletes or cancels0Claude Code: deny
- Can't be undone0Claude Code: ask
- Changes things3Claude Code: ask: see these tools
- Only reads6Claude Code: allow: see these tools
No check matched anything in the tool definitions. No finding is not a safety guarantee. How the checks work.
claude mcp add --transport http backtest https://mcp.backtest.emidlabs.com/mcpTools
Open a tool for its reasons and full description. Descriptions are the publisher's own words, shown as they are.
9 tools
Changes things 3Claude Code: ask
submit_backtestSubmits a strategy for backtesting against historical OHLCV data.No findings
Why it is in this group
- The name "submit_backtest" says "submit": a word for a change.
Description, as the server wrote it Submits a strategy for backtesting against historical OHLCV data. Returns immediately with an id and status — call get_backtest_result to fetch the outcome once it finishes. Testing the same strategy against many assets? Use submit_backtest_batch instead — one call per asset here adds up fast. Optionally accepts confirmationSources to only count a candidate Entry/Exit as a real trade once corroborated by a submit_confirmation_source result (multi-timeframe or cross-asset confirmation) — see the confirmationSources argument and submit_confirmation_source's own description.
Annotations the server declares
- title: Submit Backtest
- destructiveHint: false
- idempotentHint: false
- openWorldHint: false
- readOnlyHint: false
submit_backtest_batchSubmits ONE strategy against MANY asset pairs in a single call — the same backtest you'd get from calling submit_backtest once per asset, without needing dozens of round trips.No findings
Why it is in this group
- The name "submit_backtest_batch" says "submit": a word for a change.
Description, as the server wrote it Submits ONE strategy against MANY asset pairs in a single call — the same backtest you'd get from calling submit_backtest once per asset, without needing dozens of round trips. Returns immediately with a batchId (pass it to get_backtest_batch_results to fetch every asset's outcome, paginated) plus the per-asset id/status assigned right away. Best-effort: one bad asset pair (unknown, or its date range outside coverage) shows up with an error in that item only — every other asset in the batch is unaffected. Optionally accepts confirmationSources, applied identically to every asset in the batch — see submit_backtest's own confirmationSources argument for the full semantics.
Annotations the server declares
- title: Submit Backtest Batch
- destructiveHint: false
- idempotentHint: false
- openWorldHint: false
- readOnlyHint: false
submit_confirmation_sourceRuns a strategy against historical data purely to produce a signal timeline used to confirm OTHER backtests — not a backtest itself.No findings
Why it is in this group
- The name "submit_confirmation_source" says "submit": a word for a change.
Description, as the server wrote it Runs a strategy against historical data purely to produce a signal timeline used to confirm OTHER backtests — not a backtest itself. Walks the same candles and evaluates the same DSL as submit_backtest, but never simulates a position: no trade, no PnL, no WinRate/drawdown, none of that applies here, because this strategy is never meant to be traded on its own. Returns immediately with an id and status — call get_confirmation_source to check completion, then pass that id as a confirmationSources sourceId in submit_backtest (e.g. only count an XRP entry once a BTC-neutral confirmation source agrees). Costs the same capacity as a regular backtest of the same size — the compute is identical, it just skips trade simulation.
Annotations the server declares
- title: Submit Confirmation Source
- destructiveHint: false
- idempotentHint: false
- openWorldHint: false
- readOnlyHint: false
Only reads 6Claude Code: allow
get_backtest_batch_resultsFetches every asset's outcome from a submit_backtest_batch call, paginated.No findings
Why it is in this group
- The name "get_backtest_batch_results" says "get": a word for reading.
Description, as the server wrote it Fetches every asset's outcome from a submit_backtest_batch call, paginated. By default (waitForCompletion: true) polls internally until every item in the batch is done — a cheap check, not one that pages through everything — so one call returns the finished page. Each item has the same aggregate metrics and recency fields (recentTradeCount/recentAvgPnlR/recentOutcomes) get_backtest_result returns for a single backtest, plus assetPair/status/error, so the single-result and batch-result shapes never drift apart. totalCount/completedCount/failedCount/pendingCount come back on every page, not just the last, so you can tell the batch is done from a single pageSize=1 call.
Annotations the server declares
- title: Get Backtest Batch Results
- destructiveHint: false
- idempotentHint: true
- openWorldHint: false
- readOnlyHint: true
get_backtest_resultFetches a submitted backtest by id.No findings
Why it is in this group
- The name "get_backtest_result" says "get": a word for reading.
Description, as the server wrote it Fetches a submitted backtest by id. By default (waitForCompletion: true) polls internally until it finishes, so one call returns one final answer — no need to poll from the caller's side. Only aggregate metrics are returned here, no trade-by-trade detail — call get_backtest_trades for that (paginated, sortable). Fetching many results from the same submit_backtest_batch call? Use get_backtest_batch_results instead.
Annotations the server declares
- title: Get Backtest Result
- destructiveHint: false
- idempotentHint: true
- openWorldHint: false
- readOnlyHint: true
get_backtest_tradesFetches the closed-trade list for a completed backtest, paginated and sortable — the trade-by-trade detail get_backtest_result deliberately omits.No findings
Why it is in this group
- The name "get_backtest_trades" says "get": a word for reading.
Description, as the server wrote it Fetches the closed-trade list for a completed backtest, paginated and sortable — the trade-by-trade detail get_backtest_result deliberately omits. Only closed trades ever appear; a position still open when the backtest's date range ends isn't represented here or anywhere else. Example: sortBy="exitTime", sortDirection="desc", pageSize=5 for the most recently closed trades.
Annotations the server declares
- title: Get Backtest Trades
- destructiveHint: false
- idempotentHint: true
- openWorldHint: false
- readOnlyHint: true
get_confirmation_sourceFetches a submitted confirmation source by id.No findings
Why it is in this group
- The name "get_confirmation_source" says "get": a word for reading.
Description, as the server wrote it Fetches a submitted confirmation source by id. By default (waitForCompletion: true) polls internally until it finishes, so one call returns one final answer. No trade-outcome fields here at all (no PnlR/WinRate/...) — a confirmation source never opens a position. Once Completed, its id can be used as a confirmationSources sourceId in submit_backtest; its raw signal timeline is available separately via get_confirmation_source_signals.
Annotations the server declares
- title: Get Confirmation Source
- destructiveHint: false
- idempotentHint: true
- openWorldHint: false
- readOnlyHint: true
get_confirmation_source_signalsFetches a completed confirmation source's raw signal timeline, paginated — the actual data a backtest's confirmationSources requirement is checked against.No findings
Why it is in this group
- The name "get_confirmation_source_signals" says "get": a word for reading.
Description, as the server wrote it Fetches a completed confirmation source's raw signal timeline, paginated — the actual data a backtest's confirmationSources requirement is checked against. Can easily run into the thousands for a frequent condition over a long range (every candle-condition match is a row, not just closed trades), which is why this is paginated from the start. Debugging/inspection only — you do NOT need this tool to make confirmationSources work, and should not fetch these rows to reconstruct the gating yourself. To actually gate a backtest by this source, pass its id directly as sourceId in submit_backtest's own confirmationSources array; the backend applies the backward-only state check against this exact timeline automatically, including the higher-timeframe-to-lower-timeframe alignment. Reimplementing that alignment by hand from this raw data is unnecessary and easy to get wrong (e.g. failing to correctly persist a higher-timeframe state across every lower-timeframe candle until the next higher-timeframe close). Use this tool only to sanity-check a source's signal density or diagnose an unexpectedly low ConfirmedSignalsCount after the fact.
Annotations the server declares
- title: Get Confirmation Source Signals
- destructiveHint: false
- idempotentHint: true
- openWorldHint: false
- readOnlyHint: true
list_available_assetsLists every asset pair with real historical data, each with its supported timeframes and the date range actually available.No findings
Why it is in this group
- The name "list_available_assets" says "list": a word for reading.
Description, as the server wrote it Lists every asset pair with real historical data, each with its supported timeframes and the date range actually available. Optional to call — submit_backtest already returns a clear error (with the real available range) when an asset or date range doesn't have data, so this is for up-front exploration or for recovering from an "unknown asset" error, not a required step before every submit_backtest.
Annotations the server declares
- title: List Available Assets
- destructiveHint: false
- idempotentHint: true
- openWorldHint: false
- readOnlyHint: true
This is not a safety rating, and no finding is not a safety guarantee. The groups and findings come from fixed checks of the tool definitions the server returned on the date shown, not from its code or what it does when called. How the checks work.
Install
Pinned to version 0.1.0. Values in angle brackets are yours to fill in.
claude mcp add --transport http backtest https://mcp.backtest.emidlabs.com/mcpRun in a terminal.
Claude Code permissions
Allow the reads, ask before a change, deny the deletes. Paste into .claude/settings.json.
{
"permissions": {
"allow": [
"mcp__backtest__list_available_assets",
"mcp__backtest__get_backtest_batch_results",
"mcp__backtest__get_backtest_trades",
"mcp__backtest__get_backtest_result",
"mcp__backtest__get_confirmation_source",
"mcp__backtest__get_confirmation_source_signals"
],
"ask": [
"mcp__backtest__submit_confirmation_source",
"mcp__backtest__submit_backtest_batch",
"mcp__backtest__submit_backtest"
],
"deny": []
}
}Tools that only read are allowed, tools that change things ask first, tools that delete or cancel are denied. It assumes the server is installed as backtest. Review it before you use it.
