Skip to main content
Glama
YoppaV

polymarket-research

by YoppaV

License: MIT Python 3.10+ tests

polymarket-research

Read-only MCP server that gives Claude Code investigative access to Polymarket — wallet forensics, market metadata, and cross-wallet pattern analysis. No order placement, no signing, no private keys.

All four tiers ship: 21 tools backed by Polymarket's public Gamma + Data + CLOB APIs, a local SQLite cache, and (optionally) Polygon RPC for on-chain enrichment.

Architecture

┌──────────────┐   stdio    ┌──────────────────┐    HTTPS    ┌─────────────────────┐
│  Claude Code │ ─────────► │   MCP server     │ ──────────► │ gamma / clob / data │
│  (or any MCP │            │ (FastMCP, 21     │             │  polymarket APIs    │
│   client)    │ ◄───────── │  tools)          │ ◄────────── │  (public, no auth)  │
└──────────────┘            └──────┬───────────┘             └─────────────────────┘
                                   │
                                   ▼  (cache + cohort queries)
                            ┌─────────────┐                  ┌────────────────────┐
                            │  SQLite     │   opt-in (env)   │  Polygon RPC       │
                            │  (~/.poly…) │ ───────────────► │  (Tier-4 chain     │
                            └─────────────┘                  │   enrichment only) │
                                                             └────────────────────┘

Pure-read: the server never signs or moves funds. Trades are stored append-only in SQLite by (transaction_hash, log_index); profiles are TTL'd. Polygon RPC is fully opt-in via POLYGON_RPC_URL — without it, Tiers 1–3 run end-to-end on the public HTTP APIs alone.

Tier 1 tools — wallet investigation

Tool

What it does

get_wallet_profile

Identity + total portfolio value (cached, TTL 1h).

get_wallet_positions

Open positions, sorted by current USD value.

get_wallet_trades

Trade history, newest first; paginates Data API.

get_wallet_pnl_breakdown

Cash PnL grouped by category / month / market.

get_wallet_top_trades

Largest trades by notional USD; wins/losses filter.

get_wallet_concentration

HHI, Gini, top-5 share, biggest single market.

get_wallet_first_trade

Earliest trade — proxy for "join date".

Tier 2 tools — markets & events

Tool

What it does

get_market

Single market by id / conditionId / slug. Caches payload.

get_market_orderbook

CLOB book snapshot for one outcome (mid, spread, depth).

get_market_holders

Top holders across a market's outcome tokens.

get_market_price_history

CLOB price history for one outcome (1m / 1h / 1d / …).

search_markets

Filter Gamma markets by activity, slug substring, sort.

get_event

Event + child markets by slug or id (e.g. "GTA VI" group).

Tier 3 tools — cross-wallet

Tool

What it does

correlate_wallets

Jaccard + Pearson on bucketed trade timelines; common markets.

find_whale_followers

Lag percentiles for candidates that copy a leader on same market+side.

find_market_cohort

All wallets in the cache that traded a given market (with rollups).

get_cache_stats

Counters of cache contents — trades, traders, markets, etc.

Bulk loader (scripts/ingest_historical.py)

Cohort tools query the local SQLite cache, so populate it first either by running Tier-1 tools against the wallets you care about, or by bulk-loading a historical dataset (CSV / JSONL / JSON):

venv/bin/python scripts/ingest_historical.py \
  --file ~/data/polymarket_trades.csv --format csv \
  --col-tx-hash transactionHash --col-wallet proxyWallet \
  --col-condition-id conditionId --col-ts timestamp

--dry-run, --since 2024-01-01, --limit N, and --db-path are all supported. Re-running is idempotent (PK is (tx_hash, log_index)).

Tier 4 tools — forensics

Tool

What it does

find_data_source_concentrators

Cluster active markets by resolver/source; rank by aggregate volume.

compare_entry_to_consensus

Compare a trade's entry vs CLOB consensus mid at trade time (bps deviation).

get_wallet_alpha_decay

Bucket a wallet's trades on a market into deciles of its lifetime; surfaces early-vs-late edge.

get_wallet_timing_pattern

UTC hour-of-day histogram + best-effort timezone inference.

compare_entry_to_consensus accepts an optional enrich_with_chain=True flag that looks up the trade's block timestamp via Polygon RPC. That path is opt-in: set POLYGON_RPC_URL and install the chain extra (pip install -e '.[chain]'). Without it, the tool runs purely off CLOB price history.

Setup

git clone <this repo>
cd polymarket-mcp
uv venv venv --python python3.12
uv pip install --python venv/bin/python -e .

(python3 -m venv venv works too if you have python3-venv installed.)

Environment

Var

Default

Purpose

POLYMARKET_GAMMA_BASE

https://gamma-api.polymarket.com

Override Gamma host.

POLYMARKET_CLOB_BASE

https://clob.polymarket.com

Override CLOB host (Tier 2).

POLYMARKET_DATA_BASE

https://data-api.polymarket.com

Override Data host.

POLYGON_RPC_URL

(unset)

Polygon RPC for Tier 4 forensics.

POLYMARKET_RATE_LIMIT_RPS

5

Per-host token-bucket cap.

POLYMARKET_DB_PATH

~/.polymarket_research.db

SQLite cache file.

POLYMARKET_CACHE_MODE

warm

warm / bypass / offline.

Run the server standalone

PYTHONPATH=src venv/bin/python -m polymarket_research.server

You should see the FastMCP banner; the process is now listening on stdio.

Connect via Claude Code

A ready-to-go .mcp.json ships at the repo root. From inside Claude Code, either start it from this directory or symlink the file. Then restart the MCP layer (or run /mcp restart polymarket-research) and the seven tools above appear under polymarket-research:*.

Recipes

Investigate a wallet:

> Use polymarket-research:get_wallet_profile on 0x<wallet>.
> Then get_wallet_concentration and pnl_breakdown by category.

Spot a high-conviction position:

> get_wallet_top_trades 0x<wallet> by notional_usd, n=10, side=losses
> compare those trades to get_wallet_pnl_breakdown by market

Find a wallet's earliest activity:

> get_wallet_first_trade 0x<wallet>

Replace <wallet> with any Polymarket trader address — use search_markets

  • get_market_holders to discover candidates on markets that interest you.

Cache

Trades are stored append-only by (transaction_hash, log_index); wallet and market profiles are TTL'd. Inspect manually:

sqlite3 ~/.polymarket_research.db ".schema"
sqlite3 ~/.polymarket_research.db "SELECT COUNT(*) FROM trades"

Reset the cache by deleting the file. The schema is recreated on next run.

Tests

PYTHONPATH=src venv/bin/python -m pytest tests/ -v --cov=polymarket_research

126 tests, ~90% coverage on parsers/analytics. Heavy coverage on the pure layer; endpoints exercise fakes for HTTP and :memory: SQLite for cache.

Read-only invariant

This server never imports a private key, never signs, never places an order. Verify with:

grep -rEn 'sign|private_key|eip712|order_place|submit_order|wallet_create' src/

(Any hits should be substrings inside docstrings or comments — never live code.)

Disclaimer

This server reads only public Polymarket and Polygon on-chain data. It does not sign, place orders, or move funds. Outputs (concentration, alpha decay, timing patterns, cohort overlaps) are research signals — not financial advice. Use of the tool implies acceptance that all analyzed data is public and that the author is not affiliated with Polymarket.