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.
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。