Skip to content
verify mcp Beta VerifyMCP is currently in beta. If you notice any issues, get in touch and we’ll put it right.

EmidLabs Backtest

REMOTE · MCP.BACKTEST.EMIDLABS.COM · SCANNED OCT 12

Run crypto trading strategy backtests through EmidLabs's Backtesting API.

0 this week 85 Trust /100
Trust breakdown (7 categories)

How this component scores in each security and reliability category. Every signal is checked automatically against the live server, and we only credit what we can confirm. How we score → Why this is hard to score →

Endpoint Security74
Transport & Reachability100
Schema Quality & AI Usability77
  • 100% of prompts and resources have a non-trivial description (not blank, and not just the item's name).Pass
  • AI-judged instruction clarity (excellent).Pass
  • Context-footprint check failed: tool/resource definitions use about 2954 tokens (~295/item across 10 items; 9 tools + 1 resources), over budget; trim descriptions and params. See how to fix → Fail
  • Usage-examples check failed: none of the tools include examples. See how to fix → Fail
Stability & Change Management100
  • No destabilizing schema changes in the last 30 days.Pass
Tool Coverage100
  • 100% of tools have a non-trivial description (not blank, and not just the tool's name).Pass
  • 100% of tool parameters carry a description.Pass
  • Structured output schemas are declared (100% of tools); any adoption earns full credit.Pass
Tool Safety100
  • No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.Pass
  • We read all 9 captured tool definition(s), and no name or description among them implies an irreversible operation.Pass
  • An AI judge read all 11 captured unit(s) of tool text and found none that tries to manipulate the model reading it.Pass
Capabilities100
  • Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.Pass
Install

How do I install the EmidLabs Backtest MCP server?

EmidLabs Backtest is a hosted endpoint at https://mcp.backtest.emidlabs.com/mcp, so there is nothing to install locally. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.

remote · mcp.backtest.emidlabs.com

# add to Claude Code
claude mcp add --transport http emidlabs-backtest-mcp 'https://mcp.backtest.emidlabs.com/mcp'
// .cursor/mcp.json
{
  "mcpServers": {
    "emidlabs-backtest-mcp": {
      "url": "https://mcp.backtest.emidlabs.com/mcp"
    }
  }
}
// .vscode/mcp.json
{
  "servers": {
    "emidlabs-backtest-mcp": {
      "type": "http",
      "url": "https://mcp.backtest.emidlabs.com/mcp"
    }
  }
}
# ~/.codex/config.toml
[mcp_servers.emidlabs-backtest-mcp]
url = "https://mcp.backtest.emidlabs.com/mcp"
// opencode.json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "emidlabs-backtest-mcp": {
      "type": "remote",
      "url": "https://mcp.backtest.emidlabs.com/mcp",
      "enabled": true
    }
  }
}
# add to OpenClaw
openclaw mcp add emidlabs-backtest-mcp --url 'https://mcp.backtest.emidlabs.com/mcp' --transport streamable-http
# ~/.hermes/config.yaml
mcp_servers:
  emidlabs-backtest-mcp:
    url: "https://mcp.backtest.emidlabs.com/mcp"
// ~/.netclaw/config/netclaw.json
{
  "McpServers": {
    "emidlabs-backtest-mcp": {
      "Transport": "http",
      "Url": "https://mcp.backtest.emidlabs.com/mcp"
    }
  }
}
# add to Vellum
assistant mcp add emidlabs-backtest-mcp -t streamable-http -u 'https://mcp.backtest.emidlabs.com/mcp'
// mcp.json
{
  "mcpServers": {
    "emidlabs-backtest-mcp": {
      "type": "http",
      "url": "https://mcp.backtest.emidlabs.com/mcp"
    }
  }
}

The mcpServers block is a cross-client convention. Remote transports vary, so check your client's docs.

Changelog

