{"openapi":"3.1.0","info":{"title":"Spider Solitaire API","version":"0.1.0","description":"A real, stateless, playable single-player card game: genuine 104-card double-deck shuffle and deal, tableau move validation with the same-suit-run-as-a-unit rule, stock dealing under the no-empty-column rule, automatic sequence clearing, 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://spidersolitaire.connectorbay.com/mcp.","contact":{"name":"Unify Dynamics LLC","email":"hr@unifydynamics.com","url":"https://connectorbay.com/spidersolitaire/docs"},"termsOfService":"https://connectorbay.com/spidersolitaire/terms"},"servers":[{"url":"https://spidersolitaire.connectorbay.com"}],"externalDocs":{"url":"https://connectorbay.com/spidersolitaire/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 104-card double deck and deals standard Spider (10 columns: 4 sized 6, 6","description":"Shuffles a real 104-card double deck and deals standard Spider (10 columns: 4 sized 6, 6\n    sized 5; top card of each face up; remaining 50 to the stock). Use for \"let's play spider\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"suits_mode":{"default":1,"description":"1 (all Spades, easiest), 2 (Spades+Hearts), or 4 (all suits, hardest). Default 1.","title":"Suits Mode","type":"integer"},"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 Spider rules, returning the new state with an","description":"Validates and applies one move per real Spider rules, returning the new state with an\n    informative message (or a rejection reason for an illegal move).","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', 'from_pile': int (0-9), 'to_pile': int (0-9), 'count': int} or {'action': 'deal'}.","examples":[{"action":"tableau_to_tableau","count":1,"from_pile":2,"to_pile":5},{"action":"deal"}],"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 `count` cards from one tableau pile to another. A count > 1 is legal ONLY if those","description":"Moves `count` cards from one tableau pile to another. A count > 1 is legal ONLY if those\n    cards form a same-suit, consecutive-descending run — Spider's defining rule. Auto-clears a\n    completed King-to-Ace same-suit sequence on the destination pile. Use for \"move the 8 onto the\n    9\", \"move these three cards over\".","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-9.","title":"From Pile","type":"integer"},"to_pile":{"description":"Destination tableau pile, 0-9.","title":"To Pile","type":"integer"},"count":{"default":1,"description":"How many cards to move as one same-suit run, starting from the top. Default 1.","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/deal_from_stock":{"post":{"operationId":"deal_from_stock","summary":"Deals one card face up to every one of the 10 columns from the stock. Illegal if any column","description":"Deals one card face up to every one of the 10 columns from the stock. Illegal if any column\n    is currently empty, or the stock has fewer than 10 cards left. Use for \"deal from the stock\".","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":"deal_from_stockArguments","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 (every valid tableau run relocation, plus dealing from the","description":"Lists every currently legal move (every valid tableau run relocation, plus dealing from the\n    stock when allowed) 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: prefers a move that completes a 13-card same-suit sequence, then one that","description":"A real hint: prefers a move that completes a 13-card same-suit sequence, then one that\n    exposes a face-down card, then any other legal move, then dealing from the stock — or a\n    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: stock size, cleared-sequence count, and","description":"A human-readable text rendering of the whole board: stock size, cleared-sequence count, and\n    every tableau column (face-down cards shown as '??'). 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}}}}