FRED-80 has an MCP (Model Context Protocol) server built into the engine itself. Point Claude, Gemini, or any MCP-capable assistant at a running FRED-80 process and it can read your sprites, watch for Lua errors, press buttons in your live cart, and edit code — without you copy-pasting a single screenshot.
Normally, getting an AI assistant to help with a game means describing what's on screen, pasting error messages by hand, and never being quite sure the assistant is looking at the same state you are. FRED-80's MCP server closes that loop: the assistant can query the engine directly and act on it — the same running process you're looking at, not a description of it.
FRED-80 speaks MCP over a local TCP socket. Most AI hosts only know how to spawn a process over stdio, so a small bridge script sits in between.
$ export FRED80_MCP_TOKEN=some-long-random-string
$ ./fred-80
The MCP server listens on 127.0.0.1:8090 and only accepts connections that present this token. Currently macOS only — the tool code compiles everywhere, but the live socket server itself is stubbed on Windows/Amiga builds for now.
{
"mcpServers": {
"fred80": {
"command": "python3",
"args": ["/path/to/amico-8/tools/mcp_bridge.py"],
"env": { "FRED80_MCP_TOKEN": "some-long-random-string" }
}
}
}
tools/mcp_bridge.py pipes JSON-RPC lines between your host's stdio and FRED-80's TCP socket — all protocol logic and the auth boundary live in the engine, not the bridge. Works with Claude Desktop, Gemini CLI, and any other stdio-based MCP host.
Open a cart and describe what you want. The assistant reaches for screenshot, sprite_get, or get_error_log the same way it reaches for any other tool — no special prompting required.
A real tool-call sequence — no hand-waving. The assistant closes the loop itself: draw, run, look, fix.
Everything the engine already does for a human in the editor, exposed the same way to an assistant.
engine_pingget_telemetryget_error_logget_palettedocs_searchsprite_get / sprite_setsprite_drawsprite_fill_rectsprite_hitbox_setsprite_exportmap_loadmap_get / map_setmap_drawmap_exportiso_set / iso_getiso_fill_heightiso_infovoxel_get / voxel_setvoxel_fill_planevoxel_fill_rowvoxel_rebuild_hullvoxel_infosfx / musicnotesnd_load / snd_playpoly_buildcart_create / cart_opencart_read_sheet / cart_write_sheetcart_list_sheetsreload_cartinject_inputscreenshotDiamond-grid tilemaps get their own tool category and their own runtime API — most assistants hit this cold, so here's the whole loop both ways: writing cart code directly, and live-editing through MCP.
local iso = dofile(CART_DIR .. "isometric.lua")
local TW, TH, HU = 32, 16, 8 -- tile width, height, elevation-per-height-unit (px)
local cols, rows = 4, 4
local data, heights, ramps = {}, {}, {}
for i = 1, cols * rows do
data[i], heights[i], ramps[i] = 1, 0, 0 -- tile 1, ground level, flat
end
local tm = tilemap_new_iso(TW, TH, HU, cols, rows, { ground_sprite }, data, heights, ramps)
local map = iso.new(tm, 320, 240) -- ox,oy: world (1,1)@height 0 projects here
function _draw()
cls(0)
map:draw() -- terrain
map:draw_actor(player_spr, p.col, p.row, p.h) -- occlusion-correct actor
end
Full API (ramps, hop-tweens, iso.center_bounds, loading a map the editor painted via iso_mload) is on the API Reference page; a runnable cart is in the examples.
iso_set/iso_get's col/row are 0-based (the editor's raw grid) — a different convention from tilemap_get/tilemap_set's 1-based one at the Lua/runtime layer above. Worth stating up front to an assistant working across both.
Every tool is tagged by how much it can change, so a host can reason about — or ask you to confirm — anything beyond a read.
Read-only. Screenshots, sprite/palette/error readback, fps and frame timing. Can't change anything.
Changes cart state — sprite pixels, tilemap cells, voxels, a played sound, an injected button press. Reversible by re-editing or re-running.
Only reload_cart today. Restarts the cart from a fresh Lua state — all in-memory runtime state (score, position) is lost, same as pressing F5.
The server only binds to 127.0.0.1 and requires a bearer token set by whoever launches FRED-80 —
it's not reachable over the network, and there's nothing to configure beyond the token. execute_lua_eval
(arbitrary Lua from the assistant) is deliberately not shipped yet — it needs real sandboxing first.
Full tool schemas and parameters
Every tool listed here has a full parameter reference, defaults, and gotchas documented alongside the rest of the Lua API.