protogrid

Search / io.github.emidlabs/backtest-mcp

EmidLabs Backtest

R0· no sign-in

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

v0.1.0 · active · repository · website · descriptor JSON · versions

An agent can connect right now, no human step.Remote endpoint, no authentication, reachable on the last probe.
Quality85good
Trust94of 100
Uptime, 30 days100%
Latency p50561 ms

Connect

8 clients · secrets stay placeholders
{
  "mcpServers": {
    "backtest-mcp": {
      "type": "http",
      "url": "https://mcp.backtest.emidlabs.com/mcp"
    }
  }
}
claude mcp add --transport http backtest-mcp https://mcp.backtest.emidlabs.com/mcp
[mcp_servers.backtest-mcp]
url = "https://mcp.backtest.emidlabs.com/mcp"
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "backtest-mcp": {
      "type": "remote",
      "url": "https://mcp.backtest.emidlabs.com/mcp",
      "enabled": true
    }
  }
}
{
  "mcpServers": {
    "backtest-mcp": {
      "type": "http",
      "url": "https://mcp.backtest.emidlabs.com/mcp"
    }
  },
  "deeplink": "cursor://anysphere.cursor-deeplink/mcp/install?name=backtest-mcp&config=eyJ0eXBlIjoiaHR0cCIsInVybCI6Imh0dHBzOi8vbWNwLmJhY2t0ZXN0LmVtaWRsYWJzLmNvbS9tY3AifQ%3D%3D"
}
{
  "servers": {
    "backtest-mcp": {
      "type": "http",
      "url": "https://mcp.backtest.emidlabs.com/mcp"
    }
  }
}
{
  "mcpServers": {
    "backtest-mcp": {
      "httpUrl": "https://mcp.backtest.emidlabs.com/mcp"
    }
  }
}
extensions:
  "backtest-mcp":
    enabled: true
    name: "backtest-mcp"
    type: streamable_http
    uri: "https://mcp.backtest.emidlabs.com/mcp"
    timeout: 300

Quality 85 / 100good

protocol75 · weight 25
  • warn
    protocol.modernnewest supported version is 2025-11-25; 2026-07-28 not supported, older versions are deprecated until 2027-07-28
  • n/a
    protocol.statelessonly applies to 2026-07-28 servers
  • pass
    protocol.transportstreamable HTTP
  • n/a
    protocol.list_ttlonly applies to 2026-07-28 servers
authorizationn/a · weight 15
  • n/a
    auth.prm, auth.as_metadata, auth.cimdno remote uses OAuth
  • n/a
    auth.secret_in_urlno templated URL
tool hygiene86 · weight 30
  • pass
    tools.descriptionsevery tool has a description
  • warn
    tools.description_length1 tools have descriptions over 1,024 characters, which crowds the context
  • pass
    tools.schemasevery tool has an object input schema
  • pass
    tools.annotations9 of 9 tools declare readOnlyHint or destructiveHint
  • pass
    tools.directory_hintsevery tool declares readOnlyHint, destructiveHint, idempotentHint and openWorldHint
  • warn
    tools.token_costabout 8,584 tokens to load every tool
  • pass
    tools.api_dumptools are not a one-to-one API dump
stability100 · weight 15
  • pass
    stability.changesno tool changes in 30 days
  • pass
    stability.rug_pullno tool changed its meaning under the same name
dependenciesn/a · weight 15
  • n/a
    deps.known_vulns, deps.mcp_sdk_version, deps.resolvableno npm or PyPI package

9 tools, about 8,584 tokens to load them all · tool set 591be529dcca · checked 2026-10-19 10:52 UTC

Tool changes

No tool definition changes recorded. A server's first observation is its baseline; later probes record what changes.

Checks run on what our credential-free, read-only probes observe; tools are never called and no code audit is performed. How it is computed.

Trust 94 / 100

provenance90
liveness100
freshness85
hygiene100

+repository +namespace-matches-repo +website +reachable +uptime-100% ~updated-84d-ago

Derived from observable signals (official registry feed and our own credential-free probes); no code audit performed. How it is computed.

Endpoints

remoteauthreachableuptime 30dp50protocollast ok
https://mcp.backtest.emidlabs.com/mcp streamable-httpnoneyes100%561 ms2025-11-252026-10-19

Tools (9)

get_backtest_batch_resultsread-onlyFetches 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.
get_backtest_resultread-onlyFetches 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.
get_backtest_tradesread-onlyFetches 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.
get_confirmation_sourceread-onlyFetches 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.
get_confirmation_source_signalsread-onlyFetches 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.
list_available_assetsread-onlyLists 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.
submit_backtestSubmits 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.
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. 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.
submit_confirmation_sourceRuns 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.

Schemas: list_tools.

Similar MCP servers

Official server.json
{
  "name": "io.github.emidlabs/backtest-mcp",
  "title": "EmidLabs Backtest",
  "$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
  "remotes": [
    {
      "url": "https://mcp.backtest.emidlabs.com/mcp",
      "type": "streamable-http"
    }
  ],
  "version": "0.1.0",
  "repository": {
    "id": "1312820736",
    "url": "https://github.com/emidlabs/emidlabs-backtest-mcp",
    "source": "github"
  },
  "websiteUrl": "https://emidlabs.com",
  "description": "Run crypto trading strategy backtests through EmidLabs's Backtesting API."
}