{"openapi":"3.1.0","info":{"title":"Breakout Sim API","version":"0.1.0","description":"A real, stateless, playable brick-breaker engine simulated tick by tick: real ball physics, real angle-reflection paddle collisions, real brick-grid collision detection, life tracking, and win/game-over 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://breakoutsim.connectorbay.com/mcp.","contact":{"name":"Unify Dynamics LLC","email":"hr@unifydynamics.com","url":"https://connectorbay.com/breakoutsim/docs"},"termsOfService":"https://connectorbay.com/breakoutsim/terms"},"servers":[{"url":"https://breakoutsim.connectorbay.com"}],"externalDocs":{"url":"https://connectorbay.com/breakoutsim/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 game and returns its initial state (a full brick grid, top rows worth more","description":"Starts a fresh game and returns its initial state (a full brick grid, top rows worth more\n    points, ball served upward from just above the paddle). Use for \"let's play brick breaker\",\n    \"start a new game\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"width":{"default":30.0,"description":"Court width in units.","maximum":80,"minimum":12,"title":"Width","type":"number"},"height":{"default":24.0,"description":"Court height in units.","maximum":60,"minimum":16,"title":"Height","type":"number"},"rows":{"default":5,"description":"Brick rows.","maximum":10,"minimum":1,"title":"Rows","type":"integer"},"cols":{"default":10,"description":"Brick columns.","maximum":20,"minimum":3,"title":"Cols","type":"integer"},"lives":{"default":3,"description":"Starting lives.","maximum":9,"minimum":1,"title":"Lives","type":"integer"}},"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/move_paddle":{"post":{"operationId":"move_paddle","summary":"Sets the paddle's intent for the NEXT step() call — it does not move the paddle","description":"Sets the paddle's intent for the NEXT step() call — it does not move the paddle\n    immediately. Use for \"move the paddle left\", \"hold position\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"state":{"additionalProperties":true,"description":"The current game state, exactly as returned by new_game/move_paddle/step.","examples":[{"ball":{"vx":0.6,"vy":-0.8,"x":15.0,"y":21.0},"brick_area_height":8.4,"brick_cols":10,"brick_rows":5,"bricks":[[5,5,5,5,5,5,5,5,5,5],[4,4,4,4,4,4,4,4,4,4],[3,3,3,3,3,3,3,3,3,3],[2,2,2,2,2,2,2,2,2,2],[1,1,1,1,1,1,1,1,1,1]],"height":24.0,"lives":3,"paddle":{"intent":"stop","width":5.0,"x":12.5},"paddle_speed":1.5,"score":0,"status":"in_progress","ticks":0,"width":30.0}],"title":"State","type":"object"},"direction":{"description":"'left', 'right', or 'stop'.","title":"Direction","type":"string"}},"required":["state","direction"],"title":"move_paddleArguments","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/step":{"post":{"operationId":"step","summary":"Advances the simulation exactly one tick: moves the paddle and ball, and resolves wall","description":"Advances the simulation exactly one tick: moves the paddle and ball, and resolves wall\n    bounces, brick collisions (removing exactly the brick(s) hit and awarding points), paddle\n    collisions (real angle-reflection), life loss, win, and game-over. Returns the new state plus\n    event and bricks_hit (row/col pairs removed this tick, if any). Use for \"advance the ball\",\n    \"next tick\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"state":{"additionalProperties":true,"description":"The current game state, exactly as returned by new_game/move_paddle/step.","examples":[{"ball":{"vx":0.6,"vy":-0.8,"x":15.0,"y":21.0},"brick_area_height":8.4,"brick_cols":10,"brick_rows":5,"bricks":[[5,5,5,5,5,5,5,5,5,5],[4,4,4,4,4,4,4,4,4,4],[3,3,3,3,3,3,3,3,3,3],[2,2,2,2,2,2,2,2,2,2],[1,1,1,1,1,1,1,1,1,1]],"height":24.0,"lives":3,"paddle":{"intent":"stop","width":5.0,"x":12.5},"paddle_speed":1.5,"score":0,"status":"in_progress","ticks":0,"width":30.0}],"title":"State","type":"object"}},"required":["state"],"title":"stepArguments","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 court: '#' marks a surviving brick, '=' the paddle, 'o' the ball,","description":"A human-readable ASCII court: '#' marks a surviving brick, '=' the paddle, 'o' the ball,\n    with score/lives/status below. 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/move_paddle/step.","examples":[{"ball":{"vx":0.6,"vy":-0.8,"x":15.0,"y":21.0},"brick_area_height":8.4,"brick_cols":10,"brick_rows":5,"bricks":[[5,5,5,5,5,5,5,5,5,5],[4,4,4,4,4,4,4,4,4,4],[3,3,3,3,3,3,3,3,3,3],[2,2,2,2,2,2,2,2,2,2],[1,1,1,1,1,1,1,1,1,1]],"height":24.0,"lives":3,"paddle":{"intent":"stop","width":5.0,"x":12.5},"paddle_speed":1.5,"score":0,"status":"in_progress","ticks":0,"width":30.0}],"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}}}}