Koskamo

Player Two MCP

An official MCP server provided by Player Two that allows AI agents to interact with the Player Two game store and SDK. It enables searching and listing games, retrieving game facts and SDK documentation, and managing game submissions, media uploads, builds, trophies, leaderboards, and multiplayer rooms for developers.

Endpoint and access

No sign-in to connect and list tools. Individual tools may still need a vendor account, credentials, or permissions; check the documented prerequisites.

Player Two MCP logo, by Player TwoVendor evidenceStreamable HTTPNo sign-inEndpoint checked 2026-11-08Operated by Player Two
MCP endpoint (Streamable HTTP)
https://playertwo.lol/api/mcp
Vendor documentation

What its tools do

33 tools, grouped by the hints the server advertises. Hints are self-declared, not verified behavior.

33 of 33 have a description · 33 of 33 declare behavior hints · 24 of 30 with parameters document them all

Checks and signals

Each line is separate evidence, not a trust score.

  • Passed Endpoint answered the live check ·
  • Passed Official MCP Registry namespace is tied to playertwo.lol ·
  • Passed Endpoint is on the registry namespace domain ·
  • Availability 1 of 1 checks passed in 30 days

What you can do with it

  • Search and list browser games on the store
  • Retrieve game facts and SDK documentation
  • Submit games and upload media or web builds
  • Manage trophies, leaderboards, and multiplayer rooms

Source and maintenance

Vendor evidenceRegistry 1.1.0
Maintenance checked

Protocol and capabilities

Server
player-two 1.1.0
MCP protocol negotiated in check
2025-11-25
Tools
33 advertised
Resources
Not advertised
Resource templates
Not advertised
Prompts
Not advertised
Server-advertised capabilities
{
  "tools": {
    "listChanged": false
  }
}

Server-provided instructions

Untrusted server output shown for inspection. It is not Koskamo guidance and is excluded from knowledge search.