Every change we have recorded for this component, newest first. Security-relevant changes are always shown. ▲ marks a change for the better, ▼ a change for the worse; unmarked changes are neutral.

  • 28 Sept 26 0
    • We updated how we score, so this day's move reflects our rubric, not a change to the server See what changed → functional
  • 25 Sept 26 0
    • We updated how we score, so this day's move reflects our rubric, not a change to the server See what changed → functional
  • 10 Sept 26 0
    • Stability: 0.97 → pass security
  • 8 Sept 26 0
    • Stability: pass → 0.93 functional
  • 6 Sept 26 0
    • Stability: fail → pass ▲ security
  • 2 Sept 26 0
    • Tool “get_confirmation_source_signals” rewrote its description, which is the text the model reads security
  • 1 Sept 26 0
    • Tool “submit_backtest” rewrote its description, which is the text the model reads security
    • Tool “submit_backtest_batch” rewrote its description, which is the text the model reads security
    • Schema quality: 241 → 280 ▼ functional
    • New tool “get_confirmation_source” functional
    • New tool “get_confirmation_source_signals” functional
    • New tool “submit_confirmation_source” functional
    • “submit_backtest” added an optional parameter “confirmationSources” cosmetic
    • “submit_backtest_batch” added an optional parameter “confirmationSources” cosmetic
  • 26 Aug 26 0
    • We updated how we score, so this day's move reflects our rubric, not a change to the server See what changed → functional
Diagnostics

Diagnostic detail from the automated scan of this channel: what the scanner observed at each step, so you can see exactly where a check passed or failed. It is informational only and never changes the trust score.

Captured 12 Oct 2026 · Probed https://mcp.backtest.emidlabs.com/mcp

TLS valid

Negotiated TLS 1.3 with TLS_AES_128_GCM_SHA256 .

Subject Issuer Valid from Valid until Key Signature Serial
CN=mcp.backtest.emidlabs.com CN=YE2,O=Let's Encrypt,C=US 11 Oct 2026 9 Jan 2027 ECDSA 256 ECDSA-SHA384 5abe28731a724f076787599e23d59efaeca
SANs: mcp.backtest.emidlabs.com
CN=YE2,O=Let's Encrypt,C=US (CA) CN=Root YE,O=ISRG,C=US 3 Sept 2025 2 Sept 2028 ECDSA 384 ECDSA-SHA384 4df3b15dd6c0784c507cd37b58e6f115
CN=Root YE,O=ISRG,C=US (CA) CN=ISRG Root X2,O=Internet Security Research Group,C=US 13 May 2026 2 Sept 2032 ECDSA 384 ECDSA-SHA384 872165fc34b6e5fba8add5b3705fb53a
CN=ISRG Root X2,O=Internet Security Research Group,C=US (CA) CN=ISRG Root X1,O=Internet Security Research Group,C=US 13 May 2026 2 Sept 2032 ECDSA 384 SHA256-RSA 6c8f1dc727c7117f7baf853ac980f9cd

Background: What to check on a remote MCP endpoint →

DNSSEC insecure

Validation of mcp.backtest.emidlabs.com. — Not signed

Zone DS Keys Algorithms Outcome
. trust_anchor 20326, 38696 8, 8 Verified
com. present 19718 13 Verified
emidlabs.com. absent Unsigned (proven) parent-signed NSEC/NSEC3 proves an unsigned delegation
Authentication No authorisation required

The endpoint answered without asking for a token. Anyone who knows the URL can reach it.

Result No authorisation required
HTTP status 200

Background: How OAuth 2.1 works in the 2026 MCP spec →

Transports 2 probes
Transport URL Outcome Status Location
streamable-http https://mcp.backtest.emidlabs.com/mcp Verified 200
http (plaintext) http://mcp.backtest.emidlabs.com/mcp HTTPS enforced 308 https://mcp.backtest.emidlabs.com/mcp
MCP tools · 9 exposed · ~2,852 tokens

The tools this component advertises to a client, with an estimated token cost for each. Expand a tool to see its parameters and schema. The per-tool counts are indicative and are not scored directly; the schema's total context footprint is one signal in Schema Quality & AI Usability. A tool's description is untrusted text the model reads on every call, which is what makes this list a security surface and not just an inventory: how tool poisoning works →

Tool Tokens
get_backtest_batch_results ~339

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.

NameTypeReqDescription
backtestApiKeystring|null–Your EmidLabs backtest API key. Not needed if this connector was added with a static 'x-api-key' header.
backtestBaseUrlstring|null–Defaults to the public production API.
batchIdstring|null–The batchId returned by submit_backtest_batch.
pageinteger–1-based page number. Default 1.
pageSizeinteger–Items per page, 1-100. Default 20.
pollTimeoutMsinteger–Defaults to 300000 (5 minutes) — a batch's slowest item determines the total wait, so this is higher than get_backtest_result's default.
waitForCompletionboolean–If true (default), polls internally until every item in the batch is done or pollTimeoutMs elapses.
NameTypeReqDescription
batchIdstring––
completedCountinteger–How many items finished successfully.
failedCountinteger–How many items finished unsuccessfully (Failed, Cancelled, or Expired).
itemsarray––
pageinteger––
pageSizeinteger––
pendingCountinteger–How many items are still Queued or Running. The whole batch is done once this reaches 0 — true on every page, not just the last.
totalCountinteger–Total items in this batch, across every page — not just this one.
totalPagesinteger––

