{"openapi":"3.1.0","info":{"title":"FreeCell API","version":"0.1.0","description":"A real, stateless, playable single-player card game: genuine 52-card round-robin shuffle and deal, tableau move validation with the exact supermove capacity formula, free-cell and foundation moves, and win detection. Every tool call takes the full game state and returns the new state; nothing is stored server-side.\n\nEvery operation is read-only or compute-only. The same tools are available over MCP (streamable HTTP) at https://freecellplay.connectorbay.com/mcp.","contact":{"name":"Unify Dynamics LLC","email":"hr@unifydynamics.com","url":"https://connectorbay.com/freecellplay/docs"},"termsOfService":"https://connectorbay.com/freecellplay/terms"},"servers":[{"url":"https://freecellplay.connectorbay.com"}],"externalDocs":{"url":"https://connectorbay.com/freecellplay/docs"},"security":[{},{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"type":"http","scheme":"bearer","description":"Optional. A Pro API key raises rate limits; no credentials are required."}},"schemas":{"Error":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object"}}}}},"paths":{"/v1/tools/new_game":{"post":{"operationId":"new_game","summary":"Shuffles a real 52-card deck and deals it round-robin, all face up, across 8 tableau","description":"Shuffles a real 52-card deck and deals it round-robin, all face up, across 8 tableau\n    columns. Use for \"let's play freecell\", \"deal a freecell hand\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"seed":{"anyOf":[{"type":"integer"},{"type":"null"}],"default":null,"description":"Optional integer seed for a reproducible shuffle (testing/demos). Omit for a real random shuffle.","title":"Seed"}},"title":"new_gameArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/make_move":{"post":{"operationId":"make_move","summary":"Validates and applies one move per real FreeCell rules (including the exact supermove","description":"Validates and applies one move per real FreeCell rules (including the exact supermove\n    capacity check), returning the new state with an informative message or rejection reason.","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"state":{"additionalProperties":true,"description":"The current game state, exactly as returned by new_game or make_move. Carry it forward between calls; there is no server-side session.","title":"State","type":"object"},"move":{"additionalProperties":true,"description":"{'action': 'tableau_to_tableau'|'tableau_to_free'|'free_to_tableau'|'tableau_to_foundation'|'free_to_foundation', 'from_pile': int (0-7), 'to_pile': int (0-7), 'cell': int (0-3), 'count': int}.","examples":[{"action":"tableau_to_tableau","count":1,"from_pile":2,"to_pile":5},{"action":"tableau_to_free","from_pile":3}],"title":"Move","type":"object"}},"required":["state","move"],"title":"make_moveArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/move_tableau_to_tableau":{"post":{"operationId":"move_tableau_to_tableau","summary":"Moves a valid descending, alternating-color run of `count` cards between tableau columns,","description":"Moves a valid descending, alternating-color run of `count` cards between tableau columns,\n    enforcing the exact supermove capacity formula: (1+free cells)*2^(other empty columns).","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"state":{"additionalProperties":true,"description":"The current game state, exactly as returned by new_game or make_move. Carry it forward between calls; there is no server-side session.","title":"State","type":"object"},"from_pile":{"description":"Source tableau pile, 0-7.","title":"From Pile","type":"integer"},"to_pile":{"description":"Destination tableau pile, 0-7.","title":"To Pile","type":"integer"},"count":{"default":1,"description":"How many cards to move as one run. Default 1. Capped by the exact supermove formula — see supermove_capacity.","title":"Count","type":"integer"}},"required":["state","from_pile","to_pile"],"title":"move_tableau_to_tableauArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/move_tableau_to_free":{"post":{"operationId":"move_tableau_to_free","summary":"Parks a tableau column's top card in an empty free cell. Use for \"put this card in a free","description":"Parks a tableau column's top card in an empty free cell. Use for \"put this card in a free\n    cell\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"state":{"additionalProperties":true,"description":"The current game state, exactly as returned by new_game or make_move. Carry it forward between calls; there is no server-side session.","title":"State","type":"object"},"from_pile":{"description":"Source tableau pile, 0-7.","title":"From Pile","type":"integer"},"cell":{"anyOf":[{"type":"integer"},{"type":"null"}],"default":null,"description":"Which free cell (0-3) to use. Omit to use the first empty one.","title":"Cell"}},"required":["state","from_pile"],"title":"move_tableau_to_freeArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/move_free_to_tableau":{"post":{"operationId":"move_free_to_tableau","summary":"Moves a free cell's card onto a tableau pile if it fits. Use for \"play the free cell card","description":"Moves a free cell's card onto a tableau pile if it fits. Use for \"play the free cell card\n    onto pile 2\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"state":{"additionalProperties":true,"description":"The current game state, exactly as returned by new_game or make_move. Carry it forward between calls; there is no server-side session.","title":"State","type":"object"},"cell":{"description":"Free cell index, 0-3.","title":"Cell","type":"integer"},"to_pile":{"description":"Destination tableau pile, 0-7.","title":"To Pile","type":"integer"}},"required":["state","cell","to_pile"],"title":"move_free_to_tableauArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/move_tableau_to_foundation":{"post":{"operationId":"move_tableau_to_foundation","summary":"Moves a tableau pile's top card to its suit foundation if it's the next rank needed.","description":"Moves a tableau pile's top card to its suit foundation if it's the next rank needed.","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"state":{"additionalProperties":true,"description":"The current game state, exactly as returned by new_game or make_move. Carry it forward between calls; there is no server-side session.","title":"State","type":"object"},"from_pile":{"description":"Source tableau pile, 0-7.","title":"From Pile","type":"integer"}},"required":["state","from_pile"],"title":"move_tableau_to_foundationArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/move_free_to_foundation":{"post":{"operationId":"move_free_to_foundation","summary":"Moves a free cell's card to its suit foundation if it's the next rank needed.","description":"Moves a free cell's card to its suit foundation if it's the next rank needed.","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"state":{"additionalProperties":true,"description":"The current game state, exactly as returned by new_game or make_move. Carry it forward between calls; there is no server-side session.","title":"State","type":"object"},"cell":{"description":"Free cell index, 0-3.","title":"Cell","type":"integer"}},"required":["state","cell"],"title":"move_free_to_foundationArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/supermove_capacity":{"post":{"operationId":"supermove_capacity","summary":"Computes the EXACT maximum number of cards that can be moved as one unit onto `to_pile`","description":"Computes the EXACT maximum number of cards that can be moved as one unit onto `to_pile`\n    right now: (1 + empty free cells) * 2 ^ (other empty tableau columns, excluding the destination\n    itself). Use for \"how many cards can I move at once\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"state":{"additionalProperties":true,"description":"The current game state, exactly as returned by new_game or make_move. Carry it forward between calls; there is no server-side session.","title":"State","type":"object"},"to_pile":{"description":"The tableau pile, 0-7, you want to move a run onto.","title":"To Pile","type":"integer"}},"required":["state","to_pile"],"title":"supermove_capacityArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/get_valid_moves":{"post":{"operationId":"get_valid_moves","summary":"Lists every currently legal move (tableau runs within supermove capacity, free-cell parks,","description":"Lists every currently legal move (tableau runs within supermove capacity, free-cell parks,\n    and foundation moves) as ready-to-use move objects. Use for \"what can I do\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"state":{"additionalProperties":true,"description":"The current game state, exactly as returned by new_game or make_move. Carry it forward between calls; there is no server-side session.","title":"State","type":"object"}},"required":["state"],"title":"get_valid_movesArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/hint":{"post":{"operationId":"hint","summary":"A real hint: a foundation move if one exists, else a tableau move, else any legal move, or","description":"A real hint: a foundation move if one exists, else a tableau move, else any legal move, or\n    a genuine deadlock report if nothing at all is legal. Use for \"give me a hint\", \"am I stuck\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"state":{"additionalProperties":true,"description":"The current game state, exactly as returned by new_game or make_move. Carry it forward between calls; there is no server-side session.","title":"State","type":"object"}},"required":["state"],"title":"hintArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/render":{"post":{"operationId":"render","summary":"A human-readable text rendering of the whole board: foundations, free cells, and every","description":"A human-readable text rendering of the whole board: foundations, free cells, and every\n    tableau column. Use for \"show me the board\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"state":{"additionalProperties":true,"description":"The current game state, exactly as returned by new_game or make_move. Carry it forward between calls; there is no server-side session.","title":"State","type":"object"}},"required":["state"],"title":"renderArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}}}}