pokerdata-mcp 0.0.0-stage → 1.0.1
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.
- package/LICENSE +25 -0
- package/README.md +139 -2
- package/bin/pokerdata-mcp.js +76 -0
- package/package.json +35 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 HFT Studio LLC
|
|
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.
|
|
22
|
+
|
|
23
|
+
This licence covers the code in this repository. The sample data in
|
|
24
|
+
samples/ is solver output from pokerdata.io, provided for evaluation under the
|
|
25
|
+
terms at https://pokerdata.io/terms.
|
package/README.md
CHANGED
|
@@ -1,3 +1,140 @@
|
|
|
1
|
-
#
|
|
1
|
+
# PokerData MCP: GTO poker solver data for AI agents
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[PokerData](https://pokerdata.io) serves GTO solver strategy for no-limit
|
|
4
|
+
hold'em and pot-limit Omaha as JSON, over an MCP server and a REST API.
|
|
5
|
+
Point Claude, Cursor or any MCP client at it and ask "what does UTG open at
|
|
6
|
+
100bb?" or "how does the BB defend vs a BTN open?" and the agent gets the
|
|
7
|
+
solver's real frequencies and EVs, not a guess.
|
|
8
|
+
|
|
9
|
+
- **Endpoint:** `https://pokerdata.io/api/mcp` (Streamable HTTP, stateless)
|
|
10
|
+
- **Free without a key:** the tool list and every 6-max NL cash preflop tool,
|
|
11
|
+
all 8 stack depths
|
|
12
|
+
- **Everything else:** a `pdk_` key from [pokerdata.io/app/api](https://pokerdata.io/app/api).
|
|
13
|
+
A free trial key (100 calls, no card) unlocks every data tool.
|
|
14
|
+
|
|
15
|
+
This repository holds setup instructions, a small stdio bridge for clients
|
|
16
|
+
that only speak stdio, examples and sample data. The data and the server are
|
|
17
|
+
hosted at pokerdata.io.
|
|
18
|
+
|
|
19
|
+
## What's covered
|
|
20
|
+
|
|
21
|
+
| Game | Format | Stacks | Data |
|
|
22
|
+
|---|---|---|---|
|
|
23
|
+
| No-limit hold'em 6-max (`nl`) | Cash, 5% rake, 0.5bb cap | 20, 30, 40, 50, 70, 100, 150, 200bb | Every preflop decision node, frequency and EV per hand class (169) |
|
|
24
|
+
| NLHE tournament 8-max (`nlmtt8`) | Chip EV, 1bb BB ante | 10 to 300bb | Preflop |
|
|
25
|
+
| NLHE tournament 8-max, classic ante (`nlh8-hydra`) | Chip EV, 0.1bb ante | 10, 20, 30, 60bb | Preflop |
|
|
26
|
+
| Pot-limit Omaha 6-max (`plo`) | Cash | 12 to 200bb | Preflop, suit-grouped classes |
|
|
27
|
+
| PLO 9-max (`plo9`) | Cash | 60, 100bb | Preflop |
|
|
28
|
+
| PLO5 6-max (`plo5`) | Cash, 1.2bb ante | 100bb | Preflop and postflop |
|
|
29
|
+
| NLHE heads-up postflop | Single-raised, 3-bet and 4-bet pots | 100bb | Solved flops with turns and rivers, per-combo strategy and EV, two bet-size trees |
|
|
30
|
+
|
|
31
|
+
`list_games` and `list_postflop_packs` return the live coverage, so an agent
|
|
32
|
+
never has to trust this table. Not covered: ICM, PKO, multiway postflop,
|
|
33
|
+
tournament postflop. Those requests come back as explicit "unsupported"
|
|
34
|
+
rather than a cash-game stand-in.
|
|
35
|
+
|
|
36
|
+
## Set it up
|
|
37
|
+
|
|
38
|
+
### Claude Code
|
|
39
|
+
|
|
40
|
+
```sh
|
|
41
|
+
# No key: 6-max NL cash preflop
|
|
42
|
+
claude mcp add --transport http pokerdata https://pokerdata.io/api/mcp
|
|
43
|
+
|
|
44
|
+
# With a key: every game and postflop
|
|
45
|
+
claude mcp add --transport http pokerdata https://pokerdata.io/api/mcp \
|
|
46
|
+
--header "Authorization: Bearer pdk_YOUR_KEY"
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Cursor (`~/.cursor/mcp.json`)
|
|
50
|
+
|
|
51
|
+
```json
|
|
52
|
+
{
|
|
53
|
+
"mcpServers": {
|
|
54
|
+
"pokerdata": {
|
|
55
|
+
"url": "https://pokerdata.io/api/mcp",
|
|
56
|
+
"headers": { "Authorization": "Bearer pdk_YOUR_KEY" }
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Claude Desktop and other stdio clients
|
|
63
|
+
|
|
64
|
+
```json
|
|
65
|
+
{
|
|
66
|
+
"mcpServers": {
|
|
67
|
+
"pokerdata": {
|
|
68
|
+
"command": "npx",
|
|
69
|
+
"args": ["-y", "pokerdata-mcp"],
|
|
70
|
+
"env": { "POKERDATA_API_KEY": "pdk_YOUR_KEY" }
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Leave out `env` to use the free tools only. The bridge in
|
|
77
|
+
[`bin/pokerdata-mcp.js`](bin/pokerdata-mcp.js) has no dependencies and only
|
|
78
|
+
forwards JSON-RPC to the hosted endpoint. Claude Desktop can also add
|
|
79
|
+
`https://pokerdata.io/api/mcp` directly as a custom connector.
|
|
80
|
+
|
|
81
|
+
### Plain HTTP
|
|
82
|
+
|
|
83
|
+
```sh
|
|
84
|
+
curl -s https://pokerdata.io/api/mcp -H 'Content-Type: application/json' \
|
|
85
|
+
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"get_node","arguments":{"game":"nl","stack":100,"history":"UTG"}}}'
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
More in [`examples/`](examples/): curl, Python, and the REST API.
|
|
89
|
+
|
|
90
|
+
## Tools
|
|
91
|
+
|
|
92
|
+
| Group | Tools | Key |
|
|
93
|
+
|---|---|---|
|
|
94
|
+
| Coverage and docs | `list_games`, `list_postflop_packs`, `list_datasets`, `get_tree_docs`, `get_exploitability` | Not needed |
|
|
95
|
+
| Preflop | `get_range`, `get_node`, `list_spots`, `get_config`, `get_range_metadata` | Not needed for `game: "nl"`; needed for every other game |
|
|
96
|
+
| Postflop | `get_postflop_node`, `get_postflop_range` | Needed |
|
|
97
|
+
| Coaching | `explain_combo`, `get_board_report`, `compare_strategies` | Needed |
|
|
98
|
+
| Your hands | hand, session and opponent tools, hand upload | Any key, free trial included; never counts against your allowance |
|
|
99
|
+
| Solve queue | `enqueue_solve`, `get_queued_solve`, `list_queued_solves`, `list_library_solutions` | Needed |
|
|
100
|
+
|
|
101
|
+
Preflop spots are action paths such as `UTG_60%_HJ_Call` (NLHE) or
|
|
102
|
+
`UTG_Open_HJ_3B` (PLO). EVs are in small blinds. Responses are compact by
|
|
103
|
+
default; pass `detail: "full"` for complete maps. Full contract:
|
|
104
|
+
[docs.pokerdata.io/ranges](https://docs.pokerdata.io/ranges).
|
|
105
|
+
|
|
106
|
+
## Plans
|
|
107
|
+
|
|
108
|
+
| Plan | Price | What you get |
|
|
109
|
+
|---|---|---|
|
|
110
|
+
| No key | Free | Tool list, coverage tools, 6-max NL cash preflop at every stack. 200 tool calls a day per IP |
|
|
111
|
+
| Starter | Free key, no card | Every data tool, 100 calls (or 50 MB) lifetime. Personal use |
|
|
112
|
+
| Pro | $100/month | Every game and all postflop, 250,000 calls or 5 GB a month. Personal use |
|
|
113
|
+
| Enterprise | $250/month | Everything in Pro, **commercial use allowed**, 5 million calls or 100 GB a month, higher rate limit |
|
|
114
|
+
| Custom | [Contact us](https://pokerdata.io/support) | Redistribution, bulk export, licences for model training, SLAs |
|
|
115
|
+
|
|
116
|
+
REST and MCP share one meter. Keys and plans: [pokerdata.io/app/api](https://pokerdata.io/app/api).
|
|
117
|
+
|
|
118
|
+
## Sample data
|
|
119
|
+
|
|
120
|
+
[`samples/`](samples/) has two real responses, so you can check the format
|
|
121
|
+
before connecting anything:
|
|
122
|
+
|
|
123
|
+
- `nl-6max-100bb-utg-first-in.json`: UTG's first decision at 100bb, every
|
|
124
|
+
action with per-hand frequency and EV.
|
|
125
|
+
- `nl-6max-100bb-utg-open-range.json`: UTG's opening range at 100bb.
|
|
126
|
+
|
|
127
|
+
## How the solves were made
|
|
128
|
+
|
|
129
|
+
Preflop cash trees are MonkerSolver solutions. The tournament and postflop
|
|
130
|
+
solves come from our own engine, validated against MonkerSolver as described
|
|
131
|
+
at [pokerdata.io/methodology](https://pokerdata.io/methodology). Postflop
|
|
132
|
+
exploitability is published per board (`list_postflop_packs` with a `pack`).
|
|
133
|
+
|
|
134
|
+
## Related
|
|
135
|
+
|
|
136
|
+
- [pokerdata.io](https://pokerdata.io): download the raw solver packs, browse ranges free
|
|
137
|
+
- [Poker Study AI](https://www.pokerstudy.ai): an AI coach that reviews your hands against the same solves
|
|
138
|
+
|
|
139
|
+
Code in this repository is MIT licensed. Sample data is provided for
|
|
140
|
+
evaluation under the [pokerdata.io terms](https://pokerdata.io/terms).
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// stdio bridge to the hosted PokerData MCP server.
|
|
3
|
+
//
|
|
4
|
+
// Reads newline-delimited JSON-RPC from stdin, POSTs each message to
|
|
5
|
+
// https://pokerdata.io/api/mcp and writes the reply to stdout. The server
|
|
6
|
+
// does all the work; this file only exists for MCP clients that speak stdio.
|
|
7
|
+
//
|
|
8
|
+
// POKERDATA_API_KEY optional pdk_ key. Without it, the tool list and the
|
|
9
|
+
// free 6-max NL cash preflop tools still work.
|
|
10
|
+
// POKERDATA_MCP_URL optional override of the endpoint.
|
|
11
|
+
|
|
12
|
+
"use strict";
|
|
13
|
+
|
|
14
|
+
const readline = require("node:readline");
|
|
15
|
+
|
|
16
|
+
const URL_ = process.env.POKERDATA_MCP_URL || "https://pokerdata.io/api/mcp";
|
|
17
|
+
const KEY = (process.env.POKERDATA_API_KEY || "").trim();
|
|
18
|
+
const VERSION = require("../package.json").version;
|
|
19
|
+
|
|
20
|
+
const headers = {
|
|
21
|
+
"Content-Type": "application/json",
|
|
22
|
+
Accept: "application/json, text/event-stream",
|
|
23
|
+
"User-Agent": `pokerdata-mcp/${VERSION}`,
|
|
24
|
+
};
|
|
25
|
+
if (KEY) headers.Authorization = `Bearer ${KEY}`;
|
|
26
|
+
|
|
27
|
+
function write(obj) {
|
|
28
|
+
process.stdout.write(JSON.stringify(obj) + "\n");
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function errorReply(msg, code, message) {
|
|
32
|
+
if (!msg || msg.id === undefined || msg.id === null) return;
|
|
33
|
+
write({ jsonrpc: "2.0", id: msg.id, error: { code, message } });
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async function forward(line) {
|
|
37
|
+
let msg;
|
|
38
|
+
try {
|
|
39
|
+
msg = JSON.parse(line);
|
|
40
|
+
} catch {
|
|
41
|
+
write({ jsonrpc: "2.0", id: null, error: { code: -32700, message: "Parse error" } });
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
let res;
|
|
45
|
+
try {
|
|
46
|
+
res = await fetch(URL_, { method: "POST", headers, body: line });
|
|
47
|
+
} catch (err) {
|
|
48
|
+
errorReply(msg, -32000, `Could not reach ${URL_}: ${err.message}`);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
if (res.status === 202) return; // notifications get no reply
|
|
52
|
+
const text = await res.text();
|
|
53
|
+
let body;
|
|
54
|
+
try {
|
|
55
|
+
body = JSON.parse(text);
|
|
56
|
+
} catch {
|
|
57
|
+
errorReply(msg, -32000, `Unexpected ${res.status} response from ${URL_}`);
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
// Errors raised before the server read the message carry id null; give
|
|
61
|
+
// them back the caller's id so the client can match the reply.
|
|
62
|
+
if (!Array.isArray(body) && body && body.id === null && msg.id !== undefined) {
|
|
63
|
+
body.id = msg.id;
|
|
64
|
+
}
|
|
65
|
+
write(body);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const rl = readline.createInterface({ input: process.stdin });
|
|
69
|
+
let queue = Promise.resolve();
|
|
70
|
+
rl.on("line", (line) => {
|
|
71
|
+
if (!line.trim()) return;
|
|
72
|
+
queue = queue.then(() => forward(line));
|
|
73
|
+
});
|
|
74
|
+
rl.on("close", () => {
|
|
75
|
+
queue.then(() => process.exit(0));
|
|
76
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,37 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pokerdata-mcp",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "MCP server for GTO poker solver data: preflop ranges and postflop strategy for no-limit hold'em and pot-limit Omaha, from pokerdata.io.",
|
|
5
|
+
"mcpName": "io.github.hft-studio/pokerdata",
|
|
6
|
+
"bin": {
|
|
7
|
+
"pokerdata-mcp": "bin/pokerdata-mcp.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"bin",
|
|
11
|
+
"README.md",
|
|
12
|
+
"LICENSE"
|
|
13
|
+
],
|
|
14
|
+
"engines": {
|
|
15
|
+
"node": ">=18"
|
|
16
|
+
},
|
|
17
|
+
"keywords": [
|
|
18
|
+
"mcp",
|
|
19
|
+
"model-context-protocol",
|
|
20
|
+
"poker",
|
|
21
|
+
"gto",
|
|
22
|
+
"solver",
|
|
23
|
+
"poker-ranges",
|
|
24
|
+
"preflop",
|
|
25
|
+
"postflop",
|
|
26
|
+
"nlhe",
|
|
27
|
+
"plo",
|
|
28
|
+
"poker-api"
|
|
29
|
+
],
|
|
30
|
+
"homepage": "https://pokerdata.io/api",
|
|
31
|
+
"repository": {
|
|
32
|
+
"type": "git",
|
|
33
|
+
"url": "git+https://github.com/hft-studio/pokerdata-mcp.git"
|
|
34
|
+
},
|
|
35
|
+
"license": "MIT",
|
|
36
|
+
"author": "HFT Studio LLC"
|
|
37
|
+
}
|