Player Two (playertwo.lol) is a game store and launchpad: games played in the browser (free or paid) or downloaded, and raises where players back a game while it is made. Without a key: search_games and list_games find its games, get_game_facts tells one in full (what it is, price, where and how to play, multiplayer, updates), get_sdk_docs reads the developer docs (the game SDK, multiplayer rooms, hosting, fees) and where_to_publish says what Player Two offers a game's developer. With the player's agent key (Authorization: Bearer p2_agent_..., made in their studio under Agents) or once they sign in when asked: submit and edit their games, from get_submission_guide on (the store and raises; a hosted game's trophies, leaderboards and what it sells; a web game's builds; a playtest link; updates on a game's page and their comments; its multiplayer rooms now). A raise takes no money until the player checks their identity in their studio themselves.

Tools

33 advertised

search_games — Search Player Two's games
Advertised by the server during the last successful anonymous check.
Advertised read-only

Find games on Player Two (playertwo.lol), a store of games played in the browser: by words (in a game's name, tagline, description, studio, genres, modes and features: every word must match), genre, platform, free or paid, multiplayer, store game or raise. Each game with its slug, name, tagline, studio, genres, modes, price and whether it is free, a sale, a free trial, whether it plays with others, where it plays, players, reviews and its page's address. get_game_facts tells one in full. No key needed.

search_games input schema
{
  "type": "object",
  "properties": {
    "kind": {
      "enum": [
        "store",
        "raise"
      ],
      "type": "string",
      "description": "store: games out (or coming) in the store; raise: games raising money from players while they are made."
    },
    "genre": {
      "type": "string",
      "maxLength": 40,
      "description": "Only games with this genre, as Player Two names them (Action, Adventure, Arcade, Arena, Casual, Co-op, Fighting, Horror, Multiplayer, Platformer, Puzzle, Racing, Roguelite, RPG, Shooter, Simulation, Social, Sports, Strategy, Survival, or a game's own)."
    },
    "limit": {
      "type": "integer",
      "maximum": 50,
      "minimum": 1,
      "description": "How many, 1 to 50 (20 if left out)."
    },
    "order": {
      "enum": [
        "featured",
        "popular",
        "new",
        "playing"
      ],
      "type": "string",
      "description": "featured (Player Two's own order, the default), popular (most players), new (newest first) or playing (most playing now)."
    },
    "price": {
      "enum": [
        "free",
        "paid",
        "any"
      ],
      "type": "string",
      "description": "free, paid, or any (the default)."
    },
    "query": {
      "type": "string",
      "maxLength": 200,
      "description": "Words to find, in a game's name, tagline, description, studio, genres, modes or features (every word must match). Left out: every game the filters let through."
    },
    "offset": {
      "type": "integer",
      "maximum": 10000,
      "minimum": 0,
      "description": "How many to skip, for the next page (the answer's next)."
    },
    "platform": {
      "enum": [
        "Browser",
        "Windows",
        "Mac",
        "Linux",
        "Mobile"
      ],
      "type": "string",
      "description": "Only games that play on this."
    },
    "multiplayer": {
      "type": "boolean",
      "description": "true: only games played with others (by their genres and modes, or their own servers); false: only the others."
    }
  }
}
search_games annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
list_games — List Player Two's games
Advertised by the server during the last successful anonymous check.
Advertised read-only

Every game in Player Two's store (playertwo.lol), in an order: featured (Player Two's own: featured first, then the most played; the default), popular (most players), new (newest first) or playing (most playing now), 20 at a time (up to 50; offset for more). The same filters as search_games. No key needed.

list_games input schema
{
  "type": "object",
  "properties": {
    "kind": {
      "enum": [
        "store",
        "raise"
      ],
      "type": "string",
      "description": "store: games out (or coming) in the store; raise: games raising money from players while they are made."
    },
    "genre": {
      "type": "string",
      "maxLength": 40,
      "description": "Only games with this genre, as Player Two names them (Action, Adventure, Arcade, Arena, Casual, Co-op, Fighting, Horror, Multiplayer, Platformer, Puzzle, Racing, Roguelite, RPG, Shooter, Simulation, Social, Sports, Strategy, Survival, or a game's own)."
    },
    "limit": {
      "type": "integer",
      "maximum": 50,
      "minimum": 1,
      "description": "How many, 1 to 50 (20 if left out)."
    },
    "order": {
      "enum": [
        "featured",
        "popular",
        "new",
        "playing"
      ],
      "type": "string",
      "description": "featured (Player Two's own order, the default), popular (most players), new (newest first) or playing (most playing now)."
    },
    "price": {
      "enum": [
        "free",
        "paid",
        "any"
      ],
      "type": "string",
      "description": "free, paid, or any (the default)."
    },
    "offset": {
      "type": "integer",
      "maximum": 10000,
      "minimum": 0,
      "description": "How many to skip, for the next page (the answer's next)."
    },
    "platform": {
      "enum": [
        "Browser",
        "Windows",
        "Mac",
        "Linux",
        "Mobile"
      ],
      "type": "string",
      "description": "Only games that play on this."
    },
    "multiplayer": {
      "type": "boolean",
      "description": "true: only games played with others (by their genres and modes, or their own servers); false: only the others."
    }
  }
}
list_games annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
get_game_facts — A game's facts
Advertised by the server during the last successful anonymous check.
Advertised read-only

Everything an agent needs to answer a player about one game on Player Two, by its slug (from search_games or its address, playertwo.lol/game/<slug>): what it is, its genres and modes, what it plays on, who it is for, its price (a sale, a trial, a raise's progress), where to play it and whether a guest can, how to play it (its controls and goals, in its developer's words), whether it is multiplayer, the Player Two services it has (trophies, leaderboards, cloud saves, add-ons), its latest updates, and how to report a bug. The same facts its page gives agents. No key needed.

get_game_facts input schema
{
  "type": "object",
  "required": [
    "slug"
  ],
  "properties": {
    "slug": {
      "type": "string",
      "maxLength": 80,
      "description": "The game's address on Player Two (playertwo.lol/game/<slug>), from search_games or list_games."
    }
  }
}
get_game_facts annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
get_sdk_docs — Read Player Two's developer docs
Advertised by the server during the last successful anonymous check.
Advertised read-only

A part of Player Two's developer docs, in Markdown, as the docs pages say it today: the game SDK (trophies, leaderboards, stats, cloud saves, presence, in-game purchases, multiplayer rooms and room code), hosting a web game and pushing builds, Player Two Connect for a game on its own site, travel and avatars, webhooks, and the platform's rules for developers (listing, raises, fees, agents). topic: a page and part ("/docs/sdk#rooms"), a part's id ("rooms-sync"), or a few words ("leaderboards", "push", "fees"); left out, the list of every topic. No key needed.

get_sdk_docs input schema
{
  "type": "object",
  "properties": {
    "topic": {
      "type": "string",
      "maxLength": 200,
      "description": "A part of the docs: a page and part (\"/docs/sdk#rooms\", \"/docs/hosting#push\"), a part's id (\"call-trophies\", \"rooms-sync\"), or a few words (\"leaderboards\", \"cloud saves\", \"fees\", \"mcp\"). Left out: the list of every topic."
    }
  }
}
get_sdk_docs annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
where_to_publish — Publishing a game on Player Two
Advertised by the server during the last successful anonymous check.
Advertised read-only

What Player Two offers a game's developer, as its docs state it, each fact with its link: what it keeps of sales, in-game purchases and raises, how a game gets there (the form, an agent, a zip, a pushed folder, GitHub, its own site served), and everything a game gets (store page, hosting, SDK, multiplayer rooms, trophies, leaderboards, saves, purchases, webhooks, MCP). No key needed.

where_to_publish input schema
{
  "type": "object",
  "properties": {}
}
where_to_publish annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
get_submission_guide — How to submit a game
Advertised by the server during the last successful anonymous check.
Advertised read-only

Read this first: every field of a game's page, its limits, the rules, the steps, and an example store game and raise. No key needed.

get_submission_guide input schema
{
  "type": "object",
  "properties": {}
}
get_submission_guide annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
check_game — Check a draft
Advertised by the server during the last successful anonymous check.
Advertised read-only

Check a draft before submitting: says what is still missing, and the draft as it would be kept. Saves nothing. No key needed.

check_game input schema
{
  "type": "object",
  "required": [
    "draft"
  ],
  "properties": {
    "draft": {
      "type": "object",
      "properties": {
        "v": {
          "type": "number",
          "const": 1
        },
        "x": {
          "type": "string",
          "description": "X handle or link."
        },
        "age": {
          "enum": [
            "13",
            "16",
            "18",
            "all",
            ""
          ],
          "type": "string",
          "description": "Who it is for. Sexual content or nudity in content makes it 18 whatever is given."
        },
        "art": {
          "type": "string",
          "description": "The key art from upload_media, required: square, 2400 by 2400 at best, no title on it. The game's card (its middle two-thirds), its page's first screen in 3D and its wide picture in the store."
        },
        "sub": {
          "type": "string",
          "maxLength": 28,
          "description": "A line under the name. Up to 28 characters; longer is cut."
        },
        "why": {
          "type": "string",
          "maxLength": 300,
          "description": "Raise: why back it. Up to 300 characters; longer is cut."
        },
        "base": {
          "type": "string",
          "maxLength": 40,
          "description": "What it is, like \"Independent studio\". Up to 40 characters; longer is cut."
        },
        "clip": {
          "type": "string",
          "description": "The launch trailer from upload_media, required (MP4 or WebM)."
        },
        "days": {
          "type": "number",
          "maximum": 120,
          "minimum": 3,
          "description": "Raise: how long it is open."
        },
        "demo": {
          "type": "boolean",
          "description": "Store: this is a free demo, not the finished game."
        },
        "face": {
          "type": "object",
          "required": [
            "from",
            "family",
            "weight",
            "italic",
            "files"
          ],
          "properties": {
            "from": {
              "enum": [
                "google",
                "own"
              ],
              "type": "string"
            },
            "files": {
              "type": "array",
              "items": {
                "type": "object",
                "required": [
                  "src"
                ],
                "properties": {
                  "src": {
                    "type": "string"
                  },
                  "range": {
                    "type": "string"
                  }
                },
                "additionalProperties": {}
              }
            },
            "family": {
              "type": "string"
            },
            "italic": {
              "type": "boolean"
            },
            "weight": {
              "type": "number"
            }
          },
          "description": "The typeface the name is lettered in, as Player Two keeps it (made from font).",
          "additionalProperties": {}
        },
        "font": {
          "anyOf": [
            {
              "type": "string",
              "description": "A template (anton, bungee, bangers, cinzel, syncopate, kanit, pixel, archivo, chakra), or a font's address from upload_media."
            },
            {
              "type": "object",
              "required": [
                "google"
              ],
              "properties": {
                "google": {
                  "type": "string"
                },
                "italic": {
                  "type": "boolean"
                },
                "weight": {
                  "type": "number"
                }
              },
              "description": "A Google Fonts family at one of its weights: its files are kept in Player Two's own store."
            }
          ],
          "description": "How the name is lettered."
        },
        "glow": {
          "type": "string",
          "pattern": "^#[0-9a-fA-F]{6}$",
          "description": "The game's colour, #rrggbb."
        },
        "goal": {
          "type": "number",
          "maximum": 10000000,
          "minimum": 1,
          "description": "Raise: dollars asked."
        },
        "kind": {
          "enum": [
            "store",
            "raise"
          ],
          "type": "string",
          "description": "\"store\": sold (or free) and played or downloaded from its page. \"raise\": players back a game being made. Default raise."
        },
        "more": {
          "type": "string",
          "maxLength": 700,
          "description": "A second paragraph. Up to 700 characters; longer is cut."
        },
        "name": {
          "type": "string",
          "maxLength": 28,
          "description": "The name as lettered on the card (uppercase); the title when empty. Up to 28 characters; longer is cut."
        },
        "note": {
          "type": "string",
          "maxLength": 900,
          "description": "A note to players. Up to 900 characters; longer is cut."
        },
        "sign": {
          "type": "string",
          "maxLength": 40,
          "description": "How it signs off. Up to 40 characters; longer is cut."
        },
        "site": {
          "type": "string",
          "description": "Its website."
        },
        "size": {
          "type": "number",
          "description": "The lettering's size, 0.5 to 1.6."
        },
        "tall": {
          "type": "string",
          "description": "An older listing's vertical poster (2:3): its card while it has no key art."
        },
        "build": {
          "type": "string",
          "description": "The address upload_web_build returned: a web build Player Two keeps, played at https://<slug>.playertwo.cc."
        },
        "depth": {
          "type": "string",
          "description": "The key art's depth map, made by Player Two."
        },
        "modes": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Up to 10 short words (Duel, Co-op...), the main ones first."
        },
        "opens": {
          "type": "number",
          "description": "Raise: when it opens to backers (milliseconds since 1970), up to 60 days ahead."
        },
        "pitch": {
          "type": "string",
          "maxLength": 700,
          "description": "What it is, in a paragraph. Up to 700 characters; longer is cut."
        },
        "price": {
          "type": "number",
          "maximum": 500,
          "minimum": 0,
          "description": "Store: dollars, 0 is free."
        },
        "share": {
          "type": "number",
          "maximum": 0.85,
          "minimum": 0.4,
          "description": "Raise with backers \"share\": the backers' share of every sale."
        },
        "shots": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Up to 8 screenshots from upload_media."
        },
        "sound": {
          "type": "boolean",
          "description": "Whether the trailer's sound may play."
        },
        "title": {
          "type": "string",
          "maxLength": 60,
          "description": "The game's name. Up to 60 characters; longer is cut."
        },
        "today": {
          "enum": [
            "concept",
            "prototype",
            "demo",
            "early"
          ],
          "type": "string",
          "description": "Raise: where the game is today."
        },
        "trial": {
          "enum": [
            0,
            15,
            30,
            60,
            90,
            120
          ],
          "type": "number",
          "description": "Store, for a game that costs money and plays in the browser: a free trial in minutes, once for each player who doesn't own it (0: none; a new game left without one gets 30)."
        },
        "access": {
          "type": "array",
          "items": {
            "enum": [
              "Subtitles",
              "Captions for sounds",
              "Adjustable text size",
              "Colour-blind options",
              "High contrast",
              "Remappable controls",
              "One-handed play",
              "No timed inputs needed",
              "Adjustable difficulty",
              "Save anytime",
              "Separate volume controls",
              "Narrated menus",
              "Camera comfort options",
              "Mouse only",
              "Keyboard only",
              "Touch only"
            ],
            "type": "string"
          },
          "description": "What it does for players with a disability."
        },
        "copies": {
          "type": "object",
          "description": "The pictures' smaller copies, by each picture's address (made by Player Two).",
          "propertyNames": {
            "type": "string"
          },
          "additionalProperties": {
            "type": "object",
            "required": [
              "w",
              "at"
            ],
            "properties": {
              "w": {
                "type": "number"
              },
              "at": {
                "type": "array",
                "items": {
                  "type": "object",
                  "required": [
                    "w",
                    "src"
                  ],
                  "properties": {
                    "w": {
                      "type": "number"
                    },
                    "src": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "follow": {
          "type": "boolean",
          "description": "With playUrl (on for a new game unless false): Player Two serves the site from https://<slug>.playertwo.cc, so saves follow players and the SDK is in its pages."
        },
        "genres": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Up to 10, the main ones first (a game shows its first four), each up to 24 characters. The store's: Action, Adventure, Arcade, Arena, Casual, Co-op, Fighting, Horror, Multiplayer, Platformer, Puzzle, Racing, Roguelite, RPG, Shooter, Simulation, Social, Sports, Strategy, Survival."
        },
        "poster": {
          "type": "string",
          "description": "An older listing's main poster (16:9): its wide picture beside key art; new key art takes the place of both posters."
        },
        "stages": {
          "type": "array",
          "items": {
            "type": "object",
            "required": [
              "title"
            ],
            "properties": {
              "days": {
                "type": "number",
                "description": "Due this many days after the raise is funded."
              },
              "proof": {
                "type": "string",
                "maxLength": 240,
                "description": "What backers will see. Up to 240 characters; longer is cut."
              },
              "share": {
                "type": "number",
                "description": "Its share of the raise, 0 to 1; all add up to 1."
              },
              "title": {
                "type": "string",
                "maxLength": 60,
                "description": "The stage. Up to 60 characters; longer is cut."
              }
            }
          },
          "description": "Raise: 1 to 8 stages."
        },
        "stills": {
          "type": "object",
          "description": "A still of each feature's video (made by Player Two).",
          "propertyNames": {
            "type": "string"
          },
          "additionalProperties": {
            "type": "string"
          }
        },
        "studio": {
          "type": "string",
          "maxLength": 40,
          "description": "The studio's name, required. Up to 40 characters; longer is cut."
        },
        "videos": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Up to 4 gameplay videos from upload_media, after the trailer, in this order."
        },
        "backers": {
          "enum": [
            "share",
            "rewards"
          ],
          "type": "string",
          "description": "Raise: what backers get, a share of every sale or rewards only."
        },
        "content": {
          "type": "array",
          "items": {
            "enum": [
              "Violence",
              "Blood and gore",
              "Sexual content",
              "Nudity",
              "Strong language",
              "Drugs, alcohol or tobacco",
              "Gambling-style play",
              "Frightening scenes",
              "Talking with strangers online"
            ],
            "type": "string"
          },
          "description": "What it shows, for players and parents."
        },
        "discord": {
          "type": "string",
          "description": "Discord invite."
        },
        "playUrl": {
          "type": "string",
          "description": "The https address where the game is played on its own site."
        },
        "rewards": {
          "type": "array",
          "items": {
            "type": "object",
            "required": [
              "min",
              "title"
            ],
            "properties": {
              "min": {
                "type": "number"
              },
              "body": {
                "type": "string",
                "maxLength": 240,
                "description": "A line more. Up to 240 characters; longer is cut."
              },
              "title": {
                "type": "string",
                "maxLength": 60,
                "description": "What they get. Up to 60 characters; longer is cut."
              }
            }
          },
          "description": "Raise with backers \"rewards\": up to 8, by the least put in for each."
        },
        "spacing": {
          "type": "string",
          "maxLength": 10,
          "description": "Letter spacing, as CSS. Up to 10 characters; longer is cut."
        },
        "tagline": {
          "type": "string",
          "maxLength": 90,
          "description": "One line about it. Up to 90 characters; longer is cut."
        },
        "youtube": {
          "type": "string",
          "description": "YouTube channel."
        },
        "branches": {
          "type": "array",
          "items": {
            "type": "object",
            "required": [
              "name",
              "goals"
            ],
            "properties": {
              "name": {
                "type": "string",
                "maxLength": 30,
                "description": "A branch of work. Up to 30 characters; longer is cut."
              },
              "goals": {
                "type": "array",
                "items": {
                  "type": "object",
                  "required": [
                    "title"
                  ],
                  "properties": {
                    "now": {
                      "type": "string"
                    },
                    "cost": {
                      "type": "number"
                    },
                    "next": {
                      "type": "string"
                    },
                    "shot": {
                      "type": "number"
                    },
                    "stage": {
                      "type": "number"
                    },
                    "title": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "description": "Raise: what the money builds, up to 4 branches of up to 3 goals."
        },
        "features": {
          "type": "array",
          "items": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 90,
                "description": "A feature with neither picture nor video: words on the page, in the game's colour. Up to 90 characters; longer is cut."
              },
              {
                "type": "object",
                "properties": {
                  "art": {
                    "type": "string",
                    "description": "A picture's address from upload_media, shown wide (16:9)."
                  },
                  "clip": {
                    "type": "string",
                    "description": "Or a video's address from upload_media (a picture wins when both are given)."
                  },
                  "text": {
                    "type": "string",
                    "maxLength": 90,
                    "description": "The feature, in a line. Up to 90 characters; longer is cut."
                  }
                }
              }
            ]
          },
          "description": "Store: up to 6."
        },
        "postBody": {
          "type": "string",
          "maxLength": 600,
          "description": "The first post. Up to 600 characters; longer is cut."
        },
        "languages": {
          "type": "array",
          "items": {
            "type": "object",
            "required": [
              "lang"
            ],
            "properties": {
              "ui": {
                "type": "boolean"
              },
              "lang": {
                "enum": [
                  "English",
                  "Spanish",
                  "Spanish (Latin America)",
                  "Portuguese (Brazil)",
                  "Portuguese",
                  "French",
                  "German",
                  "Italian",
                  "Dutch",
                  "Polish",
                  "Russian",
                  "Ukrainian",
                  "Turkish",
                  "Arabic",
                  "Hebrew",
                  "Hindi",
                  "Bengali",
                  "Thai",
                  "Vietnamese",
                  "Indonesian",
                  "Malay",
                  "Filipino",
                  "Japanese",
                  "Korean",
                  "Chinese (Simplified)",
                  "Chinese (Traditional)",
                  "Swedish",
                  "Norwegian",
                  "Danish",
                  "Finnish",
                  "Czech",
                  "Slovak",
                  "Hungarian",
                  "Romanian",
                  "Bulgarian",
                  "Greek",
                  "Persian"
                ],
                "type": "string"
              },
              "subs": {
                "type": "boolean"
              },
              "audio": {
                "type": "boolean"
              }
            }
          },
          "description": "The languages it comes in: its words on screen (ui), voices (audio), subtitles (subs)."
        },
        "minTicket": {
          "type": "number",
          "description": "Raise: the smallest stake, dollars."
        },
        "platforms": {
          "type": "array",
          "items": {
            "enum": [
              "Browser",
              "Windows",
              "Mac",
              "Linux",
              "Mobile"
            ],
            "type": "string"
          },
          "description": "Where it plays."
        },
        "postTitle": {
          "type": "string",
          "maxLength": 80,
          "description": "The first post's title. Up to 80 characters; longer is cut."
        },
        "qualifier": {
          "type": "string",
          "maxLength": 40,
          "description": "A short note after the tagline, like \"an unofficial fan game\". Up to 40 characters; longer is cut."
        },
        "todayLine": {
          "type": "string",
          "maxLength": 90,
          "description": "Raise: where it is today, in a line. Up to 90 characters; longer is cut."
        },
        "agentNotes": {
          "type": "object",
          "properties": {
            "goals": {
              "type": "string",
              "maxLength": 400,
              "description": "What a player is trying to do, and how a run or a round ends. Up to 400 characters; longer is cut."
            },
            "controls": {
              "type": "string",
              "maxLength": 400,
              "description": "The controls: keys, mouse, touch or gamepad, and what each does. Up to 400 characters; longer is cut."
            }
          },
          "description": "How to play, in the developer's words: shown to agents reading the game's page (a hidden section), never to players."
        },
        "clipCopies": {
          "type": "object",
          "description": "The trailer's lighter copies (made by Player Two).",
          "propertyNames": {
            "type": "string"
          },
          "additionalProperties": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "h",
                "src"
              ],
              "properties": {
                "h": {
                  "type": "number"
                },
                "src": {
                  "type": "string"
                }
              }
            }
          }
        },
        "controller": {
          "enum": [
            "full",
            "partial",
            ""
          ],
          "type": "string",
          "description": "\"full\": it all plays with a gamepad. \"partial\": some of it needs a keyboard or mouse."
        },
        "multiplayer": {
          "enum": [
            "rooms",
            "none",
            "own"
          ],
          "type": "string",
          "description": "For a game hosted on Player Two: Player Two's rooms through p2.rooms (the default), single-player, or its own servers."
        },
        "orientation": {
          "enum": [
            "landscape",
            "portrait",
            ""
          ],
          "type": "string",
          "description": "Which way a phone is held to play it: \"landscape\" (sideways) or \"portrait\" (upright); \"\" either way. A landscape game's card on X plays it sideways on a phone held upright, as X's app doesn't turn."
        },
        "plannedPrice": {
          "type": "number",
          "description": "Raise: the price it will sell at, dollars."
        },
        "requirements": {
          "type": "object",
          "properties": {
            "min": {
              "type": "object",
              "properties": {
                "os": {
                  "type": "string",
                  "maxLength": 80,
                  "description": "Operating system. Up to 80 characters; longer is cut."
                },
                "cpu": {
                  "type": "string",
                  "maxLength": 80,
                  "description": "Processor. Up to 80 characters; longer is cut."
                },
                "gpu": {
                  "type": "string",
                  "maxLength": 80,
                  "description": "Graphics. Up to 80 characters; longer is cut."
                },
                "ram": {
                  "type": "string",
                  "maxLength": 80,
                  "description": "Memory. Up to 80 characters; longer is cut."
                },
                "notes": {
                  "type": "string",
                  "maxLength": 200,
                  "description": "Anything else. Up to 200 characters; longer is cut."
                },
                "storage": {
                  "type": "string",
                  "maxLength": 80,
                  "description": "Disk space. Up to 80 characters; longer is cut."
                }
              }
            },
            "rec": {
              "type": "object",
              "properties": {
                "os": {
                  "type": "string",
                  "maxLength": 80,
                  "description": "Operating system. Up to 80 characters; longer is cut."
                },
                "cpu": {
                  "type": "string",
                  "maxLength": 80,
                  "description": "Processor. Up to 80 characters; longer is cut."
                },
                "gpu": {
                  "type": "string",
                  "maxLength": 80,
                  "description": "Graphics. Up to 80 characters; longer is cut."
                },
                "ram": {
                  "type": "string",
                  "maxLength": 80,
                  "description": "Memory. Up to 80 characters; longer is cut."
                },
                "notes": {
                  "type": "string",
                  "maxLength": 200,
                  "description": "Anything else. Up to 200 characters; longer is cut."
                },
                "storage": {
                  "type": "string",
                  "maxLength": 80,
                  "description": "Disk space. Up to 80 characters; longer is cut."
                }
              }
            }
          },
          "description": "What a computer needs for its downloads: the least, and what plays it best."
        }
      },
      "additionalProperties": {}
    }
  }
}
check_game annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
upload_media — Upload a picture, a trailer or a font
Advertised by the server during the last successful anonymous check.
Open-world

Keep a picture (PNG, JPEG or WebP up to 12 MB: the key art, screenshots, a feature's picture), a trailer or a gameplay video (MP4 or WebM up to 80 MB) or a font for the name's lettering (WOFF2, WOFF, TTF or OTF up to 2 MB, checked by what it is; only a font you are allowed to use on the web) in Player Two's file store. Returns its address, for the draft's art, poster, shots, clip, videos, a feature's art, or font. With game (a slug), a picture or a video for that game's updates instead: the only kind of address post_update's media takes.

upload_media input schema
{
  "type": "object",
  "properties": {
    "url": {
      "type": "string",
      "format": "uri",
      "maxLength": 2000,
      "description": "The file's https address (preferred)."
    },
    "data": {
      "type": "string",
      "maxLength": 4500000,
      "description": "Or the file itself in base64, up to 3 MB."
    },
    "game": {
      "type": "string",
      "maxLength": 80,
      "description": "For a picture or video to attach to a game's update (post_update's media): that game's slug. Kept where only its team can upload to; without it, a file can't be attached to an update."
    },
    "filename": {
      "type": "string",
      "maxLength": 120,
      "description": "Its name, when sent as data."
    }
  }
}
upload_media annotations
{
  "readOnlyHint": false,
  "openWorldHint": true,
  "idempotentHint": false,
  "destructiveHint": false
}
upload_web_build — Upload a web build
Advertised by the server during the last successful anonymous check.
Open-world

Keep a game played in the browser: a .zip with index.html at its top (up to 100 MB), or a single .html page. Returns the address to put in the draft's build. version (optional): what the build is called, up to 32 characters of letters, digits, dots, dashes, plus signs and spaces, starting with a letter or a digit (like 1.4.0); left out, it is called by its number in its game's builds ("12") once the draft names it.

upload_web_build input schema
{
  "type": "object",
  "properties": {
    "url": {
      "type": "string",
      "format": "uri",
      "maxLength": 2000,
      "description": "The file's https address (preferred)."
    },
    "data": {
      "type": "string",
      "maxLength": 4500000,
      "description": "Or the file itself in base64, up to 3 MB."
    },
    "version": {
      "anyOf": [
        {
          "type": "string",
          "maxLength": 200
        },
        {
          "type": "null"
        }
      ],
      "pattern": "^[A-Za-z0-9][A-Za-z0-9.+\\- ]*$",
      "maxLength": 32,
      "description": "Its version, shown with it in the studio and wherever its builds are listed, once a game's draft names it. A build's version is up to 32 characters: letters, digits, dots, dashes, plus signs and spaces, starting with a letter or a digit (like 1.4.0 or 2.0 beta). Left out, the build is called by its number in its game's builds (1 for its first: \"12\"). 422 bad-version when it breaks the rule."
    },
    "filename": {
      "type": "string",
      "maxLength": 120,
      "description": "Its name, when sent as data."
    }
  }
}
upload_web_build annotations
{
  "readOnlyHint": false,
  "openWorldHint": true,
  "idempotentHint": false,
  "destructiveHint": false
}
submit_game — Submit a game
Advertised by the server during the last successful anonymous check.
Open-world

Submit the player's game, for the store (kind: store) or as a raise (kind: raise). Live at once, or kept as a draft in their studio with publish: false. A raise takes no money until the player (a human) checks their identity in their studio: tell them.

submit_game input schema
{
  "type": "object",
  "required": [
    "draft"
  ],
  "properties": {
    "draft": {
      "type": "object",
      "properties": {
        "v": {
          "type": "number",
          "const": 1
        },
        "x": {
          "type": "string",
          "description": "X handle or link."
        },
        "age": {
          "enum": [
            "13",
            "16",
            "18",
            "all",
            ""
          ],
          "type": "string",
          "description": "Who it is for. Sexual content or nudity in content makes it 18 whatever is given."
        },
        "art": {
          "type": "string",
          "description": "The key art from upload_media, required: square, 2400 by 2400 at best, no title on it. The game's card (its middle two-thirds), its page's first screen in 3D and its wide picture in the store."
        },
        "sub": {
          "type": "string",
          "maxLength": 28,
          "description": "A line under the name. Up to 28 characters; longer is cut."
        },
        "why": {
          "type": "string",
          "maxLength": 300,
          "description": "Raise: why back it. Up to 300 characters; longer is cut."
        },
        "base": {
          "type": "string",
          "maxLength": 40,
          "description": "What it is, like \"Independent studio\". Up to 40 characters; longer is cut."
        },
        "clip": {
          "type": "string",
          "description": "The launch trailer from upload_media, required (MP4 or WebM)."
        },
        "days": {
          "type": "number",
          "maximum": 120,
          "minimum": 3,
          "description": "Raise: how long it is open."
        },
        "demo": {
          "type": "boolean",
          "description": "Store: this is a free demo, not the finished game."
        },
        "face": {
          "type": "object",
          "required": [
            "from",
            "family",
            "weight",
            "italic",
            "files"
          ],
          "properties": {
            "from": {
              "enum": [
                "google",
                "own"
              ],
              "type": "string"
            },
            "files": {
              "type": "array",
              "items": {
                "type": "object",
                "required": [
                  "src"
                ],
                "properties": {
                  "src": {
                    "type": "string"
                  },
                  "range": {
                    "type": "string"
                  }
                },
                "additionalProperties": {}
              }
            },
            "family": {
              "type": "string"
            },
            "italic": {
              "type": "boolean"
            },
            "weight": {
              "type": "number"
            }
          },
          "description": "The typeface the name is lettered in, as Player Two keeps it (made from font).",
          "additionalProperties": {}
        },
        "font": {
          "anyOf": [
            {
              "type": "string",
              "description": "A template (anton, bungee, bangers, cinzel, syncopate, kanit, pixel, archivo, chakra), or a font's address from upload_media."
            },
            {
              "type": "object",
              "required": [
                "google"
              ],
              "properties": {
                "google": {
                  "type": "string"
                },
                "italic": {
                  "type": "boolean"
                },
                "weight": {
                  "type": "number"
                }
              },
              "description": "A Google Fonts family at one of its weights: its files are kept in Player Two's own store."
            }
          ],
          "description": "How the name is lettered."
        },
        "glow": {
          "type": "string",
          "pattern": "^#[0-9a-fA-F]{6}$",
          "description": "The game's colour, #rrggbb."
        },
        "goal": {
          "type": "number",
          "maximum": 10000000,
          "minimum": 1,
          "description": "Raise: dollars asked."
        },
        "kind": {
          "enum": [
            "store",
            "raise"
          ],
          "type": "string",
          "description": "\"store\": sold (or free) and played or downloaded from its page. \"raise\": players back a game being made. Default raise."
        },
        "more": {
          "type": "string",
          "maxLength": 700,
          "description": "A second paragraph. Up to 700 characters; longer is cut."
        },
        "name": {
          "type": "string",
          "maxLength": 28,
          "description": "The name as lettered on the card (uppercase); the title when empty. Up to 28 characters; longer is cut."
        },
        "note": {
          "type": "string",
          "maxLength": 900,
          "description": "A note to players. Up to 900 characters; longer is cut."
        },
        "sign": {
          "type": "string",
          "maxLength": 40,
          "description": "How it signs off. Up to 40 characters; longer is cut."
        },
        "site": {
          "type": "string",
          "description": "Its website."
        },
        "size": {
          "type": "number",
          "description": "The lettering's size, 0.5 to 1.6."
        },
        "tall": {
          "type": "string",
          "description": "An older listing's vertical poster (2:3): its card while it has no key art."
        },
        "build": {
          "type": "string",
          "description": "The address upload_web_build returned: a web build Player Two keeps, played at https://<slug>.playertwo.cc."
        },
        "depth": {
          "type": "string",
          "description": "The key art's depth map, made by Player Two."
        },
        "modes": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Up to 10 short words (Duel, Co-op...), the main ones first."
        },
        "opens": {
          "type": "number",
          "description": "Raise: when it opens to backers (milliseconds since 1970), up to 60 days ahead."
        },
        "pitch": {
          "type": "string",
          "maxLength": 700,
          "description": "What it is, in a paragraph. Up to 700 characters; longer is cut."
        },
        "price": {
          "type": "number",
          "maximum": 500,
          "minimum": 0,
          "description": "Store: dollars, 0 is free."
        },
        "share": {
          "type": "number",
          "maximum": 0.85,
          "minimum": 0.4,
          "description": "Raise with backers \"share\": the backers' share of every sale."
        },
        "shots": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Up to 8 screenshots from upload_media."
        },
        "sound": {
          "type": "boolean",
          "description": "Whether the trailer's sound may play."
        },
        "title": {
          "type": "string",
          "maxLength": 60,
          "description": "The game's name. Up to 60 characters; longer is cut."
        },
        "today": {
          "enum": [
            "concept",
            "prototype",
            "demo",
            "early"
          ],
          "type": "string",
          "description": "Raise: where the game is today."
        },
        "trial": {
          "enum": [
            0,
            15,
            30,
            60,
            90,
            120
          ],
          "type": "number",
          "description": "Store, for a game that costs money and plays in the browser: a free trial in minutes, once for each player who doesn't own it (0: none; a new game left without one gets 30)."
        },
        "access": {
          "type": "array",
          "items": {
            "enum": [
              "Subtitles",
              "Captions for sounds",
              "Adjustable text size",
              "Colour-blind options",
              "High contrast",
              "Remappable controls",
              "One-handed play",
              "No timed inputs needed",
              "Adjustable difficulty",
              "Save anytime",
              "Separate volume controls",
              "Narrated menus",
              "Camera comfort options",
              "Mouse only",
              "Keyboard only",
              "Touch only"
            ],
            "type": "string"
          },
          "description": "What it does for players with a disability."
        },
        "copies": {
          "type": "object",
          "description": "The pictures' smaller copies, by each picture's address (made by Player Two).",
          "propertyNames": {
            "type": "string"
          },
          "additionalProperties": {
            "type": "object",
            "required": [
              "w",
              "at"
            ],
            "properties": {
              "w": {
                "type": "number"
              },
              "at": {
                "type": "array",
                "items": {
                  "type": "object",
                  "required": [
                    "w",
                    "src"
                  ],
                  "properties": {
                    "w": {
                      "type": "number"
                    },
                    "src": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "follow": {
          "type": "boolean",
          "description": "With playUrl (on for a new game unless false): Player Two serves the site from https://<slug>.playertwo.cc, so saves follow players and the SDK is in its pages."
        },
        "genres": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Up to 10, the main ones first (a game shows its first four), each up to 24 characters. The store's: Action, Adventure, Arcade, Arena, Casual, Co-op, Fighting, Horror, Multiplayer, Platformer, Puzzle, Racing, Roguelite, RPG, Shooter, Simulation, Social, Sports, Strategy, Survival."
        },
        "poster": {
          "type": "string",
          "description": "An older listing's main poster (16:9): its wide picture beside key art; new key art takes the place of both posters."
        },
        "stages": {
          "type": "array",
          "items": {
            "type": "object",
            "required": [
              "title"
            ],
            "properties": {
              "days": {
                "type": "number",
                "description": "Due this many days after the raise is funded."
              },
              "proof": {
                "type": "string",
                "maxLength": 240,
                "description": "What backers will see. Up to 240 characters; longer is cut."
              },
              "share": {
                "type": "number",
                "description": "Its share of the raise, 0 to 1; all add up to 1."
              },
              "title": {
                "type": "string",
                "maxLength": 60,
                "description": "The stage. Up to 60 characters; longer is cut."
              }
            }
          },
          "description": "Raise: 1 to 8 stages."
        },
        "stills": {
          "type": "object",
          "description": "A still of each feature's video (made by Player Two).",
          "propertyNames": {
            "type": "string"
          },
          "additionalProperties": {
            "type": "string"
          }
        },
        "studio": {
          "type": "string",
          "maxLength": 40,
          "description": "The studio's name, required. Up to 40 characters; longer is cut."
        },
        "videos": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Up to 4 gameplay videos from upload_media, after the trailer, in this order."
        },
        "backers": {
          "enum": [
            "share",
            "rewards"
          ],
          "type": "string",
          "description": "Raise: what backers get, a share of every sale or rewards only."
        },
        "content": {
          "type": "array",
          "items": {
            "enum": [
              "Violence",
              "Blood and gore",
              "Sexual content",
              "Nudity",
              "Strong language",
              "Drugs, alcohol or tobacco",
              "Gambling-style play",
              "Frightening scenes",
              "Talking with strangers online"
            ],
            "type": "string"
          },
          "description": "What it shows, for players and parents."
        },
        "discord": {
          "type": "string",
          "description": "Discord invite."
        },
        "playUrl": {
          "type": "string",
          "description": "The https address where the game is played on its own site."
        },
        "rewards": {
          "type": "array",
          "items": {
            "type": "object",
            "required": [
              "min",
              "title"
            ],
            "properties": {
              "min": {
                "type": "number"
              },
              "body": {
                "type": "string",
                "maxLength": 240,
                "description": "A line more. Up to 240 characters; longer is cut."
              },
              "title": {
                "type": "string",
                "maxLength": 60,
                "description": "What they get. Up to 60 characters; longer is cut."
              }
            }
          },
          "description": "Raise with backers \"rewards\": up to 8, by the least put in for each."
        },
        "spacing": {
          "type": "string",
          "maxLength": 10,
          "description": "Letter spacing, as CSS. Up to 10 characters; longer is cut."
        },
        "tagline": {
          "type": "string",
          "maxLength": 90,
          "description": "One line about it. Up to 90 characters; longer is cut."
        },
        "youtube": {
          "type": "string",
          "description": "YouTube channel."
        },
        "branches": {
          "type": "array",
          "items": {
            "type": "object",
            "required": [
              "name",
              "goals"
            ],
            "properties": {
              "name": {
                "type": "string",
                "maxLength": 30,
                "description": "A branch of work. Up to 30 characters; longer is cut."
              },
              "goals": {
                "type": "array",
                "items": {
                  "type": "object",
                  "required": [
                    "title"
                  ],
                  "properties": {
                    "now": {
                      "type": "string"
                    },
                    "cost": {
                      "type": "number"
                    },
                    "next": {
                      "type": "string"
                    },
                    "shot": {
                      "type": "number"
                    },
                    "stage": {
                      "type": "number"
                    },
                    "title": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "description": "Raise: what the money builds, up to 4 branches of up to 3 goals."
        },
        "features": {
          "type": "array",
          "items": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 90,
                "description": "A feature with neither picture nor video: words on the page, in the game's colour. Up to 90 characters; longer is cut."
              },
              {
                "type": "object",
                "properties": {
                  "art": {
                    "type": "string",
                    "description": "A picture's address from upload_media, shown wide (16:9)."
                  },
                  "clip": {
                    "type": "string",
                    "description": "Or a video's address from upload_media (a picture wins when both are given)."
                  },
                  "text": {
                    "type": "string",
                    "maxLength": 90,
                    "description": "The feature, in a line. Up to 90 characters; longer is cut."
                  }
                }
              }
            ]
          },
          "description": "Store: up to 6."
        },
        "postBody": {
          "type": "string",
          "maxLength": 600,
          "description": "The first post. Up to 600 characters; longer is cut."
        },
        "languages": {
          "type": "array",
          "items": {
            "type": "object",
            "required": [
              "lang"
            ],
            "properties": {
              "ui": {
                "type": "boolean"
              },
              "lang": {
                "enum": [
                  "English",
                  "Spanish",
                  "Spanish (Latin America)",
                  "Portuguese (Brazil)",
                  "Portuguese",
                  "French",
                  "German",
                  "Italian",
                  "Dutch",
                  "Polish",
                  "Russian",
                  "Ukrainian",
                  "Turkish",
                  "Arabic",
                  "Hebrew",
                  "Hindi",
                  "Bengali",
                  "Thai",
                  "Vietnamese",
                  "Indonesian",
                  "Malay",
                  "Filipino",
                  "Japanese",
                  "Korean",
                  "Chinese (Simplified)",
                  "Chinese (Traditional)",
                  "Swedish",
                  "Norwegian",
                  "Danish",
                  "Finnish",
                  "Czech",
                  "Slovak",
                  "Hungarian",
                  "Romanian",
                  "Bulgarian",
                  "Greek",
                  "Persian"
                ],
                "type": "string"
              },
              "subs": {
                "type": "boolean"
              },
              "audio": {
                "type": "boolean"
              }
            }
          },
          "description": "The languages it comes in: its words on screen (ui), voices (audio), subtitles (subs)."
        },
        "minTicket": {
          "type": "number",
          "description": "Raise: the smallest stake, dollars."
        },
        "platforms": {
          "type": "array",
          "items": {
            "enum": [
              "Browser",
              "Windows",
              "Mac",
              "Linux",
              "Mobile"
            ],
            "type": "string"
          },
          "description": "Where it plays."
        },
        "postTitle": {
          "type": "string",
          "maxLength": 80,
          "description": "The first post's title. Up to 80 characters; longer is cut."
        },
        "qualifier": {
          "type": "string",
          "maxLength": 40,
          "description": "A short note after the tagline, like \"an unofficial fan game\". Up to 40 characters; longer is cut."
        },
        "todayLine": {
          "type": "string",
          "maxLength": 90,
          "description": "Raise: where it is today, in a line. Up to 90 characters; longer is cut."
        },
        "agentNotes": {
          "type": "object",
          "properties": {
            "goals": {
              "type": "string",
              "maxLength": 400,
              "description": "What a player is trying to do, and how a run or a round ends. Up to 400 characters; longer is cut."
            },
            "controls": {
              "type": "string",
              "maxLength": 400,
              "description": "The controls: keys, mouse, touch or gamepad, and what each does. Up to 400 characters; longer is cut."
            }
          },
          "description": "How to play, in the developer's words: shown to agents reading the game's page (a hidden section), never to players."
        },
        "clipCopies": {
          "type": "object",
          "description": "The trailer's lighter copies (made by Player Two).",
          "propertyNames": {
            "type": "string"
          },
          "additionalProperties": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "h",
                "src"
              ],
              "properties": {
                "h": {
                  "type": "number"
                },
                "src": {
                  "type": "string"
                }
              }
            }
          }
        },
        "controller": {
          "enum": [
            "full",
            "partial",
            ""
          ],
          "type": "string",
          "description": "\"full\": it all plays with a gamepad. \"partial\": some of it needs a keyboard or mouse."
        },
        "multiplayer": {
          "enum": [
            "rooms",
            "none",
            "own"
          ],
          "type": "string",
          "description": "For a game hosted on Player Two: Player Two's rooms through p2.rooms (the default), single-player, or its own servers."
        },
        "orientation": {
          "enum": [
            "landscape",
            "portrait",
            ""
          ],
          "type": "string",
          "description": "Which way a phone is held to play it: \"landscape\" (sideways) or \"portrait\" (upright); \"\" either way. A landscape game's card on X plays it sideways on a phone held upright, as X's app doesn't turn."
        },
        "plannedPrice": {
          "type": "number",
          "description": "Raise: the price it will sell at, dollars."
        },
        "requirements": {
          "type": "object",
          "properties": {
            "min": {
              "type": "object",
              "properties": {
                "os": {
                  "type": "string",
                  "maxLength": 80,
                  "description": "Operating system. Up to 80 characters; longer is cut."
                },
                "cpu": {
                  "type": "string",
                  "maxLength": 80,
                  "description": "Processor. Up to 80 characters; longer is cut."
                },
                "gpu": {
                  "type": "string",
                  "maxLength": 80,
                  "description": "Graphics. Up to 80 characters; longer is cut."
                },
                "ram": {
                  "type": "string",
                  "maxLength": 80,
                  "description": "Memory. Up to 80 characters; longer is cut."
                },
                "notes": {
                  "type": "string",
                  "maxLength": 200,
                  "description": "Anything else. Up to 200 characters; longer is cut."
                },
                "storage": {
                  "type": "string",
                  "maxLength": 80,
                  "description": "Disk space. Up to 80 characters; longer is cut."
                }
              }
            },
            "rec": {
              "type": "object",
              "properties": {
                "os": {
                  "type": "string",
                  "maxLength": 80,
                  "description": "Operating system. Up to 80 characters; longer is cut."
                },
                "cpu": {
                  "type": "string",
                  "maxLength": 80,
                  "description": "Processor. Up to 80 characters; longer is cut."
                },
                "gpu": {
                  "type": "string",
                  "maxLength": 80,
                  "description": "Graphics. Up to 80 characters; longer is cut."
                },
                "ram": {
                  "type": "string",
                  "maxLength": 80,
                  "description": "Memory. Up to 80 characters; longer is cut."
                },
                "notes": {
                  "type": "string",
                  "maxLength": 200,
                  "description": "Anything else. Up to 200 characters; longer is cut."
                },
                "storage": {
                  "type": "string",
                  "maxLength": 80,
                  "description": "Disk space. Up to 80 characters; longer is cut."
                }
              }
            }
          },
          "description": "What a computer needs for its downloads: the least, and what plays it best."
        }
      },
      "additionalProperties": {}
    },
    "publish": {
      "type": "boolean",
      "default": true,
      "description": "false keeps it as a draft in the studio; default true."
    },
    "release": {
      "type": "object",
      "properties": {
        "at": {
          "type": [
            "number",
            "string"
          ],
          "description": "With date: when it comes out, in milliseconds or as an ISO time, up to 365 days ahead (a time already past is now). A game with its day set: the day moved."
        },
        "stand": {
          "enum": [
            "out",
            "private",
            "date"
          ],
          "type": "string",
          "description": "out: listed and playable now (the default). private: its page and its play only for its team, its testers and Player Two's admins, and in no list. date: in the lists with its day and Wishlist in place of Play, played only by its team and testers until then; then out by itself, its wishlisters told. A store game only (a raise opens on its own day); once out, it stays out."
        }
      },
      "description": "How it is listed: out now (the default), kept private, or coming on a day."
    }
  }
}
submit_game annotations
{
  "readOnlyHint": false,
  "openWorldHint": true,
  "idempotentHint": false,
  "destructiveHint": false
}
update_game — Change a game's page
Advertised by the server during the last successful anonymous check.
Advertised destructiveOpen-world

Change one of the player's games: only the fields given change. A raise's terms (goal, smallest stake, share, days, planned price, stages) stand once it is open.

update_game input schema
{
  "type": "object",
  "required": [
    "slug",
    "draft"
  ],
  "properties": {
    "slug": {
      "type": "string",
      "description": "The game's address on Player Two (playertwo.lol/game/<slug>)."
    },
    "draft": {
      "type": "object",
      "properties": {
        "v": {
          "type": "number",
          "const": 1
        },
        "x": {
          "type": "string",
          "description": "X handle or link."
        },
        "age": {
          "enum": [
            "13",
            "16",
            "18",
            "all",
            ""
          ],
          "type": "string",
          "description": "Who it is for. Sexual content or nudity in content makes it 18 whatever is given."
        },
        "art": {
          "type": "string",
          "description": "The key art from upload_media, required: square, 2400 by 2400 at best, no title on it. The game's card (its middle two-thirds), its page's first screen in 3D and its wide picture in the store."
        },
        "sub": {
          "type": "string",
          "maxLength": 28,
          "description": "A line under the name. Up to 28 characters; longer is cut."
        },
        "why": {
          "type": "string",
          "maxLength": 300,
          "description": "Raise: why back it. Up to 300 characters; longer is cut."
        },
        "base": {
          "type": "string",
          "maxLength": 40,
          "description": "What it is, like \"Independent studio\". Up to 40 characters; longer is cut."
        },
        "clip": {
          "type": "string",
          "description": "The launch trailer from upload_media, required (MP4 or WebM)."
        },
        "days": {
          "type": "number",
          "maximum": 120,
          "minimum": 3,
          "description": "Raise: how long it is open."
        },
        "demo": {
          "type": "boolean",
          "description": "Store: this is a free demo, not the finished game."
        },
        "face": {
          "type": "object",
          "required": [
            "from",
            "family",
            "weight",
            "italic",
            "files"
          ],
          "properties": {
            "from": {
              "enum": [
                "google",
                "own"
              ],
              "type": "string"
            },
            "files": {
              "type": "array",
              "items": {
                "type": "object",
                "required": [
                  "src"
                ],
                "properties": {
                  "src": {
                    "type": "string"
                  },
                  "range": {
                    "type": "string"
                  }
                },
                "additionalProperties": {}
              }
            },
            "family": {
              "type": "string"
            },
            "italic": {
              "type": "boolean"
            },
            "weight": {
              "type": "number"
            }
          },
          "description": "The typeface the name is lettered in, as Player Two keeps it (made from font).",
          "additionalProperties": {}
        },
        "font": {
          "anyOf": [
            {
              "type": "string",
              "description": "A template (anton, bungee, bangers, cinzel, syncopate, kanit, pixel, archivo, chakra), or a font's address from upload_media."
            },
            {
              "type": "object",
              "required": [
                "google"
              ],
              "properties": {
                "google": {
                  "type": "string"
                },
                "italic": {
                  "type": "boolean"
                },
                "weight": {
                  "type": "number"
                }
              },
              "description": "A Google Fonts family at one of its weights: its files are kept in Player Two's own store."
            }
          ],
          "description": "How the name is lettered."
        },
        "glow": {
          "type": "string",
          "pattern": "^#[0-9a-fA-F]{6}$",
          "description": "The game's colour, #rrggbb."
        },
        "goal": {
          "type": "number",
          "maximum": 10000000,
          "minimum": 1,
          "description": "Raise: dollars asked."
        },
        "kind": {
          "enum": [
            "store",
            "raise"
          ],
          "type": "string",
          "description": "\"store\": sold (or free) and played or downloaded from its page. \"raise\": players back a game being made. Default raise."
        },
        "more": {
          "type": "string",
          "maxLength": 700,
          "description": "A second paragraph. Up to 700 characters; longer is cut."
        },
        "name": {
          "type": "string",
          "maxLength": 28,
          "description": "The name as lettered on the card (uppercase); the title when empty. Up to 28 characters; longer is cut."
        },
        "note": {
          "type": "string",
          "maxLength": 900,
          "description": "A note to players. Up to 900 characters; longer is cut."
        },
        "sign": {
          "type": "string",
          "maxLength": 40,
          "description": "How it signs off. Up to 40 characters; longer is cut."
        },
        "site": {
          "type": "string",
          "description": "Its website."
        },
        "size": {
          "type": "number",
          "description": "The lettering's size, 0.5 to 1.6."
        },
        "tall": {
          "type": "string",
          "description": "An older listing's vertical poster (2:3): its card while it has no key art."
        },
        "build": {
          "type": "string",
          "description": "The address upload_web_build returned: a web build Player Two keeps, played at https://<slug>.playertwo.cc."
        },
        "depth": {
          "type": "string",
          "description": "The key art's depth map, made by Player Two."
        },
        "modes": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Up to 10 short words (Duel, Co-op...), the main ones first."
        },
        "opens": {
          "type": "number",
          "description": "Raise: when it opens to backers (milliseconds since 1970), up to 60 days ahead."
        },
        "pitch": {
          "type": "string",
          "maxLength": 700,
          "description": "What it is, in a paragraph. Up to 700 characters; longer is cut."
        },
        "price": {
          "type": "number",
          "maximum": 500,
          "minimum": 0,
          "description": "Store: dollars, 0 is free."
        },
        "share": {
          "type": "number",
          "maximum": 0.85,
          "minimum": 0.4,
          "description": "Raise with backers \"share\": the backers' share of every sale."
        },
        "shots": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Up to 8 screenshots from upload_media."
        },
        "sound": {
          "type": "boolean",
          "description": "Whether the trailer's sound may play."
        },
        "title": {
          "type": "string",
          "maxLength": 60,
          "description": "The game's name. Up to 60 characters; longer is cut."
        },
        "today": {
          "enum": [
            "concept",
            "prototype",
            "demo",
            "early"
          ],
          "type": "string",
          "description": "Raise: where the game is today."
        },
        "trial": {
          "enum": [
            0,
            15,
            30,
            60,
            90,
            120
          ],
          "type": "number",
          "description": "Store, for a game that costs money and plays in the browser: a free trial in minutes, once for each player who doesn't own it (0: none; a new game left without one gets 30)."
        },
        "access": {
          "type": "array",
          "items": {
            "enum": [
              "Subtitles",
              "Captions for sounds",
              "Adjustable text size",
              "Colour-blind options",
              "High contrast",
              "Remappable controls",
              "One-handed play",
              "No timed inputs needed",
              "Adjustable difficulty",
              "Save anytime",
              "Separate volume controls",
              "Narrated menus",
              "Camera comfort options",
              "Mouse only",
              "Keyboard only",
              "Touch only"
            ],
            "type": "string"
          },
          "description": "What it does for players with a disability."
        },
        "copies": {
          "type": "object",
          "description": "The pictures' smaller copies, by each picture's address (made by Player Two).",
          "propertyNames": {
            "type": "string"
          },
          "additionalProperties": {
            "type": "object",
            "required": [
              "w",
              "at"
            ],
            "properties": {
              "w": {
                "type": "number"
              },
              "at": {
                "type": "array",
                "items": {
                  "type": "object",
                  "required": [
                    "w",
                    "src"
                  ],
                  "properties": {
                    "w": {
                      "type": "number"
                    },
                    "src": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "follow": {
          "type": "boolean",
          "description": "With playUrl (on for a new game unless false): Player Two serves the site from https://<slug>.playertwo.cc, so saves follow players and the SDK is in its pages."
        },
        "genres": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Up to 10, the main ones first (a game shows its first four), each up to 24 characters. The store's: Action, Adventure, Arcade, Arena, Casual, Co-op, Fighting, Horror, Multiplayer, Platformer, Puzzle, Racing, Roguelite, RPG, Shooter, Simulation, Social, Sports, Strategy, Survival."
        },
        "poster": {
          "type": "string",
          "description": "An older listing's main poster (16:9): its wide picture beside key art; new key art takes the place of both posters."
        },
        "stages": {
          "type": "array",
          "items": {
            "type": "object",
            "required": [
              "title"
            ],
            "properties": {
              "days": {
                "type": "number",
                "description": "Due this many days after the raise is funded."
              },
              "proof": {
                "type": "string",
                "maxLength": 240,
                "description": "What backers will see. Up to 240 characters; longer is cut."
              },
              "share": {
                "type": "number",
                "description": "Its share of the raise, 0 to 1; all add up to 1."
              },
              "title": {
                "type": "string",
                "maxLength": 60,
                "description": "The stage. Up to 60 characters; longer is cut."
              }
            }
          },
          "description": "Raise: 1 to 8 stages."
        },
        "stills": {
          "type": "object",
          "description": "A still of each feature's video (made by Player Two).",
          "propertyNames": {
            "type": "string"
          },
          "additionalProperties": {
            "type": "string"
          }
        },
        "studio": {
          "type": "string",
          "maxLength": 40,
          "description": "The studio's name, required. Up to 40 characters; longer is cut."
        },
        "videos": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Up to 4 gameplay videos from upload_media, after the trailer, in this order."
        },
        "backers": {
          "enum": [
            "share",
            "rewards"
          ],
          "type": "string",
          "description": "Raise: what backers get, a share of every sale or rewards only."
        },
        "content": {
          "type": "array",
          "items": {
            "enum": [
              "Violence",
              "Blood and gore",
              "Sexual content",
              "Nudity",
              "Strong language",
              "Drugs, alcohol or tobacco",
              "Gambling-style play",
              "Frightening scenes",
              "Talking with strangers online"
            ],
            "type": "string"
          },
          "description": "What it shows, for players and parents."
        },
        "discord": {
          "type": "string",
          "description": "Discord invite."
        },
        "playUrl": {
          "type": "string",
          "description": "The https address where the game is played on its own site."
        },
        "rewards": {
          "type": "array",
          "items": {
            "type": "object",
            "required": [
              "min",
              "title"
            ],
            "properties": {
              "min": {
                "type": "number"
              },
              "body": {
                "type": "string",
                "maxLength": 240,
                "description": "A line more. Up to 240 characters; longer is cut."
              },
              "title": {
                "type": "string",
                "maxLength": 60,
                "description": "What they get. Up to 60 characters; longer is cut."
              }
            }
          },
          "description": "Raise with backers \"rewards\": up to 8, by the least put in for each."
        },
        "spacing": {
          "type": "string",
          "maxLength": 10,
          "description": "Letter spacing, as CSS. Up to 10 characters; longer is cut."
        },
        "tagline": {
          "type": "string",
          "maxLength": 90,
          "description": "One line about it. Up to 90 characters; longer is cut."
        },
        "youtube": {
          "type": "string",
          "description": "YouTube channel."
        },
        "branches": {
          "type": "array",
          "items": {
            "type": "object",
            "required": [
              "name",
              "goals"
            ],
            "properties": {
              "name": {
                "type": "string",
                "maxLength": 30,
                "description": "A branch of work. Up to 30 characters; longer is cut."
              },
              "goals": {
                "type": "array",
                "items": {
                  "type": "object",
                  "required": [
                    "title"
                  ],
                  "properties": {
                    "now": {
                      "type": "string"
                    },
                    "cost": {
                      "type": "number"
                    },
                    "next": {
                      "type": "string"
                    },
                    "shot": {
                      "type": "number"
                    },
                    "stage": {
                      "type": "number"
                    },
                    "title": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "description": "Raise: what the money builds, up to 4 branches of up to 3 goals."
        },
        "features": {
          "type": "array",
          "items": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 90,
                "description": "A feature with neither picture nor video: words on the page, in the game's colour. Up to 90 characters; longer is cut."
              },
              {
                "type": "object",
                "properties": {
                  "art": {
                    "type": "string",
                    "description": "A picture's address from upload_media, shown wide (16:9)."
                  },
                  "clip": {
                    "type": "string",
                    "description": "Or a video's address from upload_media (a picture wins when both are given)."
                  },
                  "text": {
                    "type": "string",
                    "maxLength": 90,
                    "description": "The feature, in a line. Up to 90 characters; longer is cut."
                  }
                }
              }
            ]
          },
          "description": "Store: up to 6."
        },
        "postBody": {
          "type": "string",
          "maxLength": 600,
          "description": "The first post. Up to 600 characters; longer is cut."
        },
        "languages": {
          "type": "array",
          "items": {
            "type": "object",
            "required": [
              "lang"
            ],
            "properties": {
              "ui": {
                "type": "boolean"
              },
              "lang": {
                "enum": [
                  "English",
                  "Spanish",
                  "Spanish (Latin America)",
                  "Portuguese (Brazil)",
                  "Portuguese",
                  "French",
                  "German",
                  "Italian",
                  "Dutch",
                  "Polish",
                  "Russian",
                  "Ukrainian",
                  "Turkish",
                  "Arabic",
                  "Hebrew",
                  "Hindi",
                  "Bengali",
                  "Thai",
                  "Vietnamese",
                  "Indonesian",
                  "Malay",
                  "Filipino",
                  "Japanese",
                  "Korean",
                  "Chinese (Simplified)",
                  "Chinese (Traditional)",
                  "Swedish",
                  "Norwegian",
                  "Danish",
                  "Finnish",
                  "Czech",
                  "Slovak",
                  "Hungarian",
                  "Romanian",
                  "Bulgarian",
                  "Greek",
                  "Persian"
                ],
                "type": "string"
              },
              "subs": {
                "type": "boolean"
              },
              "audio": {
                "type": "boolean"
              }
            }
          },
          "description": "The languages it comes in: its words on screen (ui), voices (audio), subtitles (subs)."
        },
        "minTicket": {
          "type": "number",
          "description": "Raise: the smallest stake, dollars."
        },
        "platforms": {
          "type": "array",
          "items": {
            "enum": [
              "Browser",
              "Windows",
              "Mac",
              "Linux",
              "Mobile"
            ],
            "type": "string"
          },
          "description": "Where it plays."
        },
        "postTitle": {
          "type": "string",
          "maxLength": 80,
          "description": "The first post's title. Up to 80 characters; longer is cut."
        },
        "qualifier": {
          "type": "string",
          "maxLength": 40,
          "description": "A short note after the tagline, like \"an unofficial fan game\". Up to 40 characters; longer is cut."
        },
        "todayLine": {
          "type": "string",
          "maxLength": 90,
          "description": "Raise: where it is today, in a line. Up to 90 characters; longer is cut."
        },
        "agentNotes": {
          "type": "object",
          "properties": {
            "goals": {
              "type": "string",
              "maxLength": 400,
              "description": "What a player is trying to do, and how a run or a round ends. Up to 400 characters; longer is cut."
            },
            "controls": {
              "type": "string",
              "maxLength": 400,
              "description": "The controls: keys, mouse, touch or gamepad, and what each does. Up to 400 characters; longer is cut."
            }
          },
          "description": "How to play, in the developer's words: shown to agents reading the game's page (a hidden section), never to players."
        },
        "clipCopies": {
          "type": "object",
          "description": "The trailer's lighter copies (made by Player Two).",
          "propertyNames": {
            "type": "string"
          },
          "additionalProperties": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "h",
                "src"
              ],
              "properties": {
                "h": {
                  "type": "number"
                },
                "src": {
                  "type": "string"
                }
              }
            }
          }
        },
        "controller": {
          "enum": [
            "full",
            "partial",
            ""
          ],
          "type": "string",
          "description": "\"full\": it all plays with a gamepad. \"partial\": some of it needs a keyboard or mouse."
        },
        "multiplayer": {
          "enum": [
            "rooms",
            "none",
            "own"
          ],
          "type": "string",
          "description": "For a game hosted on Player Two: Player Two's rooms through p2.rooms (the default), single-player, or its own servers."
        },
        "orientation": {
          "enum": [
            "landscape",
            "portrait",
            ""
          ],
          "type": "string",
          "description": "Which way a phone is held to play it: \"landscape\" (sideways) or \"portrait\" (upright); \"\" either way. A landscape game's card on X plays it sideways on a phone held upright, as X's app doesn't turn."
        },
        "plannedPrice": {
          "type": "number",
          "description": "Raise: the price it will sell at, dollars."
        },
        "requirements": {
          "type": "object",
          "properties": {
            "min": {
              "type": "object",
              "properties": {
                "os": {
                  "type": "string",
                  "maxLength": 80,
                  "description": "Operating system. Up to 80 characters; longer is cut."
                },
                "cpu": {
                  "type": "string",
                  "maxLength": 80,
                  "description": "Processor. Up to 80 characters; longer is cut."
                },
                "gpu": {
                  "type": "string",
                  "maxLength": 80,
                  "description": "Graphics. Up to 80 characters; longer is cut."
                },
                "ram": {
                  "type": "string",
                  "maxLength": 80,
                  "description": "Memory. Up to 80 characters; longer is cut."
                },
                "notes": {
                  "type": "string",
                  "maxLength": 200,
                  "description": "Anything else. Up to 200 characters; longer is cut."
                },
                "storage": {
                  "type": "string",
                  "maxLength": 80,
                  "description": "Disk space. Up to 80 characters; longer is cut."
                }
              }
            },
            "rec": {
              "type": "object",
              "properties": {
                "os": {
                  "type": "string",
                  "maxLength": 80,
                  "description": "Operating system. Up to 80 characters; longer is cut."
                },
                "cpu": {
                  "type": "string",
                  "maxLength": 80,
                  "description": "Processor. Up to 80 characters; longer is cut."
                },
                "gpu": {
                  "type": "string",
                  "maxLength": 80,
                  "description": "Graphics. Up to 80 characters; longer is cut."
                },
                "ram": {
                  "type": "string",
                  "maxLength": 80,
                  "description": "Memory. Up to 80 characters; longer is cut."
                },
                "notes": {
                  "type": "string",
                  "maxLength": 200,
                  "description": "Anything else. Up to 200 characters; longer is cut."
                },
                "storage": {
                  "type": "string",
                  "maxLength": 80,
                  "description": "Disk space. Up to 80 characters; longer is cut."
                }
              }
            }
          },
          "description": "What a computer needs for its downloads: the least, and what plays it best."
        }
      },
      "additionalProperties": {}
    }
  }
}
update_game annotations
{
  "readOnlyHint": false,
  "openWorldHint": true,
  "idempotentHint": true,
  "destructiveHint": true
}
get_game — Read one of the player's games
Advertised by the server during the last successful anonymous check.
Advertised read-only

One of the player's games as stored (drafts too), with its raise if it has one.

get_game input schema
{
  "type": "object",
  "required": [
    "slug"
  ],
  "properties": {
    "slug": {
      "type": "string",
      "description": "The game's address on Player Two (playertwo.lol/game/<slug>)."
    }
  }
}
get_game annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
list_trophies — A game's trophies
Advertised by the server during the last successful anonymous check.
Advertised read-only

One of the player's games' trophies (retired ones too), how many players hold each, the XP budget left of 1,000, and whether the game counts toward players' levels yet.

list_trophies input schema
{
  "type": "object",
  "required": [
    "slug"
  ],
  "properties": {
    "slug": {
      "type": "string",
      "description": "The game's address on Player Two (playertwo.lol/game/<slug>)."
    }
  }
}
list_trophies annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
define_trophy — Add or change a trophy
Advertised by the server during the last successful anonymous check.
Advertised destructiveOpen-world

Add a trophy to one of the player's hosted games, or change one by its key. Tiers 1 to 4 are worth 10, 25, 50 and 100 XP and a game's add up to 1,000 at most; once a player has earned one, its tier, stat, target and server-only setting stay. Every trophy is a relic, a small sculpture of cubes built from its sign: rows from the top on a grid of up to 16 by 16, # a cube and . none ("..#../.###./#####"), or a library sign's name (crown, rocket, gem, pad, bell, lantern, flag, fist, star, bolt, key, sword, shield, heart, moon, flame, hourglass, anchor, tower, joystick, gift); without one Player Two picks one by its key. The completion trophy (key "complete") is a crown until it is given the game's own sign: send key "complete" with a sign alone. The game earns a trophy with the SDK's trophies.unlock(key).

define_trophy input schema
{
  "type": "object",
  "required": [
    "slug",
    "trophy"
  ],
  "properties": {
    "slug": {
      "type": "string",
      "description": "The game's address on Player Two (playertwo.lol/game/<slug>)."
    },
    "trophy": {
      "type": "object",
      "required": [
        "key"
      ],
      "properties": {
        "art": {
          "type": "string",
          "maxLength": 600,
          "description": "A picture from upload_media."
        },
        "how": {
          "type": "string",
          "maxLength": 120,
          "description": "How to earn it, up to 120 characters."
        },
        "key": {
          "type": "string",
          "maxLength": 60,
          "description": "a-z, 0-9 and dashes, up to 40: what the game's code earns it by. \"complete\" is the completion trophy."
        },
        "name": {
          "type": "string",
          "default": "",
          "maxLength": 40,
          "description": "Up to 40 characters."
        },
        "sign": {
          "anyOf": [
            {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 600
                },
                {
                  "type": "array",
                  "items": {
                    "type": "string",
                    "maxLength": 64
                  },
                  "maxItems": 40
                }
              ]
            },
            {
              "type": "null"
            }
          ],
          "description": "The small picture its relic (a sculpture of cubes) is built from: rows of # (a cube) and . (none) from the top, up to 16 by 16, as one string separated by / or a list of rows; or a library sign's name (crown, rocket, gem, pad, bell, lantern, flag, fist, star, bolt, key, sword, shield, heart, moon, flame, hourglass, anchor, tower, joystick, gift). Left out, it keeps its sign; empty, Player Two picks one by its key."
        },
        "stat": {
          "anyOf": [
            {
              "type": "string",
              "maxLength": 60
            },
            {
              "type": "null"
            }
          ],
          "description": "Earned by itself when this stat reaches target."
        },
        "tier": {
          "type": "integer",
          "default": 0,
          "maximum": 4,
          "minimum": 1,
          "description": "1 to 4, worth 10, 25, 50 and 100 XP; a game's trophies add up to 1,000 XP at most."
        },
        "hidden": {
          "type": "boolean",
          "description": "Show only that there is one until it is earned."
        },
        "target": {
          "type": [
            "number",
            "null"
          ],
          "description": "A whole number, 1 or more."
        },
        "serverOnly": {
          "type": "boolean",
          "description": "Only the game's own server can give it, with a game key."
        }
      }
    }
  }
}
define_trophy annotations
{
  "readOnlyHint": false,
  "openWorldHint": true,
  "idempotentHint": true,
  "destructiveHint": true
}
list_boards — A game's leaderboards
Advertised by the server during the last successful anonymous check.
Advertised read-only

One of the player's games' leaderboards, with how many players are on each.

list_boards input schema
{
  "type": "object",
  "required": [
    "slug"
  ],
  "properties": {
    "slug": {
      "type": "string",
      "description": "The game's address on Player Two (playertwo.lol/game/<slug>)."
    }
  }
}
list_boards annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
define_board — Add or change a leaderboard
Advertised by the server during the last successful anonymous check.
Advertised destructiveOpen-world

Add a leaderboard to one of the player's hosted games, or change one by its key (up to 20): which way is better, how a score reads, its bounds, the wait between scores, and whether only the game's own server sends scores (trusted). The game fills it with the SDK's scores.submit(key, value).

define_board input schema
{
  "type": "object",
  "required": [
    "slug",
    "board"
  ],
  "properties": {
    "slug": {
      "type": "string",
      "description": "The game's address on Player Two (playertwo.lol/game/<slug>)."
    },
    "board": {
      "type": "object",
      "required": [
        "key",
        "name"
      ],
      "properties": {
        "key": {
          "type": "string",
          "maxLength": 60,
          "description": "a-z, 0-9 and dashes, up to 40: what the game's code fills it by."
        },
        "max": {
          "type": [
            "number",
            "null"
          ],
          "description": "The highest score it takes."
        },
        "min": {
          "type": [
            "number",
            "null"
          ],
          "description": "The lowest score it takes."
        },
        "name": {
          "type": "string",
          "maxLength": 40,
          "description": "Up to 40 characters."
        },
        "order": {
          "enum": [
            "high",
            "low"
          ],
          "type": "string",
          "description": "Which way is better."
        },
        "format": {
          "enum": [
            "number",
            "time",
            "points"
          ],
          "type": "string",
          "description": "How a score reads: a number, a time in milliseconds, or points."
        },
        "trusted": {
          "type": "boolean",
          "description": "Only the game's own server sends its scores."
        },
        "cooldown": {
          "type": "number",
          "maximum": 86400,
          "minimum": 0,
          "description": "Seconds a player waits between scores."
        }
      }
    }
  }
}
define_board annotations
{
  "readOnlyHint": false,
  "openWorldHint": true,
  "idempotentHint": true,
  "destructiveHint": true
}
list_builds — A web game's builds
Advertised by the server during the last successful anonymous check.
Advertised read-only

One of the player's web games' builds that are still kept (30 days after another took its place, and the last 20 always), newest first: each one's version (its developer's, or its number in the game's builds), which is live, who sent each (the player, or which agent key), its size, its files against the build before, its commit and note, the players on it now and where to try it without making it live; and the game's latest changes of build.

list_builds input schema
{
  "type": "object",
  "required": [
    "slug"
  ],
  "properties": {
    "slug": {
      "type": "string",
      "description": "The game's address on Player Two (playertwo.lol/game/<slug>)."
    }
  }
}
list_builds annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
make_build_live — Roll back (or forward) to a build
Advertised by the server during the last successful anonymous check.
Advertised destructiveOpen-world

Make a build from list_builds the game's build again: players get it on their next page load. The build live now stays kept, so this can be undone the same way. Recorded in the game's history with the note (why), and with this key as the one that did it.

make_build_live input schema
{
  "type": "object",
  "required": [
    "slug",
    "key"
  ],
  "properties": {
    "key": {
      "type": "string",
      "maxLength": 40,
      "description": "The build's key, from the game's list of builds."
    },
    "note": {
      "type": "string",
      "maxLength": 1000,
      "description": "Why, kept with the change in the game's history of builds."
    },
    "slug": {
      "type": "string",
      "description": "The game's address on Player Two (playertwo.lol/game/<slug>)."
    }
  }
}
make_build_live annotations
{
  "readOnlyHint": false,
  "openWorldHint": true,
  "idempotentHint": true,
  "destructiveHint": true
}
name_build — Name a build's version
Advertised by the server during the last successful anonymous check.

Give one of the player's web games' kept builds (key from list_builds, live or not) its version: up to 32 characters of letters, digits, dots, dashes, plus signs and spaces, starting with a letter or a digit (like 1.4.0 or 2.0 beta). Shown wherever its builds are from then on; nobody is told. A push names a build as it goes up (p2 push --version); this is for one that came without (a GitHub commit's, called by its number) or a correction.

name_build input schema
{
  "type": "object",
  "required": [
    "slug",
    "key",
    "version"
  ],
  "properties": {
    "key": {
      "type": "string",
      "maxLength": 40,
      "description": "The build's key, from the game's list of builds."
    },
    "slug": {
      "type": "string",
      "description": "The game's address on Player Two (playertwo.lol/game/<slug>)."
    },
    "version": {
      "type": "string",
      "maxLength": 32,
      "description": "Its version. A build's version is up to 32 characters: letters, digits, dots, dashes, plus signs and spaces, starting with a letter or a digit (like 1.4.0 or 2.0 beta). 422 bad-version otherwise."
    }
  }
}
name_build annotations
{
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
list_products — What a game sells
Advertised by the server during the last successful anonymous check.
Advertised read-only

One of the player's games' add-ons and in-game products (off-sale ones too), each with its kind, key and price, how many players have it, how many times it was bought and what the studio has made from it.

list_products input schema
{
  "type": "object",
  "required": [
    "slug"
  ],
  "properties": {
    "slug": {
      "type": "string",
      "description": "The game's address on Player Two (playertwo.lol/game/<slug>)."
    }
  }
}
list_products annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
define_product — Add or change a product
Advertised by the server during the last successful anonymous check.
Advertised destructiveOpen-world

Add something one of the player's games sells, or change one by its key. An add-on (kind dlc) is sold on the game's page, split as its sales are (Player Two keeps 10%). Everything else is sold inside the game: the game lists them (p2.store.list) and asks to sell one (p2.store.buy), Player Two's own step takes the player's yes, and Player Two keeps 20%: a consumable (bought again and again, qty a time, used up by the game's server), an item or skin, a mod, a pack (contents: 2 to 10 of the others). Key and kind stay once a player has it; retired takes it off sale.

define_product input schema
{
  "type": "object",
  "required": [
    "slug",
    "product"
  ],
  "properties": {
    "slug": {
      "type": "string",
      "description": "The game's address on Player Two (playertwo.lol/game/<slug>)."
    },
    "product": {
      "type": "object",
      "required": [
        "key",
        "name",
        "price"
      ],
      "properties": {
        "key": {
          "type": "string",
          "maxLength": 40,
          "minLength": 1,
          "description": "What the game's code asks for it by: small letters, numbers and dashes. It stays once a player has it."
        },
        "qty": {
          "type": "integer",
          "maximum": 1000,
          "minimum": 1,
          "description": "A consumable's: how many one purchase gives."
        },
        "kind": {
          "enum": [
            "dlc",
            "consumable",
            "item",
            "skin",
            "mod",
            "pack"
          ],
          "type": "string",
          "description": "dlc (an add-on, sold on the game's page, split as its sales: 10% Player Two's), or an in-game purchase sold inside the game through p2.store (20% Player Two's): consumable, item, skin, mod, pack. dlc if not said; it stays once a player has it."
        },
        "name": {
          "type": "string",
          "maxLength": 60,
          "minLength": 2
        },
        "about": {
          "type": "string",
          "maxLength": 280
        },
        "price": {
          "type": "number",
          "maximum": 500,
          "minimum": 0.99,
          "description": "In US dollars, $0.99 to $500."
        },
        "retired": {
          "type": "boolean",
          "description": "true takes it off sale (its owners keep it); false puts it back."
        },
        "contents": {
          "type": "array",
          "items": {
            "type": "string",
            "maxLength": 40
          },
          "maxItems": 10,
          "minItems": 2,
          "description": "A pack's: the keys of 2 to 10 of the game's in-game products (no add-ons or packs)."
        }
      }
    }
  }
}
define_product annotations
{
  "readOnlyHint": false,
  "openWorldHint": true,
  "idempotentHint": true,
  "destructiveHint": true
}
get_rooms — A game's rooms now
Advertised by the server during the last successful anonymous check.
Advertised read-only

One of the player's games' multiplayer rooms open now (by build) and how their players' connections were over the last minute, overall and for its eight busiest rooms: ping (the middle page's and p90, ms there and back), jitter, bytes a second each way a page, corrections and rewinds a minute a page, connections dropped; whether rooms are on, the live build's room code, and the last error that code threw. What the studio's Rooms panel shows; `units` says what each figure is in. Read-only.

get_rooms input schema
{
  "type": "object",
  "required": [
    "slug"
  ],
  "properties": {
    "slug": {
      "type": "string",
      "description": "The game's address on Player Two (playertwo.lol/game/<slug>)."
    }
  }
}
get_rooms annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
playtest_link — A game's playtest link
Advertised by the server during the last successful anonymous check.
Advertised destructiveOpen-world

One of the player's games not out yet (kept private, or coming on a day): its "anyone with the link" playtest, as its studio's Playtesters has it. on: true turns it on (anyone who opens the link sees the game's page, a private one's too, and once signed in plays it as a tester: free, in test mode, a paid game too, from then on without the link); on: false turns it off, and every tester who came by it is taken off (invited testers stay); reset: true makes a new link, the old one stopping at once. Neither: how it stands. Answers whether it is on and the link to share while it is.

playtest_link input schema
{
  "type": "object",
  "required": [
    "slug"
  ],
  "properties": {
    "on": {
      "type": "boolean",
      "description": "true: anyone with the link plays it as a tester until it is out (signed out, they see its page and sign in to play). false: off, and every tester who came by it is taken off; invited testers stay. Turned on again, it is the same link. A game not out yet only: kept private, or coming on a day."
    },
    "slug": {
      "type": "string",
      "description": "The game's address on Player Two (playertwo.lol/game/<slug>)."
    },
    "reset": {
      "type": "boolean",
      "description": "true: a new link. The old one, and every browser holding it, stops at once, and every tester who came by it is taken off. It stays on or off as it was."
    }
  }
}
playtest_link annotations
{
  "readOnlyHint": false,
  "openWorldHint": true,
  "idempotentHint": false,
  "destructiveHint": true
}
post_update — Post an update on a game's page
Advertised by the server during the last successful anonymous check.
Open-world

Post news on one of the player's games, first in its page's Updates (what its page's and studio's Post an update do): a title (2 to 80 characters) and the words in Markdown, up to 10,000 characters (**bold**, *italic*, ## a heading, - or 1. lists, > a quote, [words](https://...) links, http and https only; no HTML, no pictures by Markdown), with up to 4 pictures, or a video and 3 pictures (media: addresses from upload_media with game set to this slug; the first is the post's picture in the feed). Backers, owners, wishlisters and the studio's followers are told in their notices, in plain words (none for a private game); it can be edited (edit_update), pinned (pin_update) or deleted (delete_update) after, but nobody is told again and an email sent stays sent, so post only what the player asked for. With at (milliseconds or an ISO time with its zone, 5 minutes to 90 days ahead) it waits: only the team sees it (list_updates), nobody is told until it goes up at that time, as if posted then. 20 a day a player.

post_update input schema
{
  "type": "object",
  "required": [
    "slug",
    "title"
  ],
  "properties": {
    "at": {
      "type": [
        "number",
        "string",
        "null"
      ],
      "description": "To post it later: when it goes up, in milliseconds or as an ISO time with its zone (2026-11-08T18:00:00Z), 5 minutes to 90 days ahead. Until then only its team sees it (listUpdates, its page) and nobody is told; at its time it goes up as if posted then (its date that moment) and its audience is told once. Up to 20 waiting a game. Left out: now."
    },
    "body": {
      "type": "string",
      "default": "",
      "maxLength": 10000,
      "description": "Its words, in Markdown, up to 10,000 characters (the marks count): **bold**, *italic*, a heading (a line starting with ##), lists (- or 1.), a quote (>) and links ([words](https://...), or an address written out; http and https only). No HTML (it shows as typed) and no pictures by Markdown: those go in media. 2 characters at least, unless it has media. Its notices and emails get it as plain words, the first 240 characters."
    },
    "slug": {
      "type": "string",
      "description": "The game's address on Player Two (playertwo.lol/game/<slug>)."
    },
    "media": {
      "type": "array",
      "items": {
        "anyOf": [
          {
            "type": "string",
            "maxLength": 600
          },
          {
            "type": "object",
            "required": [
              "src"
            ],
            "properties": {
              "h": {
                "type": "integer"
              },
              "w": {
                "type": "integer"
              },
              "src": {
                "type": "string",
                "maxLength": 600,
                "description": "Its address, from upload_media with game."
              },
              "kind": {
                "enum": [
                  "image",
                  "video"
                ],
                "type": "string",
                "description": "Read from the file; said here or not."
              },
              "still": {
                "type": "string",
                "maxLength": 600,
                "description": "A video's first frame, a picture uploaded the same way: shown until it plays."
              },
              "copies": {
                "type": "object",
                "required": [
                  "w",
                  "at"
                ],
                "properties": {
                  "w": {
                    "type": "integer"
                  },
                  "at": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "required": [
                        "w",
                        "src"
                      ],
                      "properties": {
                        "w": {
                          "type": "integer"
                        },
                        "src": {
                          "type": "string",
                          "maxLength": 600
                        }
                      }
                    },
                    "maxItems": 6
                  }
                },
                "description": "A picture's smaller copies (the composer makes them as it uploads), uploaded the same way."
              }
            }
          }
        ]
      },
      "maxItems": 4,
      "description": "Up to 4 pictures (PNG, JPEG or WebP, 12 MB each), or a video (MP4, WebM or MOV, 80 MB) and up to 3 pictures, in order: the first is the post's picture in the feed, the rest open from it. Each uploaded for this game (upload_media with game); any other address is refused."
    },
    "title": {
      "type": "string",
      "maxLength": 80,
      "minLength": 2,
      "description": "Its title, 2 to 80 characters."
    }
  }
}
post_update annotations
{
  "readOnlyHint": false,
  "openWorldHint": true,
  "idempotentHint": false,
  "destructiveHint": false
}
list_updates — A game's posted updates
Advertised by the server during the last successful anonymous check.
Advertised read-only

One of the player's games' posts still up on its page, the pinned one first and then the newest (up to 100): each one's id (what edit_update, pin_update and delete_update take), its kind (devlog: its team wrote it, so it can be edited and deleted; release, unlock, vote and raise are Player Two's own, which can only be pinned), title, Markdown words, attachments, when it went up, when it was last edited, whether it is pinned, how many comments it has and whether they are locked.

list_updates input schema
{
  "type": "object",
  "required": [
    "slug"
  ],
  "properties": {
    "slug": {
      "type": "string",
      "description": "The game's address on Player Two (playertwo.lol/game/<slug>)."
    }
  }
}
list_updates annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
edit_update — Edit a posted update
Advertised by the server during the last successful anonymous check.
Advertised destructiveOpen-world

Change one of the player's developer posts (kind devlog, from list_updates) by its id: its title (2 to 80), its words in Markdown (up to 10,000) and its attachments (media: the whole new list, in order, up to 4 pictures or a video and 3; the ones it had, and new ones from upload_media with game). What you leave out stays. The same rules as post_update; nobody is told again; its page says Edited after its date, and its translations are made again. A post waiting to go up (scheduled in list_updates): at moves its time, now: true posts it now (its audience told then); it isn't marked Edited. A file taken out leaves the store a day later unless another post shows it. Only what the player asked for.

edit_update input schema
{
  "type": "object",
  "required": [
    "slug",
    "id"
  ],
  "properties": {
    "at": {
      "type": [
        "number",
        "string"
      ],
      "description": "A post waiting to go up: its new time, as for posting (5 minutes to 90 days ahead). One already up is 409."
    },
    "id": {
      "type": "string",
      "description": "The post's id, from list_updates."
    },
    "now": {
      "type": "boolean",
      "const": true,
      "description": "A post waiting to go up: up now, its audience told now (Post now). One already up is 409."
    },
    "body": {
      "type": "string",
      "maxLength": 10000,
      "description": "Its words, in Markdown, as for posting (up to 10,000 characters; 2 at least unless it has media). A developer's post (\"devlog\") only."
    },
    "slug": {
      "type": "string",
      "description": "The game's address on Player Two (playertwo.lol/game/<slug>)."
    },
    "media": {
      "type": "array",
      "items": {
        "anyOf": [
          {
            "type": "string",
            "maxLength": 600
          },
          {
            "type": "object",
            "required": [
              "src"
            ],
            "properties": {
              "h": {
                "type": "integer"
              },
              "w": {
                "type": "integer"
              },
              "src": {
                "type": "string",
                "maxLength": 600,
                "description": "Its address, from upload_media with game."
              },
              "kind": {
                "enum": [
                  "image",
                  "video"
                ],
                "type": "string",
                "description": "Read from the file; said here or not."
              },
              "still": {
                "type": "string",
                "maxLength": 600,
                "description": "A video's first frame, a picture uploaded the same way: shown until it plays."
              },
              "copies": {
                "type": "object",
                "required": [
                  "w",
                  "at"
                ],
                "properties": {
                  "w": {
                    "type": "integer"
                  },
                  "at": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "required": [
                        "w",
                        "src"
                      ],
                      "properties": {
                        "w": {
                          "type": "integer"
                        },
                        "src": {
                          "type": "string",
                          "maxLength": 600
                        }
                      }
                    },
                    "maxItems": 6
                  }
                },
                "description": "A picture's smaller copies (the composer makes them as it uploads), uploaded the same way."
              }
            }
          }
        ]
      },
      "maxItems": 4,
      "description": "Its attachments in their new order, the whole list (the ones it had that you keep, from listUpdates, and new ones from uploadMedia with game): up to 4 pictures, or a video and 3. [] takes them all out. Left out, they stay. A file taken out leaves the store a day later, unless another of the game's posts shows it."
    },
    "title": {
      "type": "string",
      "maxLength": 80,
      "minLength": 2,
      "description": "Its title, 2 to 80 characters."
    }
  }
}
edit_update annotations
{
  "readOnlyHint": false,
  "openWorldHint": true,
  "idempotentHint": true,
  "destructiveHint": true
}
pin_update — Pin an update first
Advertised by the server during the last successful anonymous check.
Open-world

Pin one of a game's posts first in its page's Updates, before the newest (pinned: true, the default), or unpin it (false). Any post, Player Two's own "Out now" too. One a game: pinning another unpins the one before. Nobody is told; visitors see Pinned on it.

pin_update input schema
{
  "type": "object",
  "required": [
    "slug",
    "id"
  ],
  "properties": {
    "id": {
      "type": "string",
      "description": "The post's id, from list_updates."
    },
    "slug": {
      "type": "string",
      "description": "The game's address on Player Two (playertwo.lol/game/<slug>)."
    },
    "pinned": {
      "type": "boolean",
      "default": true,
      "description": "true pins it first (unpinning the one before: one a game); false unpins it."
    }
  }
}
pin_update annotations
{
  "readOnlyHint": false,
  "openWorldHint": true,
  "idempotentHint": true,
  "destructiveHint": false
}
delete_update — Delete a posted update
Advertised by the server during the last successful anonymous check.
Advertised destructiveOpen-world

Take one of the player's developer posts (kind devlog) off its game's page for good, by its id from list_updates: gone from the page, the feeds, the studio and the API; the notices it sent are taken out of players' lists (an email already sent stays sent); its pictures and video leave the store a day later unless another post shows them; unpinned if it was pinned. It can't be undone: only when the player asked for it. Player Two's own posts can't be deleted.

delete_update input schema
{
  "type": "object",
  "required": [
    "slug",
    "id"
  ],
  "properties": {
    "id": {
      "type": "string",
      "description": "The post's id, from list_updates."
    },
    "slug": {
      "type": "string",
      "description": "The game's address on Player Two (playertwo.lol/game/<slug>)."
    }
  }
}
delete_update annotations
{
  "readOnlyHint": false,
  "openWorldHint": true,
  "idempotentHint": true,
  "destructiveHint": true
}
list_comments — A posted update's comments
Advertised by the server during the last successful anonymous check.
Advertised read-only

Players' comments on one of the player's games' posts (id from list_updates), oldest first, the newest last, up to 200: each with its id, words, who wrote it (dev: the game's team), when, whether it was taken down, the comment it replies to, and whether it is new for the player (new: written since they last read the post's comments, not by them); how many are new; and whether the post's comments are locked. Reading them doesn't mark them read: mark_comments_read does. Agents read and look after comments; they don't write them (players do).

list_comments input schema
{
  "type": "object",
  "required": [
    "slug",
    "id"
  ],
  "properties": {
    "id": {
      "type": "string",
      "description": "The post's id, from list_updates."
    },
    "slug": {
      "type": "string",
      "description": "The game's address on Player Two (playertwo.lol/game/<slug>)."
    }
  }
}
list_comments annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
hide_comment — Take a comment down
Advertised by the server during the last successful anonymous check.
Advertised destructiveOpen-world

Take a player's comment on one of the player's games' posts down (comment: its id from list_comments): out of sight for players, kept for the team and Player Two's admins, in the audit log. Only when the player asked, or it plainly breaks the rules (spam, abuse); a comment someone should look at can also be reported on the page.

hide_comment input schema
{
  "type": "object",
  "required": [
    "slug",
    "id",
    "comment"
  ],
  "properties": {
    "id": {
      "type": "string",
      "description": "The post's id, from list_updates."
    },
    "slug": {
      "type": "string",
      "description": "The game's address on Player Two (playertwo.lol/game/<slug>)."
    },
    "comment": {
      "type": "string",
      "description": "The comment's id, from list_comments."
    }
  }
}
hide_comment annotations
{
  "readOnlyHint": false,
  "openWorldHint": true,
  "idempotentHint": true,
  "destructiveHint": true
}
lock_comments — Lock a post's comments
Advertised by the server during the last successful anonymous check.
Open-world

Lock one of the player's games' posts' comments (locked: true: no more, the ones there stay) or open them again (false).

lock_comments input schema
{
  "type": "object",
  "required": [
    "slug",
    "id",
    "locked"
  ],
  "properties": {
    "id": {
      "type": "string",
      "description": "The post's id, from list_updates."
    },
    "slug": {
      "type": "string",
      "description": "The game's address on Player Two (playertwo.lol/game/<slug>)."
    },
    "locked": {
      "type": "boolean",
      "description": "true: no more comments on this post; false opens them again."
    }
  }
}
lock_comments annotations
{
  "readOnlyHint": false,
  "openWorldHint": true,
  "idempotentHint": true,
  "destructiveHint": false
}
mark_comments_read — Mark a game's comments read
Advertised by the server during the last successful anonymous check.

For the player, on the game's team: a post's comments (id from list_updates) read up to now (or up to until, in milliseconds: the newer ones stay new), or every post's with no id (Mark all read). Each of the team has their own: a teammate's new comments stay new. Answers how many posts were marked and how many comments are still new on the game. Mark them only once the player has seen them (or asked).

mark_comments_read input schema
{
  "type": "object",
  "required": [
    "slug"
  ],
  "properties": {
    "id": {
      "type": "string",
      "description": "The post's id, from list_updates; left out, every post of the game."
    },
    "slug": {
      "type": "string",
      "description": "The game's address on Player Two (playertwo.lol/game/<slug>)."
    },
    "until": {
      "type": "number",
      "description": "Read up to this moment (milliseconds), as the comment last read was written; the newer ones stay new. Left out: up to now."
    }
  }
}
mark_comments_read annotations
{
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
my_studio — The player's studio
Advertised by the server during the last successful anonymous check.
Advertised read-only

The player's studio: its games and where each stands, and whether their identity is checked (needed only for raises).

my_studio input schema
{
  "type": "object",
  "properties": {}
}
my_studio annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}

Prompts

Not advertised

No prompt definitions available.

Resources

Not advertised

No resource definitions available.

30-day availability

Aggregated from read-only remote checks; this is not a tool-execution or security guarantee.

Successful checks
1 of 1 (100%)
Average latency
1056 ms
95th percentile latency
1056 ms

Maintenance history

Public check and source-refresh events. Editorial and ownership records remain private.

  • · probe · passed · 1056 ms · metadata changed · 33 tool(s)

Connect from your client

Each snippet registers the same endpoint; pick the client you use.

This server is operated by the named third party. Listing and endpoint checks are not an endorsement or a security audit. Review the operator's permissions, terms, and data handling before connecting. How listings are checked and corrected.

Claude Code

Run this once in a terminal. It registers the remote server. Use --scope project to write .mcp.json for the repo.
Claude Code configuration
claude mcp add --transport http player-two-mcp https://playertwo.lol/api/mcp

Codex

Run this once. Codex stores MCP servers in ~/.codex/config.toml (or .codex/config.toml in a trusted project).
Codex configuration
codex mcp add player-two-mcp --url https://playertwo.lol/api/mcp

Cursor

Merge this server into .cursor/mcp.json in your project, then enable player-two-mcp in your MCP settings.
Cursor configuration
{
  "mcpServers": {
    "player-two-mcp": {
      "url": "https://playertwo.lol/api/mcp"
    }
  }
}

Cline

Merge this into cline_mcp_settings.json (Cline → MCP Servers → Configure).
Cline configuration
{
  "mcpServers": {
    "player-two-mcp": {
      "type": "streamableHttp",
      "url": "https://playertwo.lol/api/mcp",
      "disabled": false
    }
  }
}

VS Code

Merge this server into .vscode/mcp.json. Use MCP: List Servers to start player-two-mcp and inspect its tools.
VS Code configuration
{
  "servers": {
    "player-two-mcp": {
      "type": "http",
      "url": "https://playertwo.lol/api/mcp"
    }
  }
}

Gemini CLI

Run this once. It writes .gemini/settings.json in the current project; pass --scope user for ~/.gemini/settings.json.
Gemini CLI configuration
gemini mcp add --transport http player-two-mcp https://playertwo.lol/api/mcp

Claude Desktop

Open Claude Settings > Connectors > Add custom connector, enter this server URL and enable it for the conversation. This is a manual remote-connector handoff, not a desktop JSON configuration.
Claude Desktop configuration
https://playertwo.lol/api/mcp

Windsurf

Merge this into ~/.codeium/windsurf/mcp_config.json, then refresh MCP in Cascade. Windsurf remote servers use serverUrl, not url.
Windsurf configuration
{
  "mcpServers": {
    "player-two-mcp": {
      "serverUrl": "https://playertwo.lol/api/mcp"
    }
  }
}

Let your agent find its tools

Find servers like Player Two MCP from your agent. Add Koskamo once to search the index for endpoints, access requirements, and client setup. Public discovery needs no key.

Do you run Player Two MCP?

Prove ownership with a DNS record, a well-known file, or your Official MCP Registry entry, and your edits publish immediately. Proofs are re-checked weekly; admins can still hide or remove a listing.

Claim this listing