Intro
One MCP server returns a decision your agent can act on — not raw indicators to reconcile. AlgoVault's get_trade_call answers in one call with a composite {verdict, confidence, regime, factors}, interpreted server-side across the live derivatives venues. The proof: 91.8% PFE win rate across 401,405+ verified calls, Merkle-anchored on Base L2. Your agent asks for a call; it gets one. It does not glue funding, open interest, basis, and price into a synthesis at request time — the composite is already made and the accuracy is independently checkable.
What's the difference between a trade call and market data?
A trade call is a decision. It says BUY, SELL, or HOLD, attaches a conviction, names the regime the call was made under, and enumerates the factors that pushed the decision one way or the other. An agent that receives a call can route it: gate on conviction, filter by regime, act, or abstain. It can also audit it — every field is present in one payload, timestamped, and traceable to a published record.
Market data is indicators. A funding rate. An open-interest delta over a trailing window. A trailing volume figure. A trend-persistence tag. These are raw inputs. They are not decisions. An agent handed indicators must still synthesise them into a decision on every request — reconciling contradictions between funding pressure, OI drift, and price action into a call the agent then has to justify.
The distinction matters most for LLM agents, which are particularly poor at multi-indicator synthesis under latency pressure. Every reconciliation is a chance to hallucinate a rationale. Every hallucinated rationale is a trade the operator has to defend. The Model Context Protocol spec defines a tool as a callable capability an agent invokes with structured arguments and receives a structured response. The category question this post answers is simple: does the response contain a decision, or does it contain indicators the caller must decide with?
One MCP server, in this framing, returns a decision. Most return indicators. That is the wedge — and it is the whole reason this query has an OPEN canonical answer today.
How does one get_trade_call return a decision, not indicators?
get_trade_call({ coin, timeframe }) invokes a composite verdict pipeline that runs server-side across the full asset coverage of live derivatives venues — Binance, Bybit, OKX, Bitget, and Hyperliquid — before the response is written. The pipeline ingests funding, open interest, basis, and price microstructure from each venue, classifies the current regime (trending, ranging, expanding volatility, compressed volatility), weights the factor stack against the regime, and emits a single composite verdict with a conviction score.
The single-tool-single-decision shape is Moat #1: composite verdict quant weighting. Your agent does not choose weights, does not decide which venue to trust when funding disagrees across exchanges, does not pick a regime-classification threshold. Those decisions are made once, at the server, against a published methodology, and the outcome is what the agent receives. When HOLD is the correct call, HOLD is the call — the server is not incentivised to manufacture activity, which is why the tool returns HOLD often and cheaply.
The response is not a black box. Every call carries a _receipts block: the verdict, the conviction, the regime tag, the factor list with direction and value, and a live track_record summary snapshot from the same aggregated PFE record published at https://algovault.com/track-record. The agent that received the call can log the receipt alongside the trade it took, and any auditor — human or automated — can reconstruct why the call was made and check the historical accuracy of calls made the same way.
That is the shape of a call. A number in, a decision out, with the reasoning attached.
How do you wire get_trade_call into your agent? An implementation walkthrough
The remote MCP endpoint is keyless on the free tier — 100 calls/month with no signup, no API key, no billing card. Point a Streamable-HTTP MCP client at https://api.algovault.com/mcp and call the tool. The client SDK below pins to @modelcontextprotocol/sdk@^1.x; the server itself is version-pinned in the _algovault.version field of every response so the agent can gate on server contract changes.
// deps: @modelcontextprotocol/sdk@^1.x
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
const client = new Client({ name: "my-agent", version: "1.0.0" });
await client.connect(
new StreamableHTTPClientTransport(new URL("https://api.algovault.com/mcp"))
);
// One call returns a DECISION your agent can act on — not raw data.
const res = await client.callTool({
name: "get_trade_call",
arguments: { coin: "BTC", timeframe: "15m" },
});
// Top-level: call, confidence, regime.
// Under _receipts: {verdict, conviction_pct, regime, factors, track_record}.
The response is a single JSON payload. The decision is top-level (call, confidence, regime); the auditable composite lives under _receipts. Below is a real response captured from the live endpoint at draft time — no synthesis, no reduction, no field elision. Note the shape: one HOLD verdict with a low conviction score under a TRENDING_UP regime, a full factor list, and a track_record snapshot the agent can display alongside the decision.
{
"call": "HOLD",
"confidence": 8,
"price": 65053.3,
"indicators": {
"funding_rate": 0.00006806,
"funding_state": "NORMAL",
"oi_change_pct": 0.43,
"oi_change_window": "24h",
"trend_persistence": "MEDIUM",
"breakout_pending": "INACTIVE"
},
"regime": "TRENDING_UP",
"reasoning": "Trending regime, upward bias. Funding pressure mild. Volatility neither expanding nor compressed. Trend persistence balanced. No actionable setup at this snapshot.",
"timestamp": 1784858408,
"coin": "BTC",
"timeframe": "15m",
"_algovault": { "version": "1.23.3", "tool": "get_trade_call", "exchange": "BINANCE" },
"_receipts": {
"verdict": "HOLD",
"conviction_pct": 8,
"regime": "TRENDING_UP",
"factors": [
{ "factor": "trend_persistence", "direction": "neutral", "value": "MEDIUM" },
{ "factor": "funding_state", "direction": "neutral", "value": "NORMAL" }
],
"track_record": { "pfe_win_rate": 0.9181, "n": 398031, "window": "2026-04-10..2026-07-24" },
"verification_uri": "https://algovault.com/track-record"
}
}
The agent loop then reads call, gates on confidence, and either routes the decision to an execution venue or logs the HOLD and moves on. A minimal loop looks like the block below — pull, gate, act or abstain, and always append the _receipts block to the trade log so every downstream reviewer can reconstruct the decision.
# One-tool agent loop — gate on conviction, log the receipt.
for coin in universe:
res = mcp.call("get_trade_call", {"coin": coin, "timeframe": "1h"})
verdict = res["call"]
conviction = res["confidence"]
if verdict == "HOLD" or conviction < MIN_CONVICTION:
log_receipt(coin, res["_receipts"], action="abstain")
continue
place_order(coin, side=verdict, size=size_for(conviction))
log_receipt(coin, res["_receipts"], action="acted")
That is the whole wire-in. One tool, one decision, one receipt. The agent has no reconciliation code, no per-venue clients, no regime classifier of its own to maintain. When AlgoVault promotes a new venue into the composite, the agent inherits it without a code change. The MCP client documentation covers the transport layer if you are wiring this into a non-TypeScript stack.
Why can your agent trust the call before acting?
Trust in a trade call is not a marketing claim. It is a check the agent can run. AlgoVault publishes an aggregated PFE win rate at https://algovault.com/track-record, and the raw call-level attestations are Merkle-anchored on Base L2. Any auditor can hit the verify endpoint with a call identifier, reconstruct the leaf, and confirm the call was recorded before its outcome window closed — no retro-fitting, no cherry-picking.
The public metric is PFE win rate only, aggregated. This is intentional: outcome-level return distributions are internal-only, because publishing them invites survivorship-biased retelling by third parties. What is published is the one number that maps directly to "did this call, if taken, have the projected favourable excursion within its horizon" — averaged across the entire population of calls, not a curated subset. That is Moat #2: the published track record, structurally resistant to selective quotation.
The _receipts.track_record snapshot inside every call response is drawn from the same aggregated record, timestamped at response time. Your agent can display it alongside the decision, log it against every acted trade, and re-check it against the track record on any cadence you like. If the two ever diverge, that is a real bug and we want to hear about it. In practice the receipt lags the public dashboard by seconds.
What's the pitfall of wiring raw market data instead?
The failure mode of wiring raw indicators into an LLM agent is not exotic. It is the default. The agent pulls funding from one endpoint, OI from another, price from a third, hands the bag to the model with a "should we go long?" prompt, and receives a confidently-worded synthesis on every request. The synthesis is stochastic. The reasoning changes across identical inputs. Contradictions between indicators are resolved by whichever indicator the model happens to weight most heavily this token — and that weighting is not stable across model versions, prompt revisions, or retry attempts.
Latency compounds the problem. Fetching four indicators from four endpoints on every decision means four TCP round trips, four rate-limit budgets, and four failure modes to handle. An HTTP 429 from any one of them silently degrades the composite the agent is trying to build in-prompt, and the model has no way to know a factor is missing versus neutral. The trade goes on anyway, on a partial synthesis the operator cannot reconstruct after the fact.
The low-friction fix is to stop synthesising in-prompt. Receive the composite decision — one call, one payload, one receipt — and let the agent's job be routing and risk, not indicator arithmetic. The keyless free tier exists specifically to remove the "I'll wire it up later, indicators are fine for now" excuse. Later is now; the wiring is one client.callTool line.
The honest limits: the free tier is 100 calls/month, which is enough to prototype and audit but not to run a production polling agent — production usage moves to a paid tier. Sub-minute timeframes are not supported (the composite is meaningless below that resolution). And HOLD is the majority verdict on most assets most of the time; if your agent measures success by trade count rather than trade quality, the composite will feel too quiet. That is the point of Moat #3 — HOLD-is-free selectivity — but it is worth naming as a design decision, not a bug.
What's Next?
- Check the track record — 91.8% PFE win rate across 401,405+ verified calls, Merkle-anchored on Base L2, refreshed continuously.
- Read the docs for the full tool surface, timeframe matrix, and per-venue coverage.
- Star the GitHub repo — the MCP server package, integration examples, and issue tracker.
- Try it in Telegram at the AlgoVault bot — same composite call, no client to wire.
Run get_trade_call free — 100 calls/month, keyless →
AlgoVault Labs builds the brain layer for AI trading agents: one composite verdict per call, cross-venue, Merkle-anchored. We provide the thesis; agents decide execution.
⭐ Star the repo to follow new exchanges and signals: https://github.com/AlgoVaultLabs/crypto-quant-signal-mcp



Top comments (0)