Continental-MCP-Server
A research-only MCP server providing read-only data, analytics, and intelligence for Polymarket BTC 5-minute Up/Down markets, enabling LLM agents to query market snapshots, performance metrics, and strategy candidates.
README
Continental-MCP-Server
A 24/7 data-collection, analytics, and intelligence service for Polymarket BTC 5-minute Up/Down markets, exposed to LLM agents over the Model Context Protocol (MCP). It runs on an Ubuntu VPS and is strictly research-only: no API keys, no order placement, no bot-status decisions. Every response is framed as evidence (data with sample sizes, confidence intervals, and freshness), not trading advice.
Consumers are (a) LLM agents via MCP, (b) a trading bot via a read-only REST
data plane + ingest, and (c) humans via reports and Telegram alerts. The Python
package is named pmre (pm-research-engine); this repository is the MCP server
that fronts it.
For agents: connect to the MCP server
The server speaks Streamable HTTP with bearer-token auth and is
read-only. Any MCP-capable client (Claude, the OpenAI Agents SDK, OpenAI's
hosted {"type": "mcp"} tool, custom clients) can auto-discover every tool via
tools/list and call it — you do not hand-wire the tools.
- Endpoint:
http://<host>:8090/mcp(default port8090) - Transport: Streamable HTTP
- Auth:
Authorization: Bearer <PMRE_MCP_BEARER_TOKEN>on every request (a missing/invalid token returns401) - Network: bind to a private WireGuard/Tailscale overlay IP — never expose it publicly
Claude Code / mcp.json
{
"mcpServers": {
"continental": {
"type": "http",
"url": "http://127.0.0.1:8090/mcp",
"headers": { "Authorization": "Bearer <PMRE_MCP_BEARER_TOKEN>" }
}
}
}
OpenAI Agents SDK (Python)
A complete, runnable example lives at examples/openai_agent_mcp.py:
from agents import Agent, Runner
from agents.mcp import MCPServerStreamableHttp
async with MCPServerStreamableHttp(
name="continental",
params={
"url": "http://127.0.0.1:8090/mcp",
"headers": {"Authorization": "Bearer <PMRE_MCP_BEARER_TOKEN>"},
},
cache_tools_list=True,
) as server:
agent = Agent(name="analyst", model="gpt-4o-mini", mcp_servers=[server])
result = await Runner.run(agent, "Is the engine healthy? What is the "
"strongest candidate by CI-lower net EV?")
print(result.final_output)
Response envelope
Every tool response is wrapped in a freshness envelope carrying
data_last_updated_at, current_session, session_integrity, and any
warnings. Decisions should be made on CI lower bounds, never point
estimates.
Tools (16, all read-only)
| Tool | Returns |
|---|---|
get_system_health |
Which collectors are alive/silent + recent incidents |
get_current_session |
Primary/overlap session, integrity, seconds to next boundary |
get_current_btc5m_market |
Active + next market: token ids, price-to-beat, fee params, tick size |
get_latest_market_snapshot |
Latest order book: mids, spreads, depth, fee estimate |
get_timestamp_performance |
Per-timestamp win rate, net EV (taker/maker), CI-lower, Brier |
get_calibration_curve |
Reliability curve (win rate vs price) per 2¢ bin, Wilson CIs, FDR flags |
get_session_performance |
Performance per session/overlap (each with its own n and CI) |
get_regime_performance |
Performance per volatility regime |
get_fee_parameters |
Fee params for a market (feesEnabled, rate, model version) + history |
get_fair_value_snapshot |
Fair-value output: p_fair, z_score, sigma_1s, model_edge |
get_maker_fill_estimates |
P(fill) and time-to-fill for hypothetical maker posts |
get_strategy_candidates |
Strategy candidates with status + full evidence |
get_champion_strategy |
Current champion strategy and its CI-lower net EV (or null) |
get_paper_trade_performance |
Aggregated paper-trade telemetry ingested from the bot |
get_analysis_run_summary |
Summary of an analysis run: counts, versions, deterministic hash |
get_data_quality_report |
Snapshot counts, stale/crossed/close-call rates over a window |
Resources
| URI | Contents |
|---|---|
pmre://methodology |
Calibration-first, CI-lower decisions, BH-FDR, dual-scope sessions |
pmre://data-dictionary |
Schema / field dictionary for the served tables |
pmre://fee-model |
Dynamic taker fee curve notes |
pmre://daily-report |
Latest daily research report (markdown) |
Run the server
uv sync
# Set the MCP bearer token (and other secrets) — copy the template first.
cp .env.example .env # then edit PMRE_MCP_BEARER_TOKEN, PMRE_DATABASE_URL, ...
uv run python -m pmre migrate # create/upgrade the schema
uv run python -m pmre serve-mcp # MCP server on PMRE_SERVING_HOST:PMRE_MCP_PORT (default :8090)
./run.sh launches the whole system locally (migrate + calendar + collectors +
REST + MCP + hourly analytics). Modes: all (default), serve (no collectors),
demo (synthetic offline dataset), collectors. See the header of run.sh.
Relevant environment variables (all PMRE_-prefixed; see .env.example):
| Variable | Purpose |
|---|---|
PMRE_MCP_PORT |
MCP server port (default 8090) |
PMRE_MCP_BEARER_TOKEN |
Bearer token agents must present |
PMRE_SERVING_HOST |
Bind address — set to the overlay IP |
PMRE_DATABASE_URL |
Postgres 16 + TimescaleDB in prod; SQLite for dev/tests |
PMRE_ENV |
dev or production (prod fails fast on any unset secret) |
What the engine does
- Fees are first-class — dynamic taker-fee curve
rate·p·(1−p); every EV in gross / net-taker / net-maker variants; maker entries are a first-class family. - Calibration-first analytics — reliability curves (win rate vs price) with Wilson CIs; decisions on CI-lower net EV, never point estimates.
- Multiple-testing control — Benjamini-Hochberg FDR (q=0.10) on every bucket claim; a null dataset produces ~zero "edges" (the project's most important test).
- Fair-value benchmark —
p_fair = Φ(z),z = ln(S/S_ptb)/(σ_1s·√τ), independent of the empirical tables. - Session & holiday model — tz-native Tokyo/London/New York + overlaps;
holidays are integrity labels (regular/holiday/half_day/weekend), not
closures. Every metric ships at
totalAND per-session scope. - Two facades, one service layer — FastAPI REST (bot) + MCP (agents), both read-only, both stamped with freshness + evidence + current session.
- Storage triad — PostgreSQL 16 + TimescaleDB (hypertables + compression), daily Parquet exports, zstd raw JSONL archive (replayable).
Layout
src/pm_sessions/ shared, versioned session/calendar model (the bot reuses it)
src/pmre/
config.py pydantic-settings (fails fast on missing prod secrets)
db/ SQLAlchemy models (all v1+v2 tables) + engine + timescale
collectors/ slugs, discovery, clob_ws (book engine), snapshotter,
btc_feed, resolution, calendar_job, supervisor
features/ fair_value, btc_state
analytics/ stats (Wilson/BH), ev, calibration, regime, maker_fill,
walkforward, runner, reports
registry/ candidates, gates, extractor (research_only -> ... -> disabled)
serving/ service (shared), envelope, auth, ingest,
rest/ (FastAPI), mcp/ (FastMCP) <-- MCP server lives here
ops/ health, alerts, clock, watchdog, backup, systemd_notify
parquet_export.py daily exporter + duckdb + replay
cli.py `python -m pmre <command>`
tests/ unit + integration + golden fixtures
deploy/ systemd units/timers, compose, Caddy, wireguard, runbooks
REST facade (for the bot, not agents)
serve-rest exposes read-only GET /v1/health|session/current|markets/current| snapshots/latest|performance/*|candidates*|fills/maker-estimates| fairvalue/params|fees/parameters|quality/report|analysis/summary plus ingest
POST /v1/ingest/paper-trades|bot-decisions|bot-heartbeat. Bearer auth (read vs
ingest scopes), freshness envelope on every read.
Development
uv sync
uv run pytest # full suite (SQLite; no Docker needed)
uv run ruff check src tests
# End-to-end on a throwaway DB: seed synthetic data with a planted, persistent
# NY-session edge, run analytics -> walk-forward -> candidate extraction.
export PMRE_DATABASE_URL="sqlite+pysqlite:///./pmre.db"
uv run python -m pmre migrate
uv run python -m pmre pipeline-demo --days 25 # discovers the planted edge
uv run python -m pmre daily-report
Testing on real PostgreSQL + TimescaleDB
docker run -d --name pg -e POSTGRES_USER=pmre -e POSTGRES_PASSWORD=pmre \
-e POSTGRES_DB=pmre -p 55432:5432 timescale/timescaledb:latest-pg16
PMRE_TEST_POSTGRES_URL=postgresql+psycopg2://pmre:pmre@127.0.0.1:55432/pmre \
uv run pytest tests/test_postgres_integration.py
Deployment
deploy/ ships systemd units/timers (pmre-mcp.service, pmre-rest.service,
analytics/backup timers), a Docker Compose stack, a Caddyfile, and WireGuard
notes. Bind both facades to the overlay IP; nothing is public. See
deploy/README.md for install, runbooks, and chaos drills.
Design docs
mcp_plan.md (v2.1 spec) and mcp_phases.md (the 10 build phases) document the
full design and status. All phases are implemented and tested.
Research only. Every response is evidence — data with n, confidence intervals, and freshness — not trading advice.
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.