mcpField
P
Pico8 Mcp

Pico8 Mcp

Local
github.com/smartfrogGames & Entertainment0Updated 17w ago

About Pico8 Mcp

Pico8 Mcp is an MCP server for LLM agents to control real PICO-8 carts in deterministic lockstep. It exposes screenshots, Lua globals, and memory, and includes multi-session support and a live browser viewer.

Key features

  1. 01Advance game frames in lockstep
  2. 02Control buttons and script sequences
  3. 03Read screenshots, Lua globals, and memory
  4. 04Reset, manage sessions, and check startup
  5. 05Watch play in a live browser viewer

Use cases

  1. 01Automating play of PICO-8 carts
  2. 02Inspecting game state and memory
  3. 03Replaying or resetting a game session
  4. 04Watching agent actions in a browser

MCP support

The server exposes tools to MCP clients over stdio for starting carts, pressing buttons, advancing frames, and reading screenshots and state.

Configuration

Local server config is the same for every client. Copy it into your client’s MCP config file.

No install method listed yet

We haven’t collected a package or remote endpoint for this server. Follow the instructions in the project README.

Repository

Tools

No tool list yet

Local servers expose tools only once running on your machine, and the maintainer has not provided a tool list.

Details

From the project README

pico8-mcp

MCP server that lets an LLM play PICO-8 carts interactively: press buttons, advance frames deterministically, look at pixel-perfect screenshots, and read game variables — against the real PICO-8 binary, headless.

How it works

LLM ⇄ MCP (stdio) ⇄ pico8-mcp ⇄ pipes ⇄ pico8 -x cart_instrumented.p8
  • The cart is copied to /tmp/pico8-mcp/<session>/ and a small Lua harness is injected at the end of its __lua__ section (the original file is never touched). The harness shadows btn/btnp and replaces _update/_update60 with a command loop.
  • Input rides on PICO-8's serial(0x804, …) stdin channel. On desktop PICO-8 (0.2.7) this read has fread semantics: it blocks until exactly len bytes arrive. The driver therefore speaks fixed-size 8-byte packets (<op:1><a:3 hex><b:3 hex>\n), which freezes the engine between commands and gives perfect lockstep — batched frames run at host speed (~600 game frames in <30 ms), not real time.
  • Output rides on printh (text lines prefixed @) and serial(0x805, …) (raw binary: framebuffer + palette dumps), rendered server-side to PNG.

Requirements

  • pico8 on PATH (or PICO8_BIN=/path/to/pico8), version 0.2.x
  • Node.js ≥ 18
  • Carts must use _update/_update60 and read input via btn/btnp (standard carts do; custom flip() main loops are not supported)

Install

npm install && npm run build

opencode config (opencode.json):

{
  "mcp": {
    "pico8": {
      "type": "local",
      "command": ["node", "/path/to/pico8-mcp/dist/index.js"]
    }
  }
}

Claude Desktop and any other MCP host: same command, stdio transport.

Tools

ToolPurpose
pico8_bootStart a cart under lockstep control (game time frozen until you step). Optional seed for deterministic rnd().
pico8_stepHold buttons (left/right/up/down/o/x), advance N frames, get a screenshot.
pico8_playScripted sequence of {buttons, frames} steps in one call.
pico8_screenPixel-perfect PNG of the current frame (scale 1–4).
pico8_readRead Lua globals by dotted path (player.x, objects.1.type…).
pico8_peekHex dump of PICO-8 RAM (0x6000 framebuffer, 0x2000 map…).
pico8_resetKill + restart from the original file (picks up cart edits).
pico8_shutdown / pico8_sessionsLifecycle / listing.
pico8_boot_checkRun the unmodified cart with pico8 -x for N seconds and report boot errors (benchmark-style check).

Multiple sessions can run side by side; session_id defaults to the most recent live one.

Live viewer

The server hosts a small local web page so you can watch the LLM play in real time: open http://127.0.0.1:7864/ in a browser. It shows the game screen (streamed over SSE), the buttons currently held, and a log of every tool call plus the cart's printh output.

pico8-mcp live viewer

  • While a browser tab is connected, batched steps are split into small chunks (default 15 frames) with a screen grab after each, so long pico8_step calls play back like a fast-forward video. With no viewer connected there is zero overhead.
  • Playback runs at the LLM's pace (usually much faster than real time).

Env knobs:

VariableDefaultEffect
PICO8_MCP_VIEWER1set to 0 to disable the viewer entirely
PICO8_MCP_VIEWER_PORT7864listen port (binds 127.0.0.1 only)
PICO8_MCP_VIEWER_CHUNK15frames per intermediate screen grab while spectating

If the port is already in use (e.g. a second MCP host), the viewer is disabled with a warning on stderr and the server keeps working normally.

Semantics worth knowing

  • Buttons stay held between steps; btnp() fires on the first frame of a new press only. To tap twice: step with the button, step with buttons: [], step with the button again.
  • Screenshots are taken post-_draw of the last stepped frame.
  • A runtime error in the cart kills the -x process; the error text is surfaced in the tool result. pico8_reset starts over.
  • The harness uses GPIO memory (0x5f80–0x5fff) as its packet buffer and overrides btn/btnp globals — carts that use GPIO themselves or cache local btn=btn before the harness loads will misbehave.

Development

  • npm run build then node test/mcp-probe.mjs [cart.p8] runs an end-to-end probe through a real MCP client (boot → play → read → shutdown).
  • PICO8_BIN selects an alternative PICO-8 binary.

Comments

Markdown supported

New to MCP?

From what the protocol is to installing your first server, these answers cover most first questions.

An open protocol that defines how AI applications connect to external tools and data in a uniform way. Clients talk to the model; MCP servers provide tools, resources and prompt templates. They exchange standard messages, so one server can be reused by many clients.