oddsrail 0.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,5 @@
1
+ .venv/
2
+ __pycache__/
3
+ *.pyc
4
+ .env
5
+ *.log
oddsrail-0.3.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 oddsrail
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,261 @@
1
+ Metadata-Version: 2.5
2
+ Name: oddsrail
3
+ Version: 0.3.0
4
+ Summary: MCP server giving AI trading agents access to prediction markets (Polymarket, Kalshi) with on-chain builder-code attribution and trading signals.
5
+ Project-URL: Homepage, https://github.com/hmesutozsoy/oddsrail
6
+ Project-URL: Repository, https://github.com/hmesutozsoy/oddsrail
7
+ Project-URL: Issues, https://github.com/hmesutozsoy/oddsrail/issues
8
+ Author: oddsrail
9
+ License: MIT License
10
+
11
+ Copyright (c) 2026 oddsrail
12
+
13
+ Permission is hereby granted, free of charge, to any person obtaining a copy
14
+ of this software and associated documentation files (the "Software"), to deal
15
+ in the Software without restriction, including without limitation the rights
16
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17
+ copies of the Software, and to permit persons to whom the Software is
18
+ furnished to do so, subject to the following conditions:
19
+
20
+ The above copyright notice and this permission notice shall be included in all
21
+ copies or substantial portions of the Software.
22
+
23
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29
+ SOFTWARE.
30
+ License-File: LICENSE
31
+ Keywords: ai-agents,kalshi,llm,mcp,model-context-protocol,polymarket,prediction-markets,trading
32
+ Classifier: Development Status :: 4 - Beta
33
+ Classifier: Intended Audience :: Developers
34
+ Classifier: Intended Audience :: Financial and Insurance Industry
35
+ Classifier: License :: OSI Approved :: MIT License
36
+ Classifier: Programming Language :: Python :: 3
37
+ Classifier: Programming Language :: Python :: 3.11
38
+ Classifier: Programming Language :: Python :: 3.12
39
+ Classifier: Topic :: Office/Business :: Financial :: Investment
40
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
41
+ Requires-Python: >=3.11
42
+ Requires-Dist: cryptography>=42.0
43
+ Requires-Dist: httpx>=0.28
44
+ Requires-Dist: mcp[cli]>=2.0.0
45
+ Requires-Dist: polymarket-client>=0.6.0
46
+ Description-Content-Type: text/markdown
47
+
48
+ # oddsrail
49
+
50
+ <!-- mcp-name: io.github.hmesutozsoy/oddsrail -->
51
+
52
+ **The rail AI agents use to trade prediction markets.**
53
+
54
+ An MCP server that gives any agent (Claude Code, Claude Desktop, or anything
55
+ MCP-compatible) prediction-market access across **Polymarket and Kalshi**:
56
+ market search, orderbooks, price history, positions, and order routing — with
57
+ **on-chain builder-code attribution** on Polymarket — plus two premium signal
58
+ tools (in-play overshoot/fade detection, resolution dispute-risk).
59
+
60
+ **Free to use, and free of fees.** oddsrail ships with a project builder code
61
+ registered at **0 bps**, so orders routed through it are attributed without
62
+ adding a single basis point to anyone's trade. The project's income is a share
63
+ of Polymarket's weekly builder reward pool — paid by Polymarket's own program,
64
+ not by you. Running your own builder profile instead is one environment
65
+ variable (`ODDSRAIL_BUILDER_CODE`), and `server_info` always tells you which
66
+ code is in use. No fee tiers, no paywalled tools, no account required.
67
+
68
+ ## Why this and not Parsec
69
+
70
+ The closest competitor (parsecapi.com) is a closed-source hosted service:
71
+ it stores your exchange keys (or holds a managed wallet that signs for you),
72
+ and its Builder Program keeps **55–85% of the fees builders collect**.
73
+ oddsrail is the opposite on every axis: **self-hosted, non-custodial (keys
74
+ never leave your machine), open source, and you keep 100% of your Polymarket
75
+ builder fees** because attribution uses Polymarket's native mechanism, not a
76
+ middleman escrow. Parsec also ships zero signal/analytics tools and nothing
77
+ on resolution risk — that's our paid layer.
78
+
79
+ ## Quickstart
80
+
81
+ Python 3.11+ required.
82
+
83
+ ```bash
84
+ pip install oddsrail
85
+ ```
86
+
87
+ ```bash
88
+ claude mcp add --transport stdio oddsrail -- oddsrail
89
+ ```
90
+
91
+ Or from a clone, without installing:
92
+
93
+ ```bash
94
+ python3 -m venv .venv && .venv/bin/pip install -r requirements.txt
95
+ ```
96
+
97
+ ```bash
98
+ claude mcp add --transport stdio oddsrail -- /abs/path/to/oddsrail/.venv/bin/python -m oddsrail.server
99
+ ```
100
+
101
+ Then ask the agent: *"search markets about the World Cup final and run the
102
+ overshoot signal on the favorite"*.
103
+
104
+ ## How attribution works (CLOB V2, verified Aug 2026)
105
+
106
+ 1. Get your **builder code** (a bytes32) at polymarket.com → **Settings →
107
+ Builders**. Set your fee rates there: taker up to 100 bps, maker up to
108
+ 50 bps — additive on top of platform fees, settled to your builder wallet.
109
+ 2. `export ODDSRAIL_BUILDER_CODE=0x...` where the server runs.
110
+ 3. Every order any agent routes through `place_order` has the code placed in
111
+ the V2 order struct's `builder` field **before signing** — attribution is
112
+ on-chain, visible in every `OrderFilled` event on CTF Exchange V2.
113
+ 4. Verify with the `builder_stats` tool (public builder-trades endpoint +
114
+ leaderboard).
115
+
116
+ If you skip this, orders carry the bundled oddsrail code at 0 bps — costing
117
+ you nothing and funding the project. If you set your own, yours wins; the
118
+ default is a default, not a lock-in.
119
+
120
+ ## Environment variables
121
+
122
+ | Variable | Default | Meaning |
123
+ |---|---|---|
124
+ | `ODDSRAIL_DRY_RUN` | `1` | `1` = orders are simulated and returned, never posted. Set `0` to trade. |
125
+ | `ODDSRAIL_BUILDER_CODE` | project default | Your bytes32 builder code. Overrides the bundled project default so attribution (and any reward-pool share) accrues to you instead. |
126
+ | `POLYMARKET_PRIVATE_KEY` | unset | Operator wallet key; required only for real trading. Never leaves this machine. |
127
+ | `POLYMARKET_WALLET_ADDRESS` | unset | Proxy/deposit wallet address, if the account uses one. |
128
+
129
+ ## Status — live-verified 2026-08-23
130
+
131
+ All 10 callable tools were driven end-to-end through a real MCP client
132
+ session against live Polymarket, from the Finland VPS (`/opt/oddsrail`).
133
+ Verified working: search, market lookup, orderbook (9/65 levels), price
134
+ history (361 pts), overshoot signal, dispute-risk, builder leaderboard,
135
+ dry-run order, open orders, server info.
136
+
137
+ Field mappings were corrected against the real API during that run — the
138
+ docs-guessed shapes were wrong in three places (`outcomes` is a dict keyed
139
+ `yes`/`no`, `search()` nests markets inside events, and book/volume/
140
+ resolution data live in `prices`/`metrics`/`state`/`resolution`
141
+ sub-objects).
142
+
143
+ ## ⚠️ Network note
144
+
145
+ Polymarket API domains are **blocked on Turkish networks (BTK)** — local
146
+ testing fails TLS with a block page. Run the server where Polymarket is
147
+ reachable (the Finland VPS at `/opt/oddsrail`, a VPN, or any unblocked
148
+ network). The signal logic and MCP layer are fully testable offline.
149
+
150
+ ## Kalshi (venue #2)
151
+
152
+ Kalshi is **bring-your-own-key and single-tenant by design**: the operator
153
+ supplies their own API key, trades their own account, and this server caches
154
+ nothing. That is deliberate — Kalshi's Developer Agreement limits API use to a
155
+ member's own trading (§3), bars facilitating other members' trading (§3.2) and
156
+ sublicensing the API (§3.7), and restricts storing/sharing API data (§3.1). A
157
+ hosted multi-tenant Kalshi service would not be compliant; a self-hosted one is.
158
+
159
+ **Attribution does not exist here.** Kalshi Builder Codes are a
160
+ Solana/DFlow/Jupiter integration — there is no builder or affiliate field
161
+ anywhere on the REST API, so Kalshi order flow cannot be attributed or
162
+ monetised the way Polymarket's can. Kalshi is in oddsrail for coverage and
163
+ signal reach, not for routing revenue.
164
+
165
+ Two shapes on this API are easy to get wrong, so oddsrail normalises both:
166
+
167
+ - **Prices are dollar strings, not cents** (`"0.5600"`), sizes are fixed-point
168
+ strings (`"10.00"`); the legacy integer-cent fields were removed in March
169
+ 2026. All arithmetic uses `Decimal`.
170
+ - **The orderbook is bids-only on both sides.** `yes_dollars` and `no_dollars`
171
+ are both bid ladders, ascending — so the best bid is the *last* element, and
172
+ a NO bid at $0.99 *is* a YES ask at $0.01. `kalshi_get_orderbook` returns a
173
+ conventional best-first bid/ask view of the YES book plus the raw ladders.
174
+
175
+ Order placement speaks natural terms — `outcome` (yes/no), `action`
176
+ (buy/sell), `price` = probability of that outcome — and translates to Kalshi's
177
+ YES-book `bid`/`ask` internally (buy NO @ 0.25 becomes ask @ 0.75). That
178
+ translation is unit-tested, since it is the obvious place to ship an
179
+ inverted-position bug.
180
+
181
+ Credentials: `KALSHI_KEY_ID` plus `KALSHI_PRIVATE_KEY_PATH` (PKCS#8 PEM) or
182
+ `KALSHI_PRIVATE_KEY`. Set `KALSHI_DEMO=1` to hit the demo environment. Read
183
+ tools need no key at all.
184
+
185
+ ## Tools (21)
186
+
187
+ - `search_markets`, `get_market`, `get_orderbook`, `price_history`,
188
+ `get_positions` — read-only, no keys
189
+ - `overshoot_signal` — premium: fresh panic-jump detection + this market's
190
+ historical reversion tendency (ported from the polymarket-wc analyzer)
191
+ - `dispute_risk` — premium: transparent 0–100 heuristic for contested
192
+ (UMA-dispute-prone) resolutions
193
+ - `place_order`, `cancel_order`, `open_orders` — trading, dry-run by default
194
+ - `builder_stats` — attribution verification + public builder leaderboard
195
+ - `server_info` — config status, per-venue
196
+
197
+ Kalshi: `kalshi_search_markets`, `kalshi_get_market`, `kalshi_get_orderbook`,
198
+ `kalshi_get_trades`, `kalshi_balance`, `kalshi_positions`,
199
+ `kalshi_open_orders`, `kalshi_place_order`, `kalshi_cancel_order`.
200
+
201
+ ## Stack notes
202
+
203
+ - Official unified SDK `polymarket-client` (0.6.x): `AsyncPublicClient` for
204
+ data, `AsyncSecureClient.place_limit_order(..., builder_code=...)` for
205
+ attributed orders. The legacy `py-clob-client` is archived and cannot
206
+ attach builder codes — do not use it.
207
+ - MCP SDK 2.0: `MCPServer` from `mcp.server.mcpserver` (the old
208
+ `mcp.server.fastmcp.FastMCP` import is gone in 2.x).
209
+ - Kalshi is on plain `httpx` + `cryptography`, not the official SDK:
210
+ `kalshi-python-sync` requires Python >=3.13 and re-releases weekly in
211
+ lockstep with the spec version. Auth is RSA-PSS(SHA256, salt=digest length)
212
+ over `str(unix_ms) + METHOD + path`, where the path includes `/trade-api/v2`
213
+ and excludes the query string. Base URL is now
214
+ `external-api.kalshi.com`.
215
+ - x402 (planned): the official `x402` PyPI package (v2.20+) can wrap MCP
216
+ tools directly (`x402.mcp`, payment rides in tool-call `_meta`), but its
217
+ MCP helpers currently target mcp 1.x — integrating means pinning
218
+ `mcp>=1.28,<2` or waiting for the 2.x-compatible release. Mainnet
219
+ settlement needs a facilitator (Coinbase CDP: 1,000 free settlements/mo,
220
+ then $0.001). Keep free tiers of both signals so registries can index the
221
+ server.
222
+
223
+ ## What the builder economy looks like (live, 2026-08-23)
224
+
225
+ Pulled from the public leaderboard via `builder_stats`:
226
+
227
+ | | weekly | all-time |
228
+ |---|---|---|
229
+ | #1 (betmoar) | $2.31M | $2.10B |
230
+ | median of top 25 | $127K | $88.2M |
231
+ | **entry to top 25** | **$42K** | $36.8M |
232
+
233
+ The instructive rows are the small-user ones: MagicMarkets routes $354K/week
234
+ with **1 active user**, Gate $1.11M/week with 2, PolymarketScan $277K with 3.
235
+ Those are bot operators routing their own flow — oddsrail's exact target
236
+ customer — and they show a single serious agent trader is worth real volume.
237
+ Wallets (MetaMask, 37K users) dominate on user count, not on volume per user.
238
+
239
+ ## Roadmap
240
+
241
+ 1. ~~Live smoke test from an unblocked network~~ — done 2026-08-23, all tools pass
242
+ 2. Register builder code (polymarket.com → Settings → Builders), set fees to
243
+ 0 bps at launch, export `ODDSRAIL_BUILDER_CODE`; first attributed order on
244
+ a tiny size
245
+ 3. ~~Kalshi as venue #2~~ — done 2026-08-23, 9 tools, verified live
246
+ 4. x402 paid wrapping for the two signals once the mcp-2.x conflict clears
247
+ 5. Registry listings: official MCP registry (`mcp-publisher`, PyPI
248
+ `mcp-name:` marker), Smithery (needs public streamable-HTTP + a free
249
+ tool for their scanner), Glama (`glama.json`)
250
+
251
+ ## Listing / distribution
252
+
253
+ - **GitHub**: https://github.com/hmesutozsoy/oddsrail (public, MIT)
254
+ - **Glama**: auto-crawls GitHub; `glama.json` in the repo root claims
255
+ maintainership.
256
+ - **Official MCP registry**: `server.json` is ready. Publishing needs the
257
+ package on PyPI first (the registry verifies ownership via an
258
+ `mcp-name: io.github.hmesutozsoy/oddsrail` marker in the PyPI README),
259
+ then `mcp-publisher login github && mcp-publisher publish`.
260
+ - **Smithery**: requires a public HTTPS streamable-HTTP endpoint — available
261
+ once oddsrail is hosted rather than run locally over stdio.
@@ -0,0 +1,214 @@
1
+ # oddsrail
2
+
3
+ <!-- mcp-name: io.github.hmesutozsoy/oddsrail -->
4
+
5
+ **The rail AI agents use to trade prediction markets.**
6
+
7
+ An MCP server that gives any agent (Claude Code, Claude Desktop, or anything
8
+ MCP-compatible) prediction-market access across **Polymarket and Kalshi**:
9
+ market search, orderbooks, price history, positions, and order routing — with
10
+ **on-chain builder-code attribution** on Polymarket — plus two premium signal
11
+ tools (in-play overshoot/fade detection, resolution dispute-risk).
12
+
13
+ **Free to use, and free of fees.** oddsrail ships with a project builder code
14
+ registered at **0 bps**, so orders routed through it are attributed without
15
+ adding a single basis point to anyone's trade. The project's income is a share
16
+ of Polymarket's weekly builder reward pool — paid by Polymarket's own program,
17
+ not by you. Running your own builder profile instead is one environment
18
+ variable (`ODDSRAIL_BUILDER_CODE`), and `server_info` always tells you which
19
+ code is in use. No fee tiers, no paywalled tools, no account required.
20
+
21
+ ## Why this and not Parsec
22
+
23
+ The closest competitor (parsecapi.com) is a closed-source hosted service:
24
+ it stores your exchange keys (or holds a managed wallet that signs for you),
25
+ and its Builder Program keeps **55–85% of the fees builders collect**.
26
+ oddsrail is the opposite on every axis: **self-hosted, non-custodial (keys
27
+ never leave your machine), open source, and you keep 100% of your Polymarket
28
+ builder fees** because attribution uses Polymarket's native mechanism, not a
29
+ middleman escrow. Parsec also ships zero signal/analytics tools and nothing
30
+ on resolution risk — that's our paid layer.
31
+
32
+ ## Quickstart
33
+
34
+ Python 3.11+ required.
35
+
36
+ ```bash
37
+ pip install oddsrail
38
+ ```
39
+
40
+ ```bash
41
+ claude mcp add --transport stdio oddsrail -- oddsrail
42
+ ```
43
+
44
+ Or from a clone, without installing:
45
+
46
+ ```bash
47
+ python3 -m venv .venv && .venv/bin/pip install -r requirements.txt
48
+ ```
49
+
50
+ ```bash
51
+ claude mcp add --transport stdio oddsrail -- /abs/path/to/oddsrail/.venv/bin/python -m oddsrail.server
52
+ ```
53
+
54
+ Then ask the agent: *"search markets about the World Cup final and run the
55
+ overshoot signal on the favorite"*.
56
+
57
+ ## How attribution works (CLOB V2, verified Aug 2026)
58
+
59
+ 1. Get your **builder code** (a bytes32) at polymarket.com → **Settings →
60
+ Builders**. Set your fee rates there: taker up to 100 bps, maker up to
61
+ 50 bps — additive on top of platform fees, settled to your builder wallet.
62
+ 2. `export ODDSRAIL_BUILDER_CODE=0x...` where the server runs.
63
+ 3. Every order any agent routes through `place_order` has the code placed in
64
+ the V2 order struct's `builder` field **before signing** — attribution is
65
+ on-chain, visible in every `OrderFilled` event on CTF Exchange V2.
66
+ 4. Verify with the `builder_stats` tool (public builder-trades endpoint +
67
+ leaderboard).
68
+
69
+ If you skip this, orders carry the bundled oddsrail code at 0 bps — costing
70
+ you nothing and funding the project. If you set your own, yours wins; the
71
+ default is a default, not a lock-in.
72
+
73
+ ## Environment variables
74
+
75
+ | Variable | Default | Meaning |
76
+ |---|---|---|
77
+ | `ODDSRAIL_DRY_RUN` | `1` | `1` = orders are simulated and returned, never posted. Set `0` to trade. |
78
+ | `ODDSRAIL_BUILDER_CODE` | project default | Your bytes32 builder code. Overrides the bundled project default so attribution (and any reward-pool share) accrues to you instead. |
79
+ | `POLYMARKET_PRIVATE_KEY` | unset | Operator wallet key; required only for real trading. Never leaves this machine. |
80
+ | `POLYMARKET_WALLET_ADDRESS` | unset | Proxy/deposit wallet address, if the account uses one. |
81
+
82
+ ## Status — live-verified 2026-08-23
83
+
84
+ All 10 callable tools were driven end-to-end through a real MCP client
85
+ session against live Polymarket, from the Finland VPS (`/opt/oddsrail`).
86
+ Verified working: search, market lookup, orderbook (9/65 levels), price
87
+ history (361 pts), overshoot signal, dispute-risk, builder leaderboard,
88
+ dry-run order, open orders, server info.
89
+
90
+ Field mappings were corrected against the real API during that run — the
91
+ docs-guessed shapes were wrong in three places (`outcomes` is a dict keyed
92
+ `yes`/`no`, `search()` nests markets inside events, and book/volume/
93
+ resolution data live in `prices`/`metrics`/`state`/`resolution`
94
+ sub-objects).
95
+
96
+ ## ⚠️ Network note
97
+
98
+ Polymarket API domains are **blocked on Turkish networks (BTK)** — local
99
+ testing fails TLS with a block page. Run the server where Polymarket is
100
+ reachable (the Finland VPS at `/opt/oddsrail`, a VPN, or any unblocked
101
+ network). The signal logic and MCP layer are fully testable offline.
102
+
103
+ ## Kalshi (venue #2)
104
+
105
+ Kalshi is **bring-your-own-key and single-tenant by design**: the operator
106
+ supplies their own API key, trades their own account, and this server caches
107
+ nothing. That is deliberate — Kalshi's Developer Agreement limits API use to a
108
+ member's own trading (§3), bars facilitating other members' trading (§3.2) and
109
+ sublicensing the API (§3.7), and restricts storing/sharing API data (§3.1). A
110
+ hosted multi-tenant Kalshi service would not be compliant; a self-hosted one is.
111
+
112
+ **Attribution does not exist here.** Kalshi Builder Codes are a
113
+ Solana/DFlow/Jupiter integration — there is no builder or affiliate field
114
+ anywhere on the REST API, so Kalshi order flow cannot be attributed or
115
+ monetised the way Polymarket's can. Kalshi is in oddsrail for coverage and
116
+ signal reach, not for routing revenue.
117
+
118
+ Two shapes on this API are easy to get wrong, so oddsrail normalises both:
119
+
120
+ - **Prices are dollar strings, not cents** (`"0.5600"`), sizes are fixed-point
121
+ strings (`"10.00"`); the legacy integer-cent fields were removed in March
122
+ 2026. All arithmetic uses `Decimal`.
123
+ - **The orderbook is bids-only on both sides.** `yes_dollars` and `no_dollars`
124
+ are both bid ladders, ascending — so the best bid is the *last* element, and
125
+ a NO bid at $0.99 *is* a YES ask at $0.01. `kalshi_get_orderbook` returns a
126
+ conventional best-first bid/ask view of the YES book plus the raw ladders.
127
+
128
+ Order placement speaks natural terms — `outcome` (yes/no), `action`
129
+ (buy/sell), `price` = probability of that outcome — and translates to Kalshi's
130
+ YES-book `bid`/`ask` internally (buy NO @ 0.25 becomes ask @ 0.75). That
131
+ translation is unit-tested, since it is the obvious place to ship an
132
+ inverted-position bug.
133
+
134
+ Credentials: `KALSHI_KEY_ID` plus `KALSHI_PRIVATE_KEY_PATH` (PKCS#8 PEM) or
135
+ `KALSHI_PRIVATE_KEY`. Set `KALSHI_DEMO=1` to hit the demo environment. Read
136
+ tools need no key at all.
137
+
138
+ ## Tools (21)
139
+
140
+ - `search_markets`, `get_market`, `get_orderbook`, `price_history`,
141
+ `get_positions` — read-only, no keys
142
+ - `overshoot_signal` — premium: fresh panic-jump detection + this market's
143
+ historical reversion tendency (ported from the polymarket-wc analyzer)
144
+ - `dispute_risk` — premium: transparent 0–100 heuristic for contested
145
+ (UMA-dispute-prone) resolutions
146
+ - `place_order`, `cancel_order`, `open_orders` — trading, dry-run by default
147
+ - `builder_stats` — attribution verification + public builder leaderboard
148
+ - `server_info` — config status, per-venue
149
+
150
+ Kalshi: `kalshi_search_markets`, `kalshi_get_market`, `kalshi_get_orderbook`,
151
+ `kalshi_get_trades`, `kalshi_balance`, `kalshi_positions`,
152
+ `kalshi_open_orders`, `kalshi_place_order`, `kalshi_cancel_order`.
153
+
154
+ ## Stack notes
155
+
156
+ - Official unified SDK `polymarket-client` (0.6.x): `AsyncPublicClient` for
157
+ data, `AsyncSecureClient.place_limit_order(..., builder_code=...)` for
158
+ attributed orders. The legacy `py-clob-client` is archived and cannot
159
+ attach builder codes — do not use it.
160
+ - MCP SDK 2.0: `MCPServer` from `mcp.server.mcpserver` (the old
161
+ `mcp.server.fastmcp.FastMCP` import is gone in 2.x).
162
+ - Kalshi is on plain `httpx` + `cryptography`, not the official SDK:
163
+ `kalshi-python-sync` requires Python >=3.13 and re-releases weekly in
164
+ lockstep with the spec version. Auth is RSA-PSS(SHA256, salt=digest length)
165
+ over `str(unix_ms) + METHOD + path`, where the path includes `/trade-api/v2`
166
+ and excludes the query string. Base URL is now
167
+ `external-api.kalshi.com`.
168
+ - x402 (planned): the official `x402` PyPI package (v2.20+) can wrap MCP
169
+ tools directly (`x402.mcp`, payment rides in tool-call `_meta`), but its
170
+ MCP helpers currently target mcp 1.x — integrating means pinning
171
+ `mcp>=1.28,<2` or waiting for the 2.x-compatible release. Mainnet
172
+ settlement needs a facilitator (Coinbase CDP: 1,000 free settlements/mo,
173
+ then $0.001). Keep free tiers of both signals so registries can index the
174
+ server.
175
+
176
+ ## What the builder economy looks like (live, 2026-08-23)
177
+
178
+ Pulled from the public leaderboard via `builder_stats`:
179
+
180
+ | | weekly | all-time |
181
+ |---|---|---|
182
+ | #1 (betmoar) | $2.31M | $2.10B |
183
+ | median of top 25 | $127K | $88.2M |
184
+ | **entry to top 25** | **$42K** | $36.8M |
185
+
186
+ The instructive rows are the small-user ones: MagicMarkets routes $354K/week
187
+ with **1 active user**, Gate $1.11M/week with 2, PolymarketScan $277K with 3.
188
+ Those are bot operators routing their own flow — oddsrail's exact target
189
+ customer — and they show a single serious agent trader is worth real volume.
190
+ Wallets (MetaMask, 37K users) dominate on user count, not on volume per user.
191
+
192
+ ## Roadmap
193
+
194
+ 1. ~~Live smoke test from an unblocked network~~ — done 2026-08-23, all tools pass
195
+ 2. Register builder code (polymarket.com → Settings → Builders), set fees to
196
+ 0 bps at launch, export `ODDSRAIL_BUILDER_CODE`; first attributed order on
197
+ a tiny size
198
+ 3. ~~Kalshi as venue #2~~ — done 2026-08-23, 9 tools, verified live
199
+ 4. x402 paid wrapping for the two signals once the mcp-2.x conflict clears
200
+ 5. Registry listings: official MCP registry (`mcp-publisher`, PyPI
201
+ `mcp-name:` marker), Smithery (needs public streamable-HTTP + a free
202
+ tool for their scanner), Glama (`glama.json`)
203
+
204
+ ## Listing / distribution
205
+
206
+ - **GitHub**: https://github.com/hmesutozsoy/oddsrail (public, MIT)
207
+ - **Glama**: auto-crawls GitHub; `glama.json` in the repo root claims
208
+ maintainership.
209
+ - **Official MCP registry**: `server.json` is ready. Publishing needs the
210
+ package on PyPI first (the registry verifies ownership via an
211
+ `mcp-name: io.github.hmesutozsoy/oddsrail` marker in the PyPI README),
212
+ then `mcp-publisher login github && mcp-publisher publish`.
213
+ - **Smithery**: requires a public HTTPS streamable-HTTP endpoint — available
214
+ once oddsrail is hosted rather than run locally over stdio.
@@ -0,0 +1,54 @@
1
+ # oddsrail
2
+
3
+ > An MCP server that gives AI trading agents access to prediction markets
4
+ > across Polymarket and Kalshi, with on-chain builder-code attribution on
5
+ > routed Polymarket orders and premium signal tools.
6
+
7
+ Self-hosted and non-custodial: the operator runs the server themselves and
8
+ private keys never leave their machine. Orders are dry-run by default.
9
+
10
+ ## What an agent can do with it
11
+
12
+ - `search_markets(query, limit)` — find markets by text; returns token ids,
13
+ best bid/ask, spread, 24h volume, liquidity, end date, resolution status
14
+ - `get_market(id_or_slug)` — one market's details
15
+ - `get_orderbook(token_id)` — live bids/asks
16
+ - `price_history(token_id, hours, fidelity_minutes)` — recent price series
17
+ - `get_positions(address)` — a wallet's current positions
18
+ - `overshoot_signal(token_id, hours, threshold)` — detects fresh price jumps
19
+ (panic moves) and reports whether a fade setup is active, plus that
20
+ market's historical reversion tendency
21
+ - `dispute_risk(id_or_slug)` — 0-100 score for how likely a market's
22
+ resolution gets contested (UMA dispute risk), with transparent reasons
23
+ - `place_order(token_id, side, price, size)` — limit order; price is an
24
+ implied probability in (0,1); dry-run unless the operator enables trading
25
+ - `cancel_order(order_id)`, `open_orders()`
26
+ - `builder_stats(time_period)` — public builder leaderboard and this
27
+ operator's attributed trades
28
+
29
+ ## Kalshi tools
30
+
31
+ - `kalshi_search_markets(query, limit, min_volume)`, `kalshi_get_market(ticker)`,
32
+ `kalshi_get_orderbook(ticker, depth)`, `kalshi_get_trades(ticker, limit)`
33
+ - `kalshi_balance()`, `kalshi_positions()`, `kalshi_open_orders()`
34
+ - `kalshi_place_order(ticker, outcome, action, price, count)` — outcome yes|no,
35
+ action buy|sell, price is the probability of THAT outcome in (0,1)
36
+ - `kalshi_cancel_order(order_id)`
37
+
38
+ Kalshi notes: prices are dollar strings not cents; the raw orderbook is
39
+ bids-only on both sides (a NO bid at 0.99 is a YES ask at 0.01) but
40
+ `kalshi_get_orderbook` returns a normal best-first bid/ask view. Kalshi needs
41
+ the operator's own API key for private endpoints; read tools do not.
42
+
43
+ ## Install
44
+
45
+ python3 -m venv .venv && .venv/bin/pip install -r requirements.txt
46
+ claude mcp add --transport stdio oddsrail -- /abs/path/oddsrail/.venv/bin/python -m oddsrail.server
47
+
48
+ ## Notes for agents
49
+
50
+ - Prices are implied probabilities in (0,1), not cents.
51
+ - `place_order` returns `{"dry_run": true, ...}` unless the operator has set
52
+ ODDSRAIL_DRY_RUN=0 — check this before assuming an order was placed.
53
+ - Polymarket API domains are blocked on some networks (e.g. Turkey); run the
54
+ server where they resolve.
File without changes