What FairWhistle is
FairWhistle is a match-integrity surveillance agent. It watches odds microstructure across four books (1X2 + totals 2.5) for patterns consistent with match fixing or informed money, using three transparent, causal detectors โ abnormal repricing velocity, cross-market coordination, and stale-then-snap board freezes (see the rule cards on the live dashboard for exact thresholds). Every detection is published as a timestamped, SHA-256-fingerprinted, Ed25519-signed alert โ evidence-grade, not a black box.
It runs against two sources: a replay fixture โ a committed, seeded, deterministic synthetic tape with 3 openly-labeled planted anomalies, replayed on a 10-minute loop, always available โ and live โ the real FIFA World Cup Final via TxLINE mainnet consensus odds (free tier, ~60s batch delay). FairWhistle prices no trades and makes no execution claims; it answers one question: is there a reason to distrust the current price on this market? Frame it as a trading agent's risk desk โ check it before you trade, not as a strategy in itself.
Read endpoints (raw HTTP)
All are public, CORS-open, no auth. Base URL: https://fairwhistle.vercel.app
| Endpoint | What |
|---|---|
GET /api/alerts | Attested replay-fixture alerts: hashed, Ed25519-signed, current cycle. |
GET /api/live-state?sinceTs= | Live TxLINE surveillance state: odds points, feed events, live alerts. Returns 503 with an honest note if the deployment has no TXLINE_API_TOKEN configured โ expected, not a bug. |
GET /api/meta | Agent identity (Ed25519 pubkey), fixture id, detector rule parameters. |
POST /api/verify | Server-side signature verification. Body: {instance, signature, publicKey}. Also GET /api/verify?id=<alertId> for a replay-cycle alert looked up by id. |
GET /api/feed | text/event-stream SSE push of alerts as they're detected. Long-lived; not wrapped as an MCP tool (a poor fit for request/response) โ use /api/alerts for a snapshot, or subscribe directly for the live stream. |
curl "https://fairwhistle.vercel.app/api/alerts"
curl "https://fairwhistle.vercel.app/api/live-state"
curl "https://fairwhistle.vercel.app/api/meta"
curl -X POST "https://fairwhistle.vercel.app/api/verify" \
-H 'content-type: application/json' \
-d '{"instance": {...}, "signature": "...", "publicKey": "..."}'
curl -N "https://fairwhistle.vercel.app/api/feed"
MCP tools
FairWhistle ships a thin stdio MCP server (mcp/server.mjs in
the repo, using the official @modelcontextprotocol/sdk) that
wraps the read endpoints above โ no detection or attestation logic of
its own, just fetch + a light, honest reshape:
| Tool | Wraps | What |
|---|---|---|
list_active_alerts({ source, severity?, includeEvidence? }) | /api/alerts or /api/live-state | Full current alert set for a sweep. |
get_market_status({ source }) | /api/state or /api/live-state | Replay cycle/minute/score, or live feed/kickoff/game state. |
check_market_integrity({ market, source }) | same as above, filtered | The pre-trade check: clean or flagged for one outcome. |
verify_alert_signature({ source, alertId?, instance?, signature? }) | /api/verify | Confirms an alert's Ed25519 signature. |
check_market_integrity({ market: "a", source: "replay" })
->
{
"verdict": "flagged",
"matchingAlertCount": 1,
"alerts": [{ "core": { "rule": "velocity",
"narrative": "Cirrus Sports repriced 1X2 ยท Away far faster than baseline volatility explains..." } }]
}
source is replay (default, a labeled synthetic
fixture) or live (the real TxLINE feed, ~60s upstream delay,
may be unconfigured on a given deployment โ an honest
available: false there, not a bug). Every tool description
states these caveats in-band; none oversell "real-time" or guaranteed
accuracy.
Installing the MCP server / Claude Code plugin
git clone https://github.com/chaintail/fairwhistle
cd fairwhistle
pnpm install # pulls in @modelcontextprotocol/sdk + zod
node mcp/server.mjs # stdio MCP server; talks to fairwhistle.vercel.app
The repo is also a Claude Code plugin: .claude-plugin/plugin.json
+ .mcp.json wire the fairwhistle MCP server to
node ${CLAUDE_PLUGIN_ROOT}/mcp/server.mjs, and
skills/fairwhistle-integrity/SKILL.md documents tool usage,
when to reach for it as a pre-trade check, honest caveats, and a
described (prose-only, not implemented) pattern for polling live
surveillance during a trade window.
Codex works with the same stdio server via its mcp_servers
config (~/.codex/config.toml):
[mcp_servers.fairwhistle]
command = "node"
args = ["/absolute/path/to/fairwhistle/mcp/server.mjs"]
[mcp_servers.fairwhistle.env]
FAIRWHISTLE_BASE_URL = "https://fairwhistle.vercel.app"
Links
Repo: github.com/chaintail/fairwhistle
Live dashboard: fairwhistle.vercel.app
Live surveillance view: /live.html
Agent index: /llms.txt
Skill: skills/fairwhistle-integrity/SKILL.md