No examples provided.

get_backtest_result ~213

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.

NameTypeReqDescription
backtestApiKeystring|null–Your EmidLabs backtest API key. Not needed if this connector was added with a static 'x-api-key' header.
backtestBaseUrlstring|null–Defaults to the public production API.
idstring|null–The id returned by submit_backtest.
pollTimeoutMsinteger–Defaults to 120000 (2 minutes).
waitForCompletionboolean–If true (default), polls internally until the backtest finishes or pollTimeoutMs elapses.
NameTypeReqDescription
candlesProcessedinteger|null–Number of candles the analyser processed for this backtest. Null until Status is "Completed". This is raw volume, not the plan's billing unit — see UnitsConsumed for that.
errorMessagestring|null––
idstring––
recentAvgPnlRnumber|null–Average pnlR of the most recent RecentTradeCount closed trades. This is the recency signal for a rolling ranking — weighted alongside expectancyR, not a replacement for it.
recentOutcomesarray|null–"Win"/"Loss" per recent trade, chronological — oldest first, so the LAST element is the most recent trade. Lets a caller see whether recent trades were genuinely a streak (e.g. all "Loss") versus alt…
recentTradeCountinteger|null–Number of trades the recency fields below are based on (up to 5, fewer if the backtest has fewer trades). Null until Status is "Completed".
resultobject|null––
runtimeMsinteger|null–How long the analyser actually took to run this backtest, in milliseconds — pure compute time, not counting queue/messaging latency. Null until Status is "Completed".
statusstring––
unitsConsumednumber|null–The actual execution-unit cost of this backtest, matching what's debited from the account's plan balance (CandlesProcessed normalized by the account's candles-per-unit rate). Null until Status is "Co…

No examples provided.

get_backtest_trades ~247

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.

NameTypeReqDescription
backtestApiKeystring|null–Your EmidLabs backtest API key. Not needed if this connector was added with a static 'x-api-key' header.
backtestBaseUrlstring|null–Defaults to the public production API.
idstring|null–The id returned by submit_backtest.
pageinteger–1-based page number. Default 1.
pageSizeinteger–Trades per page, 1-100. Default 20.
sortBystring|null–One of: number, pnlR, pnlPct, entryTime, exitTime. Defaults to number (closing order).
sortDirectionstring|null–"asc" or "desc". Defaults to asc.
NameTypeReqDescription
itemsarray–The trades on this page, in the requested sort order.
pageinteger––
pageSizeinteger––
totalCountinteger–Total closed trades across the whole backtest, not just this page.
totalPagesinteger––

No examples provided.

get_confirmation_source ~213

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.

NameTypeReqDescription
backtestApiKeystring|null–Your EmidLabs backtest API key. Not needed if this connector was added with a static 'x-api-key' header.
backtestBaseUrlstring|null–Defaults to the public production API.
idstring|null–The id returned by submit_confirmation_source.
pollTimeoutMsinteger–Defaults to 120000 (2 minutes).
waitForCompletionboolean–If true (default), polls internally until the confirmation source finishes or pollTimeoutMs elapses.
NameTypeReqDescription
assetPairstring––
candlesProcessedinteger|null–Number of candles the analyser processed. Null until Status is "Completed". This is raw volume, not the plan's billing unit — see UnitsConsumed for that.
errorMessagestring|null––
idstring––
runtimeMsinteger|null–How long the analyser actually took to compute this confirmation source's signal timeline, in milliseconds. Null until Status is "Completed".
statusstring––
timeframestring––
unitsConsumednumber|null–The actual execution-unit cost, same pool/rate as a regular backtest — computing a confirmation source's signal timeline costs the same per candle as simulating trades, it just skips the trade simula…

No examples provided.

get_confirmation_source_signals ~335

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.

NameTypeReqDescription
backtestApiKeystring|null–Your EmidLabs backtest API key. Not needed if this connector was added with a static 'x-api-key' header.
backtestBaseUrlstring|null–Defaults to the public production API.
idstring|null–The id returned by submit_confirmation_source.
pageinteger–1-based page number. Default 1.
pageSizeinteger–Signals per page, 1-100. Default 20.
NameTypeReqDescription
itemsarray–The signals on this page, in candle order.
pageinteger––
pageSizeinteger––
totalCountinteger–Total signals across the whole confirmation source, not just this page — can easily be in the thousands for a frequent condition over a long range.
totalPagesinteger––

No examples provided.

list_available_assets ~151

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.

NameTypeReqDescription
backtestApiKeystring|null–Your EmidLabs backtest API key. Not needed if this connector was added with a static 'x-api-key' header.
backtestBaseUrlstring|null–Defaults to the public production API. Override only for self-hosted/staging use.
NameTypeReqDescription
assetsarray––

No examples provided.

submit_backtest ~527

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.

NameTypeReqDescription
assetPairstring|null–e.g. "BTC-USDC".
backtestApiKeystring|null–Your EmidLabs backtest API key (created in the Console). Not needed if this connector was added with a static 'x-api-key' header.
backtestBaseUrlstring|null–Defaults to the public production API. Override only for self-hosted/staging use.
confirmationSourcesarray|null–Optional. Each entry names a submit_confirmation_source result (same account only, must already be Completed) that every candidate Entry/Exit must be corroborated by before it's simulated as a trade…
finalDatestring|null–ISO date string, e.g. "2025-06-01".
initialDatestring|null–ISO date string, e.g. "2025-01-01".
strategySnapshotJsonobject|null–The Strategy DSL object — every field below documents its own exact shape, this is just the execution model that ties them together. Entry fills at the close of the candle where decision.entry turns…
NameTypeReqDescription
idstring––
statusstring––

No examples provided.

submit_backtest_batch ~492

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.

NameTypeReqDescription
assetPairsarray|null–e.g. ["BTC-USDC", "ETH-USDC", "SOL-USDC"]. Every asset gets the exact same strategySnapshotJson and date range.
backtestApiKeystring|null–Your EmidLabs backtest API key (created in the Console). Not needed if this connector was added with a static 'x-api-key' header.
backtestBaseUrlstring|null–Defaults to the public production API. Override only for self-hosted/staging use.
confirmationSourcesstring|null–Optional. A JSON-encoded STRING (not a native array/object — pass it exactly like a quoted string value), containing the same shape as submit_backtest's own confirmationSources: [{"sourceId":"<a subm…
finalDatestring|null–ISO date string, e.g. "2025-06-01".
initialDatestring|null–ISO date string, e.g. "2025-01-01".
strategySnapshotJsonobject|null–Same Strategy DSL object submit_backtest takes — see that tool's description for the full shape.
NameTypeReqDescription
batchIdstring–Pass this to get_backtest_batch_results to fetch every item's status/result, paginated.
itemsarray––

No examples provided.

submit_confirmation_source ~335

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.

NameTypeReqDescription
assetPairstring|null–e.g. "BTC-USDC".
backtestApiKeystring|null–Your EmidLabs backtest API key (created in the Console). Not needed if this connector was added with a static 'x-api-key' header.
backtestBaseUrlstring|null–Defaults to the public production API. Override only for self-hosted/staging use.
finalDatestring|null–ISO date string, e.g. "2025-06-01".
initialDatestring|null–ISO date string, e.g. "2025-01-01".
strategySnapshotJsonobject|null–The Strategy DSL object — identical shape to submit_backtest's own. riskManagement is accepted but never used (no position is ever opened), so it's fine to omit.
NameTypeReqDescription
idstring––
statusstring––

No examples provided.

Common questions

What is the EmidLabs Backtest MCP server?

EmidLabs Backtest is an MCP server listed in the public MCP registry as io.github.emidlabs/backtest-mcp. Run crypto trading strategy backtests through EmidLabs's Backtesting API. This page covers its hosted endpoint (https://mcp.backtest.emidlabs.com/mcp).

Is the EmidLabs Backtest MCP server safe to use?

EmidLabs Backtest scores 85 out of 100 on VerifyMCP. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

What tools does the EmidLabs Backtest MCP server expose?

EmidLabs Backtest exposes 9 tools: submit_confirmation_source, list_available_assets, submit_backtest_batch, get_backtest_batch_results, get_backtest_trades, and 4 more. Their descriptions and schemas cost roughly 2,852 tokens of context every time the server is loaded.

Does the EmidLabs Backtest MCP server require authentication?

No. We connected to EmidLabs Backtest without credentials and it answered, so anything it exposes is reachable by anyone who knows the address.

Is the EmidLabs Backtest MCP server still maintained?

EmidLabs Backtest is still listed as active in the MCP registry. We last reached this channel on 12 October 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.