DEVELOPERS / MCP
Every public tool the HNW MCP server exposes. Admin-only tools are filtered out of this list.
POST JSON-RPC 2.0 to https://highestnumberwins.com/api/mcp. No API key required at the anonymous tier; rate limit is 120/hour, 1000/day per IP.
MCP is agent-facing: no CAPTCHA is required on this path.
tools/list to see the tools and their input schemas.tools/call to call list_public_games with no arguments.live and soon lists. You can also browse them in the public games directory.create_gameCreate a new Highest Number Wins settle game. Settle is the classic multiplayer mode: each player locks one number, highest wins. Returns a game_id and a join_url.
{
"properties": {
"best_of": {
"description": "Rounds in a best-of series. Defaults to one.",
"enum": [
1,
3,
5,
7
],
"type": "number"
},
"flash_speed": {
"description": "Reel flash presentation speed.",
"enum": [
"slow",
"normal",
"fast",
"blur"
],
"type": "string"
},
"num_digits": {
"description": "Digits per locked number (6, 8, 10, or 12). Default 10.",
"enum": [
6,
8,
10,
12
],
"type": "number"
},
"participants": {
"description": "Same device needs at least two players. Shared link can start with one host. Free accounts support up to 10, Creator accounts up to 100.",
"items": {
"properties": {
"display_name": {
"maxLength": 32,
"minLength": 1,
"type": "string"
}
},
"required": [
"display_name"
],
"type": "object"
},
"maxItems": 100,
"minItems": 1,
"type": "array"
},
"play_on": {
"description": "\"same_device\" (pass phone around) or \"shared_link\" (each joins via URL)",
"enum": [
"same_device",
"shared_link"
],
"type": "string"
},
"round_seconds": {
"description": "Round duration in seconds (3, 5, 10, or 15).",
"enum": [
3,
5,
10,
15
],
"type": "number"
},
"sealed_reel": {
"description": "Optional, default false. Seals the reel: the numbers still to come stay hidden from every player until the last lock is in, so nobody, not even a scripted client, can read the reel and stop on a high number. Each player still sees their own number when they stop; until then the reel spins stand-in numbers. Leave it off for everyday play (watching the real numbers spin is part of the fun); turn it on when the user says the result really matters or asks for the strictest fairness. Afterwards verify_round checks the seed against the seal shown before the first stop.",
"type": "boolean"
},
"win_condition": {
"description": "\"highest\" (default) or \"lowest\".",
"enum": [
"highest",
"lowest"
],
"type": "string"
}
},
"required": [
"play_on",
"participants"
],
"type": "object"
}join_gameJoin an existing HNW game as a new player. Returns the new player's id, seat, color_slot, and a player_token. The token is required to authenticate subsequent actions in that game (WebSocket, locks, etc.).
{
"properties": {
"display_name": {
"description": "The name this player will appear as in the roster.",
"maxLength": 32,
"minLength": 1,
"type": "string"
},
"game_id": {
"description": "UUID of the game to join.",
"type": "string"
}
},
"required": [
"game_id",
"display_name"
],
"type": "object"
}start_gameStart the next round for a game. Only the host (seat 0) can call this. Returns the new round_id. After this, clients go through commit → reveal → lock to place their numbers.
{
"properties": {
"game_id": {
"description": "UUID of the game.",
"type": "string"
},
"host_token": {
"description": "Hex-encoded host player token (seat 0).",
"type": "string"
}
},
"required": [
"game_id",
"host_token"
],
"type": "object"
}lock_numberLock a number for a player in an HNW round. Settle rounds lock once; option_pick rounds lock once per candidate (the tool skips commit+reveal on repeat calls). Returns the server-resolved locked_number; the tool never produces the number itself, and it cannot choose when the reel stops: the server assigns each seat or option its own frame of the committed random reel, fixed before the numbers are known. If other players must commit or reveal, returns waiting_for_players immediately. Advance the others then call again; retries preserve the lock, even after a restart.
{
"properties": {
"candidate_id": {
"description": "Required for option_pick games; omit for settle.",
"type": "string"
},
"player_token": {
"description": "Player token returned by create or join (hex or base64).",
"type": "string"
},
"round_id": {
"description": "UUID of the round (returned by start_game).",
"type": "string"
}
},
"required": [
"round_id",
"player_token"
],
"type": "object"
}get_game_stateRead a game's mode, roster, house rules and labeled candidate IDs. An active classic round includes round_id and round_phase. For an invite-only game use the admitted account.
{
"properties": {
"game_id": {
"type": "string"
},
"player_token": {
"description": "Optional private player token for an admitted player.",
"type": "string"
}
},
"required": [
"game_id"
],
"type": "object"
}finish_solo_decisionFinish an existing one-person same-device Option Pick when asked to choose. Starts or resumes its round, applies fair automatic locks to the original options, and returns the official winner_candidate, ranking and round_id. Retry this same game to recover the same winner. Use verify_round for its seed or share_result when asked for a public link.
{
"properties": {
"game_id": {
"type": "string"
},
"player_token": {
"description": "The private seeded_players[0].token from create_solo_decision.",
"type": "string"
}
},
"required": [
"game_id",
"player_token"
],
"type": "object"
}get_audience_resultRead the official winner and final standings of a Creator audience game or shared-link scale draw. Returns status=pending until the draw closes. A closed draw with zero entrants has no winner. Share the returned share_url. For another page, repeat with next_offset. Find a forgotten Creator game ID with list_hosted_games.
{
"properties": {
"game_id": {
"description": "Game ID from host_public_game, list_hosted_games, or the game link.",
"type": "string"
},
"limit": {
"default": 10,
"maximum": 100,
"minimum": 1,
"multipleOf": 1,
"type": "number"
},
"offset": {
"default": 0,
"maximum": 2147483647,
"minimum": 0,
"multipleOf": 1,
"type": "number"
}
},
"required": [
"game_id"
],
"type": "object"
}share_resultWhen asked to share, publish an immutable snapshot of one resolved classic Settle or Option Pick round. Anyone with the link can view it. The winning option label is public. Participant names and other option labels are redacted by default. Returns a public page URL and PNG. For a Creator or scale draw use get_audience_result.
{
"properties": {
"caption": {
"description": "Optional public caption, up to 80 characters.",
"maxLength": 80,
"type": "string"
},
"game_id": {
"type": "string"
},
"include_names": {
"description": "Set true only when the user explicitly asks to publish player names or all option labels.",
"type": "boolean"
},
"player_token": {
"description": "Your own participant token from game creation or join. Optional for a connected account admitted to this game. Never include it in the shared message.",
"type": "string"
},
"round_id": {
"description": "The exact resolved round ID returned by start_game or get_result.",
"type": "string"
}
},
"required": [
"game_id",
"round_id"
],
"type": "object"
}get_resultReturn the winner, final leaderboard, and verification bundle summary for a game's most recently resolved round. Returns an error if the game has no resolved round yet.
{
"properties": {
"game_id": {
"description": "UUID of the game.",
"type": "string"
},
"round_id": {
"description": "Optional exact resolved round UUID. Use this to keep shared results immutable across rematches.",
"type": "string"
}
},
"required": [
"game_id"
],
"type": "object"
}create_solo_decisionSet up one person's decision with 2–20 labeled options. To choose now, pass game_id and seeded_players[0].token to finish_solo_decision. For the person to play instead, give them join_url privately: it reserves their seat for one browser for 15 minutes. Never include player tokens in links or messages. Use share_result for a public outcome.
{
"properties": {
"candidates": {
"description": "Between 2 and 20 options to pick from.",
"items": {
"properties": {
"detail": {
"description": "Optional one-line secondary text (price, description).",
"maxLength": 160,
"type": "string"
},
"label": {
"maxLength": 80,
"minLength": 1,
"type": "string"
}
},
"required": [
"label"
],
"type": "object"
},
"maxItems": 20,
"minItems": 2,
"type": "array"
},
"decider_name": {
"description": "Name of the single decider (the solo player).",
"type": "string"
},
"flash_speed": {
"description": "Reel flash presentation speed.",
"enum": [
"slow",
"normal",
"fast",
"blur"
],
"type": "string"
},
"num_digits": {
"description": "Digits per locked number (6, 8, 10, or 12). Default 10.",
"enum": [
6,
8,
10,
12
],
"type": "number"
},
"quick_select": {
"description": "For browser play, resolve all candidates on a single tap. Defaults to one tap per option. finish_solo_decision handles either setting.",
"type": "boolean"
},
"round_seconds": {
"description": "Round duration in seconds (3, 5, 10, or 15).",
"enum": [
3,
5,
10,
15
],
"type": "number"
},
"win_condition": {
"description": "Choose the highest (default) or lowest number.",
"enum": [
"highest",
"lowest"
],
"type": "string"
}
},
"required": [
"candidates"
],
"type": "object"
}create_option_pick_gameCreate an Option Pick game with 2–20 choices. Start the round with the host token, then lock once for each returned candidate ID as the decider. Returns candidates, game_id, join_url, and either a host_player (shared_link) or seeded_players (same_device).
{
"properties": {
"best_of": {
"description": "Rounds in a best-of series. Defaults to one.",
"enum": [
1,
3,
5,
7
],
"type": "number"
},
"candidates": {
"description": "Between 2 and 20 options to pick from.",
"items": {
"properties": {
"detail": {
"description": "Optional one-line secondary text (price, description).",
"maxLength": 160,
"type": "string"
},
"label": {
"maxLength": 80,
"minLength": 1,
"type": "string"
}
},
"required": [
"label"
],
"type": "object"
},
"maxItems": 20,
"minItems": 2,
"type": "array"
},
"flash_speed": {
"description": "Reel flash presentation speed.",
"enum": [
"slow",
"normal",
"fast",
"blur"
],
"type": "string"
},
"group_picks_together": {
"description": "If true, the host locks on behalf of the room.",
"type": "boolean"
},
"num_digits": {
"description": "Digits per locked number (6, 8, 10, or 12). Default 10.",
"enum": [
6,
8,
10,
12
],
"type": "number"
},
"participants": {
"description": "Shared link can start with one host. Up to 10 players on the free plan or 100 with a Creator account.",
"items": {
"properties": {
"display_name": {
"maxLength": 32,
"minLength": 1,
"type": "string"
}
},
"required": [
"display_name"
],
"type": "object"
},
"maxItems": 100,
"minItems": 1,
"type": "array"
},
"play_on": {
"description": "\"same_device\" or \"shared_link\"",
"enum": [
"same_device",
"shared_link"
],
"type": "string"
},
"round_seconds": {
"description": "Round duration in seconds (3, 5, 10, or 15).",
"enum": [
3,
5,
10,
15
],
"type": "number"
},
"sealed_reel": {
"description": "Optional, default false. Seals the reel: the numbers still to come stay hidden from every player until the last lock is in, so nobody, not even a scripted client, can read the reel and stop on a high number. Each player still sees their own number when they stop; until then the reel spins stand-in numbers. Leave it off for everyday play (watching the real numbers spin is part of the fun); turn it on when the user says the result really matters or asks for the strictest fairness. Afterwards verify_round checks the seed against the seal shown before the first stop.",
"type": "boolean"
},
"win_condition": {
"description": "\"highest\" (default) or \"lowest\".",
"enum": [
"highest",
"lowest"
],
"type": "string"
}
},
"required": [
"play_on",
"participants",
"candidates"
],
"type": "object"
}verify_roundPass round_id to check a round locally: re-derive its seed from the published inputs, check that seed against the seal (seed commitment) published before the first stop, rebuild the reel numbers from the seed and replay every lock. checks reports each part (null when a round stored before seals existed has nothing to check); matches compares seeds only; status is match only when every check passes. A round played on a sealed reel keeps its seed and numbers secret until every lock is in, so while anyone still has to stop it returns status sealed with no seed or numbers: call again once everyone has stopped. Pass game_id for a closed shared-link draw to get the backend's replay of recorded draws. Status is match or mismatch when checked, or unavailable with verified=null when the replay could not be completed.
{
"properties": {
"game_id": {
"description": "UUID of a shared-link scale game to verify. Mutually exclusive with round_id.",
"type": "string"
},
"round_id": {
"description": "UUID of the Phase 1 round to verify. Mutually exclusive with game_id.",
"type": "string"
}
},
"required": [],
"type": "object"
}hnw_discover_nearbyFind restaurants anywhere in the world from the same directory as the website. Supply lat/lng, or a city or postcode in metro. Returns up to 20 matching places and a committed eligible pool. Places come from open data (Overture Maps), so names and addresses may be kept; there are no ratings, price levels or opening hours. Demo responses are explicit. Featured dishes are available through get_featured_menu; generated dishes are never presented as an actual menu.
{
"properties": {
"lat": {
"description": "Caller's latitude (optional; pair with lng for distance sort).",
"type": "number"
},
"limit": {
"description": "Legacy hint; canonical searches return the complete matching pool, up to20. Use pick_count on lock_picks to shortlist.",
"type": "number"
},
"lng": {
"description": "Caller's longitude (optional; pair with lat).",
"type": "number"
},
"metro": {
"description": "City or postcode in any country, for example \"Lahore\", \"Austin, TX\" or \"75001\". Required when coordinates are omitted in live mode.",
"type": "string"
},
"radius_m": {
"description": "Search radius in meters when lat/lng are supplied. Default 4828 (3 miles).",
"type": "number"
}
},
"required": [],
"type": "object"
}create_branded_gameCreate an HNW Option-Pick game against a claimed merchant's dish set. Candidates come from the merchant's current page, so a merchant who rotates their menu will have their new dishes picked up automatically. Attribution is recorded server-side via the branded_games table.
{
"properties": {
"campaign": {
"description": "Optional campaign tag; stored on branded_games for analytics.",
"type": "string"
},
"display_name": {
"description": "The decider's display name. Defaults to 'Guest' for quick demos.",
"type": "string"
},
"max_candidates": {
"description": "Cap the dish list at this many (2..8). Default 5.",
"type": "number"
},
"play_on": {
"description": "\"same_device\" (default) or \"shared_link\".",
"enum": [
"same_device",
"shared_link"
],
"type": "string"
},
"slug": {
"description": "The merchant's restaurant slug (e.g. trattoria-da-vittorio-sf).",
"type": "string"
},
"trial_token": {
"description": "Optional sponsored-trial token. If present, attributes the play to the trial.",
"type": "string"
}
},
"required": [
"slug"
],
"type": "object"
}find_placesSearch places anywhere in the world by city or postcode, activity (food, bowling, karaoke, racket, outdoors) and food type or name. Results come from HNW's own open-data directory (Overture Maps): names and addresses may be kept, and there are no ratings, price levels or opening hours. Pass page for a different set of places in the same area. Demo responses are labeled. Returns a committed eligible pool. Use pool IDs and immutable receipts for selections.
{
"properties": {
"activity": {
"type": "string"
},
"city": {
"type": "string"
},
"cuisine": {
"type": "string"
},
"lat": {
"type": "number"
},
"lng": {
"type": "number"
},
"page": {
"type": "number"
},
"radius_m": {
"type": "number"
}
},
"required": [],
"type": "object"
}get_selectionRead an immutable HNW place or menu selection and its verification reference.
{
"properties": {
"id": {
"type": "string"
}
},
"required": [
"id"
],
"type": "object"
}get_live_leaderboardRead the current standings for an audience game. Entries can change while the draw is open. For the official winner after closing use get_audience_result.
{
"properties": {
"game_id": {
"type": "string"
},
"limit": {
"default": 10,
"maximum": 100,
"minimum": 1,
"multipleOf": 1,
"type": "number"
}
},
"required": [
"game_id"
],
"type": "object"
}list_public_gamesList public games that hosts have chosen to show: live now and opening soon. Each entry names its host, the host's own links and whether HNW has checked them. HNW only makes the pick; hosts run these games.
{
"properties": {},
"required": [],
"type": "object"
}get_featured_menuBrowse a restaurant's current featured dishes, prices, availability and equally applicable offers. Reading does not play or order.
{
"properties": {
"restaurant_id": {
"type": "string"
}
},
"required": [
"restaurant_id"
],
"type": "object"
}get_table_setRead the current table menu by its code from the restaurant's /t/{code} link. Returns the restaurant_id, active status, eligible dishes and any offer.
{
"properties": {
"code": {
"type": "string"
}
},
"required": [
"code"
],
"type": "object"
}verify_selectionAsk HNW to replay a place or menu selection receipt. Returns valid, the immutable receipt, and the verification method when it passes.
{
"properties": {
"id": {
"description": "Selection receipt ID from lock_picks.",
"type": "string"
}
},
"required": [
"id"
],
"type": "object"
}create_choice_poolFreeze eligible dishes from a restaurant or all selected IDs from a parent_selection_id. For an active table menu, use its restaurant_id and table_set code from get_table_set and omit item_ids and parent_selection_id. All pool members get equal draw treatment.
{
"properties": {
"item_ids": {
"items": {
"type": "string"
},
"type": "array"
},
"parent_selection_id": {
"type": "string"
},
"restaurant_id": {
"type": "string"
},
"table_set": {
"type": "string"
}
},
"required": [],
"type": "object"
}lock_picksResolve a committed eligible pool once. Supply fresh cryptographically random 32-byte hex client_entropy and the exact chosen count. Retries with the same request_id preserve the outcome.
{
"properties": {
"client_entropy": {
"type": "string"
},
"pick_count": {
"type": "number"
},
"pool_id": {
"type": "string"
},
"request_id": {
"type": "string"
}
},
"required": [
"pool_id",
"client_entropy",
"request_id",
"pick_count"
],
"type": "object"
}get_templateRead a saved template by its share ID. Use its configuration to create a new game.
{
"properties": {
"id": {
"type": "string"
}
},
"required": [
"id"
],
"type": "object"
}prepare_randomnessGenerate cryptographically random selection entropy and a request_id locally. Keep these values and pass them unchanged to lock_picks, including retries. Does not draw or select anything.
{
"properties": {},
"required": [],
"type": "object"
}