{"openapi":"3.1.0","info":{"title":"Reversi Engine API","version":"0.1.0","description":"A real, stateless, playable flip-and-capture board game engine (full 8-direction flip computation, legal-move generation, pass-when-no-moves handling, complete win/draw detection) with a minimax + alpha-beta pruning AI opponent using a positional weight table (easy/medium/hard difficulty). 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://reversiengine.connectorbay.com/mcp.","contact":{"name":"Unify Dynamics LLC","email":"hr@unifydynamics.com","url":"https://connectorbay.com/reversiengine/docs"},"termsOfService":"https://connectorbay.com/reversiengine/terms"},"servers":[{"url":"https://reversiengine.connectorbay.com"}],"externalDocs":{"url":"https://connectorbay.com/reversiengine/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":"Starts a fresh reversi-style game on the standard 4-disc center starting position and","description":"Starts a fresh reversi-style game on the standard 4-disc center starting position and\n    returns its initial state. Use for \"let's play reversi\", \"start a new game\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"first_player":{"default":"B","description":"Which side moves first.","examples":["B","W"],"title":"First Player","type":"string"}},"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":"Places a disc and flips every qualifying line. Returns the new state + status: invalid_move","description":"Places a disc and flips every qualifying line. Returns the new state + status: invalid_move\n    (illegal — state unchanged), in_progress, pass (the OTHER side had no legal move and was\n    skipped — it's still this player's turn), or win (game over; winner is 'B', 'W', or 'draw').\n    Use for \"place at row 2, column 3\", \"play square 20\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"state":{"additionalProperties":true,"description":"The current game state, exactly as returned by new_game/make_move.","examples":[{"board":[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,"W","B",null,null,null,null,null,null,"B","W",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],"current_player":"B"}],"title":"State","type":"object"},"row":{"anyOf":[{"maximum":7,"minimum":0,"type":"integer"},{"type":"null"}],"default":null,"description":"Row 0-7 (top to bottom).","title":"Row"},"col":{"anyOf":[{"maximum":7,"minimum":0,"type":"integer"},{"type":"null"}],"default":null,"description":"Column 0-7 (left to right).","title":"Col"},"index":{"anyOf":[{"maximum":63,"minimum":0,"type":"integer"},{"type":"null"}],"default":null,"description":"Alternative to row/col: row*8+col.","title":"Index"}},"required":["state"],"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/get_valid_moves":{"post":{"operationId":"get_valid_moves","summary":"Lists legal placements for whoever is to move right now, each with how many discs it would","description":"Lists legal placements for whoever is to move right now, each with how many discs it would\n    flip. Empty means that player must pass (or the game has ended). Use for \"where can I play\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"state":{"additionalProperties":true,"description":"The current game state, exactly as returned by new_game/make_move.","examples":[{"board":[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,"W","B",null,null,null,null,null,null,"B","W",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],"current_player":"B"}],"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/render":{"post":{"operationId":"render","summary":"A human-readable ASCII grid with disc counts. Use for \"show me the board\", \"who's ahead\".","description":"A human-readable ASCII grid with disc counts. Use for \"show me the board\", \"who's ahead\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"state":{"additionalProperties":true,"description":"The current game state, exactly as returned by new_game/make_move.","examples":[{"board":[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,"W","B",null,null,null,null,null,null,"B","W",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],"current_player":"B"}],"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}},"/v1/tools/ai_move":{"post":{"operationId":"ai_move","summary":"Chooses the AI's next placement for whichever side is currently to move, WITHOUT applying it","description":"Chooses the AI's next placement for whichever side is currently to move, WITHOUT applying it\n    — call make_move with the returned row/col to actually play it. Use for \"make the computer's\n    move\", \"play as the AI on hard\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"state":{"additionalProperties":true,"description":"The current game state, exactly as returned by new_game/make_move.","examples":[{"board":[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,"W","B",null,null,null,null,null,null,"B","W",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],"current_player":"B"}],"title":"State","type":"object"},"difficulty":{"default":"hard","description":"easy, medium, or hard (default). Real minimax + alpha-beta search at every level; hard searches deepest.","title":"Difficulty","type":"string"}},"required":["state"],"title":"ai_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}}}}