DEVELOPERS / MCP

MCP tool catalog.

Every public tool the HNW MCP server exposes. Admin-only tools are filtered out of this list.

Endpoint

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.

Try it: list public games

  1. Connect your MCP client to the endpoint above.
  2. Request tools/list to see the tools and their input schemas.
  3. Use tools/call to call list_public_games with no arguments.
  4. Read the live and soon lists. You can also browse them in the public games directory.

Tools

  • create_game

    Create 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.

    Input schema
    {
      "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_game

    Join 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.).

    Input schema
    {
      "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_game

    Start 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.

    Input schema
    {
      "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_number

    Lock 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.

    Input schema
    {
      "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_state

    Read 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.

    Input schema
    {
      "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_decision

    Finish 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.

    Input schema
    {
      "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_result

    Read 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.

    Input schema
    {
      "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_result

    When 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.

    Input schema
    {
      "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_result

    Return 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.

    Input schema
    {
      "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_decision

    Set 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.

    Input schema
    {
      "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_game

    Create 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).

    Input schema
    {
      "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_round

    Pass 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.

    Input schema
    {
      "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_nearby

    Find 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.

    Input schema
    {
      "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_game

    Create 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.

    Input schema
    {
      "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_places

    Search 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.

    Input schema
    {
      "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_selection

    Read an immutable HNW place or menu selection and its verification reference.

    Input schema
    {
      "properties": {
        "id": {
          "type": "string"
        }
      },
      "required": [
        "id"
      ],
      "type": "object"
    }
  • get_live_leaderboard

    Read 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.

    Input schema
    {
      "properties": {
        "game_id": {
          "type": "string"
        },
        "limit": {
          "default": 10,
          "maximum": 100,
          "minimum": 1,
          "multipleOf": 1,
          "type": "number"
        }
      },
      "required": [
        "game_id"
      ],
      "type": "object"
    }
  • list_public_games

    List 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.

    Input schema
    {
      "properties": {},
      "required": [],
      "type": "object"
    }
  • get_featured_menu

    Browse a restaurant's current featured dishes, prices, availability and equally applicable offers. Reading does not play or order.

    Input schema
    {
      "properties": {
        "restaurant_id": {
          "type": "string"
        }
      },
      "required": [
        "restaurant_id"
      ],
      "type": "object"
    }
  • get_table_set

    Read 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.

    Input schema
    {
      "properties": {
        "code": {
          "type": "string"
        }
      },
      "required": [
        "code"
      ],
      "type": "object"
    }
  • verify_selection

    Ask HNW to replay a place or menu selection receipt. Returns valid, the immutable receipt, and the verification method when it passes.

    Input schema
    {
      "properties": {
        "id": {
          "description": "Selection receipt ID from lock_picks.",
          "type": "string"
        }
      },
      "required": [
        "id"
      ],
      "type": "object"
    }
  • create_choice_pool

    Freeze 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.

    Input schema
    {
      "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_picks

    Resolve 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.

    Input schema
    {
      "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_template

    Read a saved template by its share ID. Use its configuration to create a new game.

    Input schema
    {
      "properties": {
        "id": {
          "type": "string"
        }
      },
      "required": [
        "id"
      ],
      "type": "object"
    }
  • prepare_randomness

    Generate 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.

    Input schema
    {
      "properties": {},
      "required": [],
      "type": "object"
    }