Skip to main content
Glama
ciinkwia

prediction-market-signal-mcp

by ciinkwia
README.md
# prediction-market-signal-mcp

Live **Polymarket + Kalshi prediction-market odds, movers, price history, cross-platform gaps,
watch, and X/Twitter sentiment** inside Claude, Cursor, or any MCP client — **no API key, no
subscription, no monthly minimum.** Your agent pays a fraction of a cent per call in USDC on Base
using [x402](https://x402.org).

```
pm_search          $0.01/call    markets matching a question, Polymarket + Kalshi, ranked
pm_odds            $0.02/call    headline per platform, cross-platform gap, 7-day history, summary
pm_movers          $0.02/call    biggest probability swings (Polymarket, liquid markets)
pm_history         $0.02/call    one market's probability series, with first/last/high/low
pm_ticker_events   $0.01/call    open markets mentioning a US stock ticker or company
pm_sentiment       $0.05/call    markets AND X/Twitter chatter on the same question, one call
pm_watch           $0.02/call    only what moved since your last check (stateless cursor)
pm_gaps            $0.02/call    biggest Polymarket-vs-Kalshi disagreements, same question
pm_closing         $0.01/call    markets settling soon, both platforms
pm_resolved        $0.01/call    markets that just settled, with the outcome
pm_example         free          a real capped pm_odds result, no wallet needed
```

**Facts only — not investment advice.** Every answer is implied probability, volume, and price
history from the markets themselves (plus, for `pm_sentiment`, a plain read of what X/Twitter is
saying). Nothing here is a buy/sell/hold signal, a trade recommendation, or financial advice.

## Why this exists

Prediction markets (Polymarket, Kalshi) already price real-world questions — elections, Fed
decisions, macro events — as crowd-forecast odds. Reading them across two platforms usually means
two different SDKs, two rate limits, and no cross-platform comparison. This server does both in
one call, charges per request instead of a subscription, and there is nothing to cancel.

## Tools

### `pm_search` — $0.01
Markets on Polymarket + Kalshi matching a question or topic, ranked by relevance, each with
probability, 24h change, volume, close date, URL, and id (use the id with `pm_history` or
`pm_watch`). Inputs: `q` (required), `limit` (optional, 1-50, default 20).

### `pm_odds` — $0.02
"What do the markets say" for one question — the headline market per platform, the cross-platform
probability gap, 7-day history, and a one-line summary:

```json
{
  "headline": { "polymarket": {...}, "kalshi": {...}, "gap_pts": 4 },
  "history_7d": { "points": [...] },
  "summary": "..."
}
```

Input: `q` (required). Use `pm_search` instead when you want the full ranked list.

### `pm_movers` — $0.02
Biggest 24h/7d probability swings among liquid Polymarket markets — what's newly hot. Inputs:
`window` (optional, `24h` default or `7d`), `limit` (optional, 1-50, default 20).

### `pm_history` — $0.02
One market's probability series over time, first/last/high/low. Inputs: `id` (required — a
Polymarket condition id/slug/numeric id, or a Kalshi ticker, from `pm_search`), `interval`
(optional, `1d`/`1w`/`1m`/`max`, default `1w`).

### `pm_ticker_events` — $0.01
Open Polymarket + Kalshi markets mentioning a US stock ticker or company (a bare ticker like
`TSLA` is also matched against the company name, `Tesla`). Facts only — implied probability, 24h
change, volume — never a trade signal. Inputs: `q` (required — ticker or company/topic), `limit`
(optional, 1-50, default 20).

### `pm_sentiment` — $0.05
What the markets say AND what X/Twitter is saying about the SAME question, one call: headline
market probability, an AI read of X chatter's yes/no lean, key themes, driving accounts, notable
post URLs, and an `aligned` / `diverges` / `no_clear_read` verdict comparing the two:

```json
{
  "summary": "Markets price \"...\" at 62%. X chatter (14 recent posts) leans YES — aligned with the market.",
  "agreement": "aligned",
  "market": { "polymarket": {...}, "kalshi": {...}, "gap_pts": 3 },
  "x": { "lean": "yes", "lean_note": "...", "summary": "...", "key_themes": [...] }
}
```

Input: `q` (required). No market matched on either platform = no charge.

### `pm_watch` — $0.02
Monitor 1-20 market ids or a topic, get back only the change since your last check: current
probability, `change_since_cursor` (probability points), a `moved` flag, and (for a topic watch)
newly-listed markets. Pass the response's `cursor` back in next time — it's stateless, so you can
run any number of watches in parallel. Inputs: `ids` (1-20 comma-separated ids) OR `q` (a topic) —
provide one, not both; `cursor` (optional, omit on the first call); `min_move` (optional,
probability points, default 3). **Nothing moved and nothing new = no charge** — the fresh cursor
still comes back so your monitor keeps its place.

### `pm_gaps` — $0.02
Biggest Polymarket-vs-Kalshi disagreements on the SAME question — matched by topic, close date,
and shared numbers, with a `match_confidence` score and a polarity check so opposite-side matches
never show as a misleading gap. Served from a snapshot rebuilt every 30 minutes. Inputs: `limit`
(optional, 1-50, default 20), `min_gap` (optional, probability points, default 5), `q` (optional
topic filter). No matches at that gap size = no charge; snapshot not built yet after a cold start
= free, retry shortly.

### `pm_closing` — $0.01
Markets on both platforms closing within 24h or 7d, sorted by volume. Inputs: `window` (optional,
`24h` default or `7d`), `limit` (optional, 1-50, default 20), `q` (optional topic filter).

### `pm_resolved` — $0.01
Markets on both platforms that settled within 24h or 7d, with the final outcome and last price —
for grading a forecast against reality. Same inputs as `pm_closing`.

### `pm_example` — free
A real `pm_odds` result for a fixed question ("fed rate cut"), capped to 5 markets and 12 history
points, refreshed every 6 hours. **No wallet, no payment, no x402 needed** — use it to see the
answer shape before spending on any paid tool. No inputs.

## Setup

You need a Coinbase CDP wallet funded with a little USDC on Base — that wallet pays per call.
Create one at [portal.cdp.coinbase.com](https://portal.cdp.coinbase.com) (API key + wallet secret).
`pm_example` works without any of this — it's free.

**Claude Desktop / Claude Code** — add to `claude_desktop_config.json` (or `.mcp.json` for Claude
Code):

```json
{
  "mcpServers": {
    "prediction-market-signal": {
      "command": "npx",
      "args": ["-y", "prediction-market-signal-mcp"],
      "env": {
        "CDP_API_KEY_ID": "your-key-id",
        "CDP_API_KEY_SECRET": "your-key-secret",
        "CDP_WALLET_SECRET": "your-wallet-secret",
        "X402_MAX_PRICE": "0.05"
      }
    }
  }
}
```

**Cursor** — Settings → MCP → Add new MCP server, same command/args/env as above.

`X402_MAX_PRICE` is a hard per-call ceiling in USD. If the endpoint ever quotes more than this,
the request is refused **before** anything is signed — no charge. The default `0.05` already
covers every paid tool above (the priciest is `pm_sentiment` at $0.05) — you don't need to raise it.

## Payment

**x402, bring-your-own-wallet.** Every paid tool pays from the wallet you configure — your own
Coinbase CDP account, funded with USDC on Base. There is no server-side wallet and no shared
account: each call signs its own USDC authorization, and the endpoint's facilitator settles it on
Base. Gas is covered by the facilitator; you spend USDC only.

## Cost & safety

- You are only ever charged for a successful answer. Invalid inputs are rejected **before**
  payment (HTTP 400, no settlement).
- **Nothing found = nothing charged.** An empty `pm_search` / `pm_ticker_events` / `pm_gaps` /
  `pm_closing` / `pm_resolved` / `pm_sentiment` comes back as `no_results` with `charged: false` —
  the payment is never settled.
- **`pm_watch` only charges when something moved or something new appeared.** A check that finds
  nothing new is free — poll it on a schedule without worry.
- **`pm_gaps` before its 30-minute background snapshot has finished its first build** answers free
  (503) instead of charging for an incomplete answer.
- If the upstream market data fails after payment, the API returns an explicit `error` and logs
  the call for refund rather than pretending it worked.
- **Facts only, not investment advice.** Every number is a market price or a plain read of public
  chatter — never a recommendation to trade, a price target, or a buy/sell/hold call.

## How it works

```
MCP client → prediction-market-signal-mcp → 402 challenge → sign USDC authorization
           → facilitator settles on Base → data returned
```

Protocol: **x402 v2** (CAIP-2 networks, `PAYMENT-REQUIRED` challenge header).

## License

MIT