langbot-mcp
MCP server for Langbot, the data and simulation layer for every market on Kalshi and Polymarket: search any market and read its price history, compare the same question across both venues, replay past events against the order books Langbot recorded, and, for markets that settle on what is said (mention markets are one example), the live record of the event with verifiable receipts. Data, never trading signals or advice: the optional strategy tools are off unless you opt in.
Over local stdio, search_markets and get_market_history work without a token.
uvx langbot-mcp # stdio — what Claude Code / Cursor / Claude Desktop / Codex run
langbot-mcp --http # streamable HTTP on 0.0.0.0:8001 at /mcp (hosted: https://mcp.langbot.ai/mcp); multi-tenant, token per request
langbot mcp install claude-code # one-command install (also: cursor, claude-desktop, codex, all)
Manual client entry:
{ "mcpServers": { "langbot": { "command": "uvx", "args": ["langbot-mcp"], "env": { "LANGBOT_API_TOKEN": "lb_…" } } } }
Hosted, for clients that send headers (Cursor, Claude Code --transport http):
{ "mcpServers": { "langbot": { "url": "https://mcp.langbot.ai/mcp", "headers": { "Authorization": "Bearer lb_…" } } } }
Auth. Each tool's _meta has langbot/auth (none | token: what the feed needs, which is
what applies over local stdio) and langbot/auth_hosted (always bearer). The hosted endpoint
needs Authorization: Bearer lb_… on every tool call and resource read, including none tools;
without a token, run it locally (uvx langbot-mcp).
Tools
| tool | what |
|---|---|
search_markets(query, venue?, status, category?, limit) |
every Kalshi and Polymarket market Langbot lists (no token on stdio) |
get_market_history(ticker, max_points=200) |
one market's status, result and price history; whether its books can be replayed (no token on stdio) |
list_live_events() |
live + upcoming events with sources, markets, phrases |
list_markets(query, venue?, status) |
public market metadata search |
get_market_rules(ticker) |
rules text + phrases for one market |
subscribe_phrases(event_id, phrases[], webhook_url?) |
account subscription (needs token) |
get_transcript(event_id, since_seq?, limit=2000) |
one page of transcript words + text and last_seq (pass back as since_seq); empty with redacted_sources for restricted sources |
get_recent_events(event_id?, phrases?, limit) |
latest phrase detections / lifecycle events |
get_latency_stats() |
per-source p50/p90 lag vs public stream |
watch_event(event_id, phrases?, max_wait_s=30, cursor?) |
long-poll: new phrase hits (with §21 verdict) since cursor, waits ≤ 60 s; token |
Langbot Sim
| tool | what |
|---|---|
sim_events() |
past events with a feed record and recorded Kalshi books: coverage (book rows, first/last snapshot, tickers, settled markets), Free sample flag, the caller's allowance (public) |
sim_run(event_id, strategy, params?, latency_ms?, starting_cash, detail) |
a built-in strategy (hold_none, buy_yes_on_first_counting_hit, buy_yes_near_threshold, fade_rule_mismatch) replayed on the feed → scorecard with the latency table and caveats (token; langbot/per_call_usd 0.25 via x402 without a plan). Custom code never runs on the server: langbot sim run --strategy my_bot.py runs it locally |
Opt-in strategy tools (LANGBOT_MCP_STRATEGY_TOOLS=1)
Off by default: Langbot serves data, not signals. Set LANGBOT_MCP_STRATEGY_TOOLS=1 in the
client's env to list and allow these three; without it they are hidden and cannot be called.
| tool | what |
|---|---|
draft_strategy(thesis, speaker?, phrase?, series?, window_days) |
Claude drafts a langbot.Strategy file (template without ANTHROPIC_API_KEY); with speaker/phrase it fetches base rates and prices the draft off them |
backtest_strategy(code, event_ids[] | fixture) |
replay through a paper broker → PnL summary |
run_paper(strategy_path | code) |
POSTs to the local daemon http://127.0.0.1:8787 (demo mode only) |
Terminal: what's live, what's priced, what's been said, how often before
| tool | what |
|---|---|
get_calendar(days=7) |
upcoming events with sources, markets, speaker_keys and rights |
get_market_context(ticker) |
one call per ticker: market + rules, current book, base rate for its speaker/phrase, the event, recent mentions |
get_base_rates(speaker?, phrase?, series?, window_days=365) |
how often that mention market settled YES: yes_rate, markets, avg_open_price, mispricing = avg(result − open), by_month |
search_outcomes(speaker?, phrase?, series?, venue?, since?, until?, limit, cursor?) |
the settled markets behind a base rate (venue settlement facts, paginated) |
search_mentions(speaker?, phrase?, since?, until?, limit) |
Langbot's own phrase_detected facts: phrase, speaker, event, t_spoken, lag_vs_public_ms — never transcript text |
list_speakers(q?) |
canonical speaker keys (powell, jensen-huang) with aliases and counts |
Each docstring says when an agent should reach for it. Rights (CONTRACTS §10): get_transcript returns
full text for public_domain / licensed sources and phrase facts only for restricted / unknown
ones; get_calendar and get_market_context carry rights so an agent knows in advance.
Resources: langbot://events/live, langbot://events/{id}/transcript, langbot://latency,
langbot://calendar, langbot://context/{ticker}, langbot://markets/{ticker}/brief, and the
two live (subscribable) ones below.
Live push
| resource | state |
|---|---|
langbot://events/{event_id}/hits |
every phrase_detected on the event, each with its §21 verdict (null when the feed has none), and a cursor |
langbot://markets/{ticker}/state |
said, counts (§21 reading; null = unclear), mention / needed / mention_text, last_hit, verdict |
How an agent subscribes depends on the MCP revision its client negotiated; the server serves both:
- 2025-11-25 and older:
resources/subscribe {uri}; on eachnotifications/resources/updatedfor the URI,resources/readit.resources/unsubscribe(or disconnecting) stops it. - 2026-07-28:
subscriptions/listenwithresource_subscriptions: [uri, …]; the same notification rides the listen stream (the SDK'sListenHandler), closing it unsubscribes. - neither:
watch_eventin a loop with the returnedcursor.
Upstream is one WS /v1/stream per token (stdio: one; hosted HTTP: one per tenant), filtered to
the subscribed events and types=phrase_detected, re-filtered with {"op":"subscribe"},
closed when nothing is subscribed, reconnected with jittered backoff (1 → 30 s) and backfilled
from the transcript after a reconnect. See live.py. Push over HTTP needs the default stateful
streamable HTTP (SSE responses, the GET stream); with stateless_http / json_response only
watch_event works.
Paying per call
Some feed endpoints are sold by the call (CONTRACTS §17): replay bundles ($0.50), history
($0.05), evidence packs ($0.25), provenance reports ($0.10), facts ($0.02) — initial list
prices. Tools that map to them carry _meta langbot/per_call_usd next to the plan fields,
so an agent can read the price before calling, and get_pricing passes through the feed's
per_call (always) and x402 ({enabled: false} or {enabled: true, x402_version, scheme, network, pay_to, asset, asset_decimals, facilitator, max_timeout_seconds, headers, …}) sections.
The MCP server holds no wallet. When the feed answers an x402 v2-shaped 402, the tool returns a structured error instead of a bare failure:
{"ok": false, "error": "payment_required", "status": 402, "price_usd": 0.5, "x402Version": 2,
"accepts": [{"scheme": "exact", "network": "eip155:8453", "amount": "500000", "asset": "0x…USDC", "payTo": "0x…", "maxTimeoutSeconds": 60, "extra": {"name": "USD Coin", "version": "2"}}],
"pricing_url": "https://langbot.ai/.well-known/langbot-pricing.json", "hint": "…"}
The agent can then pay with its own wallet through the SDK (LangbotClient(x402_wallet=…) in
langbot-sdk[x402], or @langbotai/sdk with x402Wallet), or ask the user for a plan token.
A 402 that is not x402-shaped (a plan gate) is reported as before.
Env
| var | default | |
|---|---|---|
LANGBOT_API_URL |
https://api.langbot.ai |
feed base URL (Dedicated VPC/on-prem deployments set their own) |
LANGBOT_API_TOKEN |
— | lb_… token, stdio mode only; public endpoints work without it |
LANGBOT_MCP_STRATEGY_TOOLS |
off | 1 exposes draft_strategy, backtest_strategy, run_paper |
ANTHROPIC_API_KEY |
— | enables draft_strategy via Claude |
LANGBOT_LLM_MODEL |
claude-opus-5-5 |
drafting model |
LANGBOT_LLM_EFFORT |
high |
output_config.effort for drafting (none to omit) |
LANGBOT_DAEMON_URL |
http://127.0.0.1:8787 |
local agent daemon |
LANGBOT_BACKTEST_FIXTURE |
— | default JSONL fixture for backtest_strategy |
LANGBOT_MCP_HOST/PORT/PATH |
0.0.0.0 / 8001 / /mcp |
HTTP mode |
Tokens in HTTP mode
--http is multi-tenant: every request must carry Authorization: Bearer lb_… and that token is used for the feed call; the server's LANGBOT_API_TOKEN is ignored. Tool calls and resource reads without a token are refused with a message pointing at https://langbot.ai/app/tokens (listing tools still works). The header is read with fastmcp.server.dependencies.get_http_headers(include={"authorization"}); see get_client() and TokenGate in server.py.
Compliance shape
The server emits facts (what was said, when) and runs nothing live. The strategy tools
are opt-in (LANGBOT_MCP_STRATEGY_TOOLS=1); when enabled, run_paper only
starts demo-mode strategies on the user's local daemon, and draft_strategy output is
reviewed by the user before langbot run. Live trading requires --mode live plus
LANGBOT_I_UNDERSTAND_LIVE=1 on the user's machine.
Develop
uv run --package langbot-mcp pytest services/mcp -q
docker build -f services/mcp/Dockerfile -t langbot-mcp . # from repo root
Registry metadata: server.json (MCP registry, mcp-publisher publish) and smithery.yaml.
License
MIT (LICENSE in this directory). langbot-mcp is published on PyPI; it is a thin client over the hosted Langbot feed, which is a proprietary service.
Metadata
Release files for langbot-mcp 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| langbot_mcp-0.1.0.tar.gz | 39.5 kB | Without provenance | Details for langbot_mcp-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| langbot_mcp-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for langbot_mcp-0.1.0-py3-none-any.whl |
Total release size: 82.1 kB
Release files / langbot_mcp-0.1.0.tar.gz
| Download URL | langbot_mcp-0.1.0.tar.gz |
|---|---|
| Size | 39.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
5ad4d7e2421e7132c289758bcb501943875af6710f242ce94e8c541829a61bee
|
|
BLAKE2b-256 checksum How to use checksums |
f6a4bd5554bb6e43f7968cd547016f2069b946f836194e3adc2890a26265939c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.13.0 {"installer":{"name":"uv","version":"0.13.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / langbot_mcp-0.1.0-py3-none-any.whl
| Download URL | langbot_mcp-0.1.0-py3-none-any.whl |
|---|---|
| Size | 42.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
865eb17dac60873d3407cc9de7d0308d7391e13fec65bb78db3e64ac69a45ab9
|
|
BLAKE2b-256 checksum How to use checksums |
d51de23522f2060b94f91c72dbc547c0110303d9ea8cf67d4cb596a677b11d35
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.13.0 {"installer":{"name":"uv","version":"0.13.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Security for langbot-mcp 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.