clone

minesweeper as an mcp server: agents start games, play moves in batches and watch the board

main
mcpsweeper / progress.md
progress.md 5.5K source

Original prompt: I like it; lets iterate in ~/Developer/mcpsweeper — make an initial version and load it into codex so we can test here

Progress

  • Chosen architecture: stateless Cloudflare Worker MCP endpoint, explicit game_id handles, D1 persistence, and a read-only MCP App spectator view.
  • Implemented the initial game engine, optimistic-revision D1 repository, four MCP tools, and the canvas spectator UI with preview mode.
  • Switched the spectator surface to 98.css and authentic classic Minesweeper chrome while retaining a canvas field for 64x64 performance.
  • Updated the Cloudflare Vitest integration; the engine tests pass.
  • Benchmarked a certified 64x64 board (409 mines) at 15 ms locally, so game creation can stay on demand.
  • Benchmarked scaling: 224x224 stayed below 750 ms across 48 default-density seeds; 256x256 showed a 2.7 s outlier, so the initial limit is 224.
  • Added an exact replay data model (initial opening plus per-batch clue values) and a 98.css timeline/intent log spectator control.
  • Validated the full MCP/D1 loop at both 64x64 and the 224x224 limit; a maximum board solved in 19 batches with complete replay history.
  • Registered mcpsweeper in Codex at http://127.0.0.1:8787/mcp and opened the live local surface in the task.
  • Diagnosed a live App crash: model-facing observations and app-facing visual snapshots shared one field, and malformed/legacy event data could terminate polling.
  • Split agent positions from visual observations. Agent positions now use delta-coded frontier/clue/flag cell IDs; the app watcher alone receives full rows.
  • Constrained the MCP App to the host viewport so zoom does not grow the iframe; only the board viewport pans. Replaced iframe fullscreen with a Fit board control.
  • Widened the UI into a board + right inspector layout. Zoom, batch scrubber, replay controls, and intent history now sit beside the puzzle.
  • Added automatic before/after comparison for the selected batch and an updates-count column in batch history.
  • Verified the 1000x720 layout has no document/body overflow: board viewport 705x535 and right inspector 258x565. Preview comparison alternated AFTER -> BEFORE with no browser errors.
  • Simplified the shell back to classic Minesweeper hierarchy (Game/Help, counters/face, board) with one docked batch-history pane; removed dashboard-like UI chrome around zoom.
  • Prevented dev UI rebuilds from deleting the generated App out from under Wrangler (emptyOutDir: false).
  • Replaced tiny canvas font rendering with connected 5x7 pixel clue glyphs so numerals do not break apart when zoomed.
  • Removed the narrow-width stacking breakpoint after Codex triggered it in a physically wide panel; game/history now remain left/right at every host width.
  • Disabled circular auto-resize and explicitly request a 640px inline App height from the MCP host. Do not clamp this request to the host's reported maxHeight; Codex reports its current short card there, which turns the resize into a no-op.
  • Large-board mine counters now expand to five digits instead of clipping values above 999.
  • Added a board stage that centers the canvas whenever it is smaller than the viewport while remaining scrollable and center-anchored at larger zoom levels.
  • Replaced fixed 768px bitmap stretching with device-pixel-aware canvas rerasterization on zoom/resize, capped at a 4096px backing store. Added overview, compact, and detailed semantic cell rendering plus unchanged-frame paint caching; /preview?size=200 now exercises large-board scaling directly.
  • Cached the reconstructed historical observation used by automatic BEFORE/AFTER comparison so 200x200 boards remain responsive instead of rebuilding all 40,000 cells every animation frame.
  • Browser-verified 200x200 rendering at 2x device scale: 2.58px overview at fit, 4.53px compact at 175%, and 7.75px detailed at 300%. Fit, comparison toggle, and replay advancement all worked with no console errors; build/typecheck and all 5 engine tests pass.
  • Added a daily 04:17 UTC retention cron that deletes games inactive for more than 14 days by indexed updated_at; D1 cascades each deletion to its moves. An integration test preserves the exact cutoff boundary and recent games while verifying the expired move is removed.
  • Verified replay share URLs are self-contained gzip/base64url fragments: a fresh page restored revision 7 and replayed to revision 1 with only GET /preview and no MCP/D1 requests. The static preview deployment must remain available and version-1 fragment decoding must remain compatible.
  • Replaced the root preview with a white, centered landing page containing a copyable agent prompt for installing the deployed MCP endpoint and autonomously playing a 20x20 game. The spectator remains at /preview and in the MCP App.
  • Browser-checked the landing page at 1280x720 (centered prompt, white background, no scripts or console errors) and reran the preview game screenshot/state regression.
  • Provisioned and migrated mcpsweeper-agent-game-db, deployed Worker version 95dd8900-974a-469e-a007-e19b4bec5d90 at https://mcpsweeper-agent-game.felinestatemachine.workers.dev, and verified the live MCP endpoint by starting a 20x20 game.
  • Deployed retention and self-contained replay-link changes as Worker version 483d3852-562d-460d-bf75-8cb9a9a9eb95; Wrangler confirmed schedule 17 4 * * *, and the production health endpoint passed.

TODO

  • Verify subsequent live batches advance in the MCP App after the user starts a fresh game.
  • Keep the deployed Worker and D1 names aligned (mcpsweeper-agent-game and mcpsweeper-agent-game-db).