API & MCP
Personal access tokens for the HTTP API and MCP server. Read your sessions, opponents, and analytics; ask Play vs Agent for an action; enqueue postflop solves into the solution library. Studio is required for study data and the solver queue. Mint a key on API Keys.
Authentication
Send the key as a Bearer header. Tokens start with psk_ and authenticate as you — they can read your study data and enqueue solves.
Authorization: Bearer psk_YOUR_TOKEN
Component docs
Live previews on the component docs share one Studio key. The visitor enters it once, in a key bar or modal in the header. A key provider wraps the docs layout, a key-entry component in the header is the only place they type it, and every component page puts its preview in the same gated preview wrapper. The site keeps the key in sessionStorage for that tab, and leaves localStorage and cookies unused. The key is only sent to pokerstudy.ai. It is never logged. It is cleared when the tab closes. The full standard is on the API key page. The per-component docs that follow this standard start at /ui.
The site checks the key with GET /api/trainer/stats and Authorization: Bearer psk_…. 200 accepts the key. 401 leaves every preview on its sample, with an Enter your API key button. 503means the check could not run, so the sample stays up and the site tries again. The check reads the status and discards the body. That body is a small summary of the key owner's preflop drills.
In an app built from the registry, the key stays in POKERSTUDY_API_KEY on the server. The installed proxy, app/api/pokerstudy/[...path], is web/registry/pokerstudy/proxy-route.ts and attaches the key there. Keep the psk_ key out of client code.
Analytics
Shown-hand aggregates over your uploaded sessions. Same auth as the rest of the API. get_opponent_limp_range is also on MCP.
POST https://www.pokerstudy.ai/api/analytics/opponent-limp-range — first-in limp 169-grids from hole cards that went to showdown. Always pass position for a seat-specific range (SB limp ≠ EP limp). Response includes classesByPosition so mixed seats stay split. Optional opponent_id, session_id, table_size, game_type, since, until, limit (1–169, default 30).
curl https://www.pokerstudy.ai/api/analytics/opponent-limp-range \
-H "Authorization: Bearer psk_YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"position":["SB"],"table_size":6}'Sample is showdown-only — limps that folded before showdown are invisible. Do not treat the grid as a complete limp range.
Play vs Agent
POST https://www.pokerstudy.ai/api/play/decide— send a table snapshot, get the agent's next action. Requires a Studio personal access token: Authorization: Bearer psk_…. Requests with no token are rejected. Preflop solver ranges, isolation vs limps, Monte Carlo equity, then a made-hand heuristic. source on the response says which layer fired.
curl https://www.pokerstudy.ai/api/play/decide \
-H "Authorization: Bearer psk_…" \
-H "Content-Type: application/json" \
-d '{"hole":["Ah","Ad"],"board":[],"pot":30,"big_blind":20,"my_seat":4,"dealer_seat":1,"seats":[1,2,3,4,5,6],"valid_actions":[{"action":"fold"},{"action":"call","amount":20},{"action":"raise","min":40,"max":2000}]}'Cards are Ah / Kd. Include preflop_actions so the range walk can see the line.
Required: hole, my_seat, dealer_seat, seats, valid_actions (fold / check / call + amount / raise + min/max). Optional: board, pot, big_blind, in_hand, players, preflop_actions, postflop_actions. Response is { "action": "raise", "amount": 60, "source": "ranges" }. amount is set only on raise.
POST https://www.pokerstudy.ai/api/play/evaluate — same snapshot plus selected. Samples opponent hands, deals the rest of the board, and lets the agent play every remaining seat. selected.ev and bot.ev are the hero chip delta from those runouts. Fold is 0. ev_loss_bb is the big blinds that action gives up versus the bot, and grade is perfect, correct, inaccuracy, mistake, or blunder.
curl https://www.pokerstudy.ai/api/play/evaluate \
-H "Authorization: Bearer psk_…" \
-H "Content-Type: application/json" \
-d '{"hole":["Ah","Ad"],"board":[],"pot":30,"big_blind":20,"my_seat":4,"dealer_seat":1,"seats":[1,2,3,4,5,6],"valid_actions":[{"action":"fold"},{"action":"call","amount":20},{"action":"raise","min":40,"max":2000}],"selected":{"action":"call"}}'selected is { "action": "call" } or { "action": "raise", "amount": 60 }. Response includes equity, selected.ev, and bot (action, amount, ev, source), plus ev_loss_bb and grade. EV is chips; the loss is big blinds. Under 0.05 is correct, under 0.25 an inaccuracy, under 1 a mistake, and 1 or more a blunder. Zero is perfect.
Quickstart
curl https://www.pokerstudy.ai/api/solver/queue \
-H "Authorization: Bearer psk_YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"title":"KK7r SRP","board":"Kh Kd 7h","pot":5.5,"effective_stack":97.5}'Range lookups for offline solver packs live on the PokerData Ranges API. This token is for your study data and the solver queue.
Connect via MCP
Give Claude (or any MCP client) direct access to your study data. The server speaks the Model Context Protocol over a single HTTP endpoint and authenticates with a token from API Keys.
Server
https://www.pokerstudy.ai/api/mcp — Streamable HTTP, stateless. Auth: Authorization: Bearer psk_YOUR_TOKEN.
list_games— Preflop coverage: stack depths and positions for every game.list_spots— Every preflop decision node for a game and stack depth.get_node— Every action at a preflop node. sizeBb is big blinds, evs are small blinds relative to fold (omitted weight = 0). An nlmtt8 40bb Open is sizeBb 2.19. Optional hand, minFreq, and full.get_config— Table config in big blinds: seats, stacks, blinds, ante, openSizes, evUnit sb. nlmtt8 40bb open is 2.2x and the SB open is 2.8x. Example: game nlmtt8, stack 40.get_range— The preflop range for one action; add hand for that hand's frequency.list_postflop_packs— Prebuilt 6-max NLHE postflop packs and their flops, per bet-size tree (33% flop or 75% every street).get_postflop_node— One flop decision: actions, sizes, overall frequencies, and each hand class's mix and EV.get_postflop_range— The range a player takes one flop action with, e.g. the BB check-call range.list_my_sessions— Recent uploaded sessions — id, hero, dates, hands, net.get_session_summary— One session's headline numbers and HUD stats.get_hand_results— Cumulative bb won hand by hand, for one session or all of them.find_hands— Search your uploaded hands by game, position, line and grade.get_tournament_results— MTT results from imported tournament summaries: ROI, ITM, finishes.list_my_opponents— Villains across your sessions, with note counts.get_opponent_notes— Rolled-up notes for one opponent.get_opponent_limp_range— Shown first-in limp 169-grid. Pass position — SB limp ≠ EP limp.enqueue_solve— Queue a heads-up postflop solve; the dump lands in the solution library.get_queued_solve— Poll one queued solve by id — pending, running, done, or failed.list_queued_solves— This account's solver-queue jobs, newest first.list_library_solutions— Finished solves already in your solution library.
Claude Code (CLI)
claude mcp add --transport http poker-study https://www.pokerstudy.ai/api/mcp \ --header "Authorization: Bearer psk_YOUR_TOKEN"
Claude Desktop / claude.ai (custom connector)
Settings → Connectors → Add custom connector URL: https://www.pokerstudy.ai/api/mcp Header: Authorization: Bearer psk_YOUR_TOKEN
Generic MCP client config (Cursor, Windsurf, …)
{
"mcpServers": {
"poker-study": {
"url": "https://www.pokerstudy.ai/api/mcp",
"headers": {
"Authorization": "Bearer psk_YOUR_TOKEN"
}
}
}
}Smoke test (no client needed)
curl -s https://www.pokerstudy.ai/api/mcp \
-H "Authorization: Bearer psk_YOUR_TOKEN" \
-H "content-type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'