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 SEP 20

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.

  • 10 Sept 26 0
    • Stability: 0.97 → pass security
  • 9 Sept 26 +1

    No change was recorded against any check on this day. Stability & Change Management went from 93 to 97. That category is still filling its 30-day observation window: 28 days of observed history at the previous scan, 29 at this one. The score rises as the window fills, whether or not the server changes.

  • 8 Sept 26 −1
    • Stability: pass → 0.93 functional
  • 6 Sept 26 +5
    • 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
  • 28 Aug 26 +2

    No change was recorded against any check on this day. Stability & Change Management went from 46 to 63.

  • 26 Aug 26 +1
    • 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 20 Sept 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=YE1,O=Let's Encrypt,C=US 12 Aug 2026 10 Nov 2026 ECDSA 256 ECDSA-SHA384 5b7741cbeba2022cf27f7b5aaf2f2023e3c
SANs: mcp.backtest.emidlabs.com
CN=YE1,O=Let's Encrypt,C=US (CA) CN=Root YE,O=ISRG,C=US 3 Sept 2025 2 Sept 2028 ECDSA 384 ECDSA-SHA384 5ddd70dd31f801c85c186a7a04b80afe
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|nullYour EmidLabs backtest API key. Not needed if this connector was added with a static 'x-api-key' header.
backtestBaseUrlstring|nullDefaults to the public production API.
batchIdstring|nullThe batchId returned by submit_backtest_batch.
pageinteger1-based page number. Default 1.
pageSizeintegerItems per page, 1-100. Default 20.
pollTimeoutMsintegerDefaults to 300000 (5 minutes) — a batch's slowest item determines the total wait, so this is higher than get_backtest_result's default.
waitForCompletionbooleanIf true (default), polls internally until every item in the batch is done or pollTimeoutMs elapses.
NameTypeReqDescription
batchIdstring
completedCountintegerHow many items finished successfully.
failedCountintegerHow many items finished unsuccessfully (Failed, Cancelled, or Expired).
itemsarray
pageinteger
pageSizeinteger
pendingCountintegerHow many items are still Queued or Running. The whole batch is done once this reaches 0 — true on every page, not just the last.
totalCountintegerTotal 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|nullYour EmidLabs backtest API key. Not needed if this connector was added with a static 'x-api-key' header.
backtestBaseUrlstring|nullDefaults to the public production API.
idstring|nullThe id returned by submit_backtest.
pollTimeoutMsintegerDefaults to 120000 (2 minutes).
waitForCompletionbooleanIf true (default), polls internally until the backtest finishes or pollTimeoutMs elapses.
NameTypeReqDescription
candlesProcessedinteger|nullNumber 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|nullAverage 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|nullNumber 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|nullHow 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|nullThe 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|nullYour EmidLabs backtest API key. Not needed if this connector was added with a static 'x-api-key' header.
backtestBaseUrlstring|nullDefaults to the public production API.
idstring|nullThe id returned by submit_backtest.
pageinteger1-based page number. Default 1.
pageSizeintegerTrades per page, 1-100. Default 20.
sortBystring|nullOne of: number, pnlR, pnlPct, entryTime, exitTime. Defaults to number (closing order).
sortDirectionstring|null"asc" or "desc". Defaults to asc.
NameTypeReqDescription
itemsarrayThe trades on this page, in the requested sort order.
pageinteger
pageSizeinteger
totalCountintegerTotal 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|nullYour EmidLabs backtest API key. Not needed if this connector was added with a static 'x-api-key' header.
backtestBaseUrlstring|nullDefaults to the public production API.
idstring|nullThe id returned by submit_confirmation_source.
pollTimeoutMsintegerDefaults to 120000 (2 minutes).
waitForCompletionbooleanIf true (default), polls internally until the confirmation source finishes or pollTimeoutMs elapses.
NameTypeReqDescription
assetPairstring
candlesProcessedinteger|nullNumber 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|nullHow long the analyser actually took to compute this confirmation source's signal timeline, in milliseconds. Null until Status is "Completed".
statusstring
timeframestring
unitsConsumednumber|nullThe 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|nullYour EmidLabs backtest API key. Not needed if this connector was added with a static 'x-api-key' header.
backtestBaseUrlstring|nullDefaults to the public production API.
idstring|nullThe id returned by submit_confirmation_source.
pageinteger1-based page number. Default 1.
pageSizeintegerSignals per page, 1-100. Default 20.
NameTypeReqDescription
itemsarrayThe signals on this page, in candle order.
pageinteger
pageSizeinteger
totalCountintegerTotal 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|nullYour EmidLabs backtest API key. Not needed if this connector was added with a static 'x-api-key' header.
backtestBaseUrlstring|nullDefaults 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|nulle.g. "BTC-USDC".
backtestApiKeystring|nullYour EmidLabs backtest API key (created in the Console). Not needed if this connector was added with a static 'x-api-key' header.
backtestBaseUrlstring|nullDefaults to the public production API. Override only for self-hosted/staging use.
confirmationSourcesarray|nullOptional. 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|nullISO date string, e.g. "2025-06-01".
initialDatestring|nullISO date string, e.g. "2025-01-01".
strategySnapshotJsonobject|nullThe 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|nulle.g. ["BTC-USDC", "ETH-USDC", "SOL-USDC"]. Every asset gets the exact same strategySnapshotJson and date range.
backtestApiKeystring|nullYour EmidLabs backtest API key (created in the Console). Not needed if this connector was added with a static 'x-api-key' header.
backtestBaseUrlstring|nullDefaults to the public production API. Override only for self-hosted/staging use.
confirmationSourcesstring|nullOptional. 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|nullISO date string, e.g. "2025-06-01".
initialDatestring|nullISO date string, e.g. "2025-01-01".
strategySnapshotJsonobject|nullSame Strategy DSL object submit_backtest takes — see that tool's description for the full shape.
NameTypeReqDescription
batchIdstringPass 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|nulle.g. "BTC-USDC".
backtestApiKeystring|nullYour EmidLabs backtest API key (created in the Console). Not needed if this connector was added with a static 'x-api-key' header.
backtestBaseUrlstring|nullDefaults to the public production API. Override only for self-hosted/staging use.
finalDatestring|nullISO date string, e.g. "2025-06-01".
initialDatestring|nullISO date string, e.g. "2025-01-01".
strategySnapshotJsonobject|nullThe 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 20 September 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.