Resolved Markets logoResolved Markets logo

MCP Server

Connect Claude, GPT, or any MCP-compatible AI agent directly to live Resolved Markets data. The server exposes orderbooks, snapshots, market metadata, and Hyperliquid perps as MCP tools — your agent can call them just like any other function.

What is MCP?

The Model Context Protocol is an open standard for connecting AI assistants to external data and tools. Once configured, your agent can ask things like "compare the BTC 5m spread on Polymarket to the BTC perp on Hyperliquid right now" and the agent will call the right tools automatically — no glue code needed.

Three ways to connect

All paths use the same backend. Tier limits (Free = all crypto + 300 rpm + 5K credits/mo; Pro = all crypto + 300 rpm + 50K credits + WebSocket; Scale = all markets + Hyperliquid + 1000 rpm + 500K credits; Enterprise = everything + 3000 rpm + 5M credits + Team access) are enforced server-side against your account.

1. Claude.ai web (one-click OAuth — easiest)

Connect directly from Claude on the web. No API key to copy, no config files — sign in once and Claude is connected. An API key is minted in your Resolved Markets account behind the scenes (visible in /api-keys labeled Claude · MCP), and you can revoke access any time from that page.

  1. Go to claude.ai/customize/connectors.
  2. Click the + button (top right), then choose Add custom connector.
  3. Enter a name (e.g. Resolved Markets) and paste this as the Remote MCP server URL: https://mcp.resolvedmarkets.com/mcp
  4. Leave OAuth Client ID and OAuth Client Secret empty — dynamic registration handles them automatically.
  5. Click Connect. A popup will open on resolvedmarkets.com.
  6. Sign in to your Resolved Markets account (or create one).
  7. Review the consent screen and click Allow access. You'll be redirected back to Claude with the connector now Connected.

Open a Claude conversation, pick the Resolved Markets connector from the tools menu, and ask something like “what BTC prediction markets are live right now?”.

2. Hosted endpoint with API key (Claude Desktop, Claude Code, ChatGPT, custom agents)

Connect any MCP client to https://mcp.resolvedmarkets.com/mcp and pass your key in the X-API-Key header. Zero install, always up to date. Use this for clients that don't support OAuth or when you want to script with a long-lived key.

For Claude Desktop or Claude Code, bridge via mcp-remote:

{
  "mcpServers": {
    "resolvedmarkets": {
      "command": "npx",
      "args": [
        "-y", "mcp-remote",
        "https://mcp.resolvedmarkets.com/mcp",
        "--header", "X-API-Key: rm_your_api_key_here"
      ]
    }
  }
}

Authorization: Bearer rm_... is also accepted if your client prefers it.

3. Self-hosted / local (npm)

Run the package locally — the stdio process reads the key once from HF_API_KEY. Best for offline tooling or multi-tenant agents that manage keys themselves.

Claude Desktop — add to claude_desktop_config.json:

{
  "mcpServers": {
    "resolvedmarkets": {
      "command": "npx",
      "args": ["-y", "@elcara-hq/resolvedmarkets-mcp"],
      "env": {
        "HF_API_URL": "https://api.resolvedmarkets.com",
        "HF_API_KEY": "rm_your_api_key_here"
      }
    }
  }
}

Claude Code:

claude mcp add resolvedmarkets -- npx -y @elcara-hq/resolvedmarkets-mcp
export HF_API_KEY=rm_your_api_key_here

One-off via npx:

HF_API_KEY=rm_your_api_key_here npx @elcara-hq/resolvedmarkets-mcp

Recommended call patterns

Most agent tasks fall into one of five patterns. Following these avoids wasted calls and keeps tier-limit errors from masking real problems.

  • Discover what's available list_categorieslist_markets (filter by category/subcategory).
  • Live state of a known market get_market (slug → conditionId)get_orderbook.
  • Historical analysis of one market → resolve to a conditionId → get_market_summary (7-day overview) query_snapshots (paginated time-series, the core analysis tool).
  • Point-in-time market state get_snapshot (searches up to 1h before the requested UTC timestamp).
  • Cross-market comparison (Polymarket vs. Hyperliquid perps) → get_orderbook + get_exchange_orderbook (Pro+ only).

Slugs vs. conditionIds. Slugs (e.g. btc-updown-5m) are human-readable and rotate as new windows open — they only resolve to currently active markets. The conditionId is a stable 0x-prefixed string that uniquely identifies a market for its whole lifetime; most tools require it. Always pass a slug through get_market first to lock down the conditionId before calling deeper analysis tools.

Tools — full reference

All 12 tools, with parameter schemas and key behavior. Pasting any of these signatures into your agent prompt is enough for it to call the tool correctly. Tier requirements are noted inline; calls that exceed the caller's tier return a structured hint with the upgrade path.

Discovery & metadata

list_categories

List all market categories with counts and capture intervals.

  • Parameters: none.
  • Returns: array of { category, subcategories[], active_count, capture_interval_ms }.
  • Tier: any (including free).
  • Use first to understand what data is available before listing markets.

list_markets

List currently-tracked (live) markets with token IDs, slugs, expiry, and category metadata.

  • Parameters (all optional):
    • category — one of crypto | sports | economics | weather | social | equities
    • subcategory — e.g. BTC, NBA, FOMC, NYC, Elon, SPX
  • Tier: any. Free & Pro see all crypto coins (crypto only); Scale/Enterprise see all categories.
  • Do not use for closed/past markets — use list_historical_markets instead.

list_historical_markets

List closed or past markets. Each row includes snapshot_count + first_seen / last_seen so you can pick one to analyze.

  • Parameters (all optional):
    • moderecent (default, paginated, fast) or full (everything ever stored, heavier)
    • cryptoBTC | ETH | SOL | XRP (crypto category only)
    • timeframe5m | 15m | 1h | 1d (crypto category only)
    • category, subcategory — same as list_markets
    • limit — 1–500, default 100. Used only when mode="recent".
  • Tier: all tiers (including Free) have unlimited history.

get_market

Resolve a single market by slug into conditionId + token IDs + status.

  • Parameters:
    • slug (required) — full, partial, or timestamped, e.g. btc-updown-5m.
  • Returns: { market_id, crypto, timeframe, tokenIdUp, tokenIdDown, expiresIn, active, expired }.
  • Tier: any.
  • Use this before tools that take a market_id when you only have the slug.

Live orderbook

get_orderbook

Live orderbook for a market — bid/ask arrays, best bid/ask, mid price, and depth for both UP and DOWN tokens.

  • Parameters (exactly ONE required):
    • market_id — 0x-prefixed conditionId.
    • OR slug — only works for active markets, e.g. btc-updown-5m.
  • Returns: { up: { bids[], asks[], mid, spread, depth }, down: {…} }.
  • Tier: Free is limited to 20 orderbook levels per side. Pro / Enterprise see full depth.
  • Common error: passing both market_id and slug, or neither, returns a clear validation error.

get_exchange_orderbook

Live orderbook from a centralized exchange (currently Hyperliquid perpetual futures). Useful for comparing Polymarket prediction prices against the underlying perp.

  • Parameters:
    • exchangehyperliquid_perp (default; only value today).
    • symbol (required)BTC | ETH | SOL | XRP.
  • Tier: Pro+ required. Free tier hits 403 with upgrade hint.

Historical snapshots

get_snapshot

Orderbook snapshot at (or just before) a specific UTC timestamp. The backend searches up to 1 hour before the requested time.

  • Parameters:
    • timestamp (required) — UTC, YYYY-MM-DD HH:MM:SS[.mmm] or ISO 8601.
    • market_id — filter to a conditionId.
    • crypto / timeframe — same enums as list_historical_markets.
    • include_book — boolean, default false. Off keeps the response small.
  • Tier: all tiers have unlimited history (no 24h cap).

get_latest_snapshots

The 5 most recent snapshots across all markets. Mainly a data-freshness probe.

  • Parameters (all optional): crypto, timeframe, include_book.
  • Tier: any. Subject to per-row tier restrictions on which markets show up.

query_snapshots

Paginated time-series of orderbook snapshots for one market. The core analysis tool.

  • Parameters:
    • market_id (required) — conditionId.
    • sideUP or DOWN. Restricting to one side roughly halves response size and speeds queries.
    • from / to — UTC range, YYYY-MM-DD HH:MM:SS.
    • limit — 1–5000 (default 500). Cap drops to 2000 when include_book=true because payloads get much larger.
    • offset — pagination, default 0.
    • include_book — boolean, default false. Per-row bid/ask arrays.
    • orderasc or desc (default desc).
  • Returns: { market_id, total, limit, offset, data: [snapshot, …] }. Loop on offset using data.length & total to page through the full window.
  • Tier: all tiers see the full archive — history is unlimited on every plan.
  • Best practice: for trend analysis, fetch without include_book first to study mid/spread; pull include_book=true only on a smaller refined window if you need the full book.

get_exchange_snapshots

Historical orderbook snapshots from an exchange (Hyperliquid perps), sampled at ~1/sec. Lightweight rows — best bid/ask, mid, spread, depth, no full arrays.

  • Parameters: exchange, symbol (required), from, to, limit (1–5000, default 500).
  • Defaults to last 24h if no range given.
  • Tier: Pro+ required.

Aggregates & system

get_market_summary

Aggregated 7-day statistics for one market.

  • Parameters: market_id (required) — conditionId. Use get_market to resolve a slug first.
  • Returns: snapshot count, avg/min/max mid price & spread, avg crypto price, per-side (UP/DOWN) breakdowns.
  • Tier: any (subject to tier history depth).

get_system_stats

System-wide health and price snapshot. Combines authenticated /v1/stats with public stats; either can be null if unavailable.

  • Parameters: none.
  • Returns: { stats, publicStats } with active market count, total snapshots, per-crypto breakdown, current crypto prices (BTC/ETH/SOL/XRP), pipeline health.
  • Tier: any.

Tier limits at a glance

Every tool call passes through the same tier check. When a request exceeds the caller's tier, the tool returns a structured error explaining the limit and pointing to the upgrade page; the agent can relay this to the user verbatim.

LimitFreeProScaleEnterprise
Monthly credits5,00050,000500,0005,000,000
Crypto marketsBTC, ETH, SOL, XRPBTC, ETH, SOL, XRPBTC, ETH, SOL, XRPBTC, ETH, SOL, XRP
Orderbook depthFullFullFullFull
History depthFull archiveFull archiveFull archiveFull archive
Rate limit (req / min)3003001,0003,000
Sports / Economics / Weather / Social / Equities
Hyperliquid perps (get_exchange_*)
WebSocket connections1510
API keys251020
MCP accessfullfullfullfull

Resources

MCP resources are read-only data sources the host can pull as context. Both resources below return JSON identical to the equivalent REST endpoint and refresh on each read.

URIDescriptionEquivalent REST
markets://liveCurrently active markets with token IDs and metadataGET /v1/markets/live
prices://latestCurrent cryptocurrency prices and pipeline/exchange statsGET /v1/public-stats

Common errors & how to fix them

SymptomLikely causeFix
401 on every callNo API key, malformed key, or revoked keyGenerate or restore a key at /api-keys. Hosted endpoint with API-key auth must pass X-API-Key or Authorization: Bearer rm_… on every request.
403 with tier hintTool requires Scale+ (e.g. get_exchange_orderbook or a non-crypto category, which Free/Pro can’t access)Upgrade at /pricing to Scale or Enterprise for all markets and exchange data.
429 rate-limitedBurst over your tier's req/min capWait retryAfterMs from the response or upgrade. Free=60, Pro=500, Enterprise=3000 rpm.
get_orderbook returns "market not found"Slug expired (window rolled over) or wrong conditionIdRe-run get_market or list_markets to get the current slug / conditionId.
query_snapshots returns empty data arrayWindow is before the market existed, or from > toCheck list_historical_markets first for first_seen / last_seen. Order: from < to.
Tool times out on large windowinclude_book=true with a wide rangeDrop include_book (cap is 5000 vs 2000 rows) or shrink the range and page with offset.
Session 401 mid-conversation (hosted)30-minute session expiredRe-initialize. mcp-remote and the claude.ai connector handle this automatically; raw HTTP clients must re-send initialize with the key.
mcp_registration_failed in claude.ai connectorURL entered without /mcp path, or browser already cached a previous failed connectorUse https://mcp.resolvedmarkets.com/mcp (with the path). Delete the failed connector and re-add.

Environment Variables

Used only for the self-hosted/local install. The hosted endpoint needs none of these.

VariableDefaultDescription
HF_API_URLhttp://localhost:3001Backend API URL. Use https://api.resolvedmarkets.com for production.
HF_API_KEYYour API key (rm_...). Required for authenticated tools.
MCP_TRANSPORTstdioTransport mode: stdio or http
MCP_PORT3002HTTP port (when using HTTP transport)

Security

  • Requests without a key (or with a malformed key) are rejected with 401 before a session is opened.
  • The key is re-validated on every request using constant-time comparison — a request that arrives on an existing session with a mismatched key is rejected as a hijack attempt.
  • Sessions auto-expire 30 minutes after initialize. After that, clients must re-initialize. mcp-remote handles this transparently.
  • Never paste your key into a shared MCP config or commit it to a repo — treat it like a password.

Example queries

Once connected, ask your AI agent any of the questions below. Each example shows thetool chain the agent will likely call so you can predict the cost and verify the result.

Single-call questions

  • “What market categories does Resolved Markets track?” — list_categories
  • “What BTC prediction markets are live right now?” — list_markets({ category: "crypto", subcategory: "BTC" })
  • “How's the data pipeline performing?” — get_system_stats
  • “Show me the latest snapshots to confirm data is live” — get_latest_snapshots

Two-call lookups

  • “Show me the live orderbook for btc-updown-5m” → get_market("btc-updown-5m")get_orderbook({ market_id })
  • “Give me a 7-day summary for the current SOL 15m market” → list_markets({ category: "crypto", subcategory: "SOL" }) get_market_summary({ market_id })

Time-series analysis

  • “What was the BTC 5m spread around 2026-03-02 10:42 UTC?” → get_snapshot({ timestamp, crypto: "BTC", timeframe: "5m" })
  • “Pull the last 500 snapshots for that market and chart the spread trend” → query_snapshots({ market_id, limit: 500, order: "asc" }) → client-side aggregation
  • “Show me the full orderbook depth every minute for the last hour” → query_snapshots({ market_id, from, to, include_book: true, limit: 2000 })

Cross-market comparison (Pro+)

  • “Compare the Polymarket BTC prediction price to the Hyperliquid BTC perp right now” → get_orderbook({ slug: "btc-updown-5m" }) + get_exchange_orderbook({ symbol: "BTC" })
  • “Was Hyperliquid BTC perp leading or lagging Polymarket during the last 4 hours?” → both query_snapshots and get_exchange_snapshots over the same range, correlate offline.

Discovery-first workflows

  • “Find me an interesting volatile market right now” → list_markets({ category: "crypto" }) → for each → get_market_summary → pick the one with the widest spread range.
  • “Are there any active sports markets with under 30 minutes to expiry?” → list_markets({ category: "sports" }) → filter on expiresIn.

HTTP Transport

For remote integrations or custom agents, run the local server in HTTP mode:

MCP_TRANSPORT=http MCP_PORT=3002 npx @elcara-hq/resolvedmarkets-mcp

Endpoint: POST http://localhost:3002/mcp

MCP Server — API Docs | Resolved Markets