Let an AI Build Your Game of Life Patterns: A Tour of Our MCP Server

A hands-on walkthrough of our Model Context Protocol server for Conway's Game of Life — real requests, real responses, and a Claude Desktop config you can copy right now.

angen.ai
July 13, 2026
6 min read
mcp
ai
claude
tutorial
api

Let an AI Build Your Game of Life Patterns: A Tour of Our MCP Server

Most Game of Life sites give you a simulator and a pattern archive. We built those too — but we also built something no other Life site has: a public Model Context Protocol (MCP) server, so an AI agent like Claude can look up, transform, and compose real Life patterns as tool calls instead of guessing at cell coordinates in a chat window.

This is a tour of that server — what it does, how to connect to it, and real request/response pairs from the live endpoint, not mocked-up examples.

Why an MCP server for a cellular automaton

If you've read our piece on why LLMs still can't play Conway's Game of Life, you know the underlying problem: language models are unreliable at hand-simulating Life past a handful of generations, because it requires exact, iterated, all-cells-at-once state tracking — a specific weakness of autoregressive text generation, not a general math deficiency.

Tool use sidesteps that weakness entirely. An agent that calls a tool for pattern data isn't reasoning its way to an answer — it's fetching the answer, computed the normal way, every time. That's the whole design premise here: give agents exact primitives for the parts of Life that are easy to get wrong by hand (cell coordinates, rotations, RLE encoding), and let them spend their reasoning budget on the actual task — composing a scene, explaining a pattern, building something for a user — instead of on neighbor-counting.

Connecting a client

The server speaks MCP over a single HTTP endpoint:

https://life.angen.ai/api/mcp/mcp

For Claude Desktop or Claude Code, add it to your MCP config:

{
  "mcpServers": {
    "gameoflife": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-fetch", "https://life.angen.ai/api/mcp/mcp"]
    }
  }
}

No API key, no auth — it's a public, read-mostly server over pattern data. You can also talk to it directly with curl or any JSON-RPC 2.0 client, which is how every example below was actually generated.

The tools, tested live

The server currently exposes eight tools. Every response quoted here is a real call against production, made while writing this article.

list_patterns — search the library by keyword or category

{"name": "list_patterns", "arguments": {"onlyStarred": true, "keyword": "glider"}}

Returns featured patterns matching "glider" — the Glider itself, the Gosper glider gun and its variants, several glider syntheses, the Gunstar, Silver's reflector. Each entry comes back with an id, name, category, and description, e.g.:

{
  "id": "glider",
  "name": "Glider",
  "category": "spaceship",
  "description": "The Glider is the smallest, most common, and first discovered spaceship in Conway's Game of Life. It moves diagonally with a period of 4 and a speed of c/4."
}

category filters to methuselah, synthesis, oscillator, spaceship, reaction, gun, or still_life; keyword does fuzzy matching over name, description, and category. This is the tool an agent calls first — to find a pattern id before doing anything else with it.

get_pattern — fetch a pattern as compact RLE

{"name": "get_pattern", "arguments": {"patternId": "glider"}}
{ "rle": "bo$2bo$3o!", "width": 3, "height": 3, "cellCount": 5 }

That's the canonical five-cell glider in RLE — the standard, tweet-sized text format for Life patterns. An agent can hand this straight to a user, decode it into coordinates itself, or feed it into the composition tools below.

get_pattern_info — the same lookup, with full metadata

{"name": "get_pattern_info", "arguments": {"patternId": "glider"}}
{
  "id": "glider", "name": "Glider", "category": "spaceship",
  "description": "The Glider is the smallest, most common, and first discovered spaceship...",
  "starred": true, "cellCount": 5,
  "bounds": { "width": 3, "height": 3 },
  "rle": "bo$2bo$3o!"
}

Use this when an agent needs to talk about a pattern (for a caption, an explanation, a comparison) rather than just place it.

rotate_pattern — turn a pattern 0/90/180/270 degrees

{"name": "rotate_pattern", "arguments": {"patternId": "glider", "angle": 90}}
{ "rle": "b2o$obo$2bo!", "width": 3, "height": 3, "cellCount": 5, "rotationAngle": 90 }

Works on patternId or a raw rle string, so you can rotate patterns that aren't in our library too.

create_grid_pattern — tile a pattern into rows and columns

{
  "name": "create_grid_pattern",
  "arguments": { "patternId": "glider", "columns": 3, "rows": 3, "columnSpacing": 5, "rowSpacing": 5 }
}

Returns a single 19×19, 45-cell RLE containing all nine gliders correctly spaced — the kind of thing that's genuinely tedious to get right by hand-counting offsets, and exact in one tool call.

create_composition — place multiple patterns at exact coordinates

{
  "name": "create_composition",
  "arguments": {
    "patterns": [
      { "patternId": "glider", "x": 0, "y": 0 },
      { "patternId": "block", "x": 10, "y": 10 }
    ]
  }
}
{ "rle": "bo$2bo$3o$$$$$$$$10b2o$10b2o!", "width": 12, "height": 12, "cellCount": 9, "patterns": [...] }

This is the general-purpose scene builder — any number of named patterns or raw RLE snippets, each with its own coordinates and optional rotation, merged into one RLE. It's what an agent uses to actually design something, as opposed to fetching or transforming a single pattern.

create_random_composition — scatter patterns without collisions

Same idea as above, but you give it pattern counts and a canvas size and it places them randomly with a minimum spacing, retrying placement up to a configurable attempt limit. Useful for agents generating varied "soup" scenes or test boards without hand-picking every coordinate.

normalize_pattern — shift a pattern's origin to (0,0)

Small but useful utility: takes a pattern or RLE string wherever it currently sits and re-anchors it to start at the origin, so downstream placement math doesn't have to account for arbitrary offsets.

What this looks like end to end

Ask Claude (with the server connected) something like "give me an RLE for three gliders converging on a central block, spaced 15 cells apart" and it will: call list_patterns or already know the ids, call get_pattern or rotate_pattern as needed to orient each glider correctly, then call create_composition to place all three plus the block at exact coordinates — and hand you back one clean RLE string, verified correct by the server's own encoder rather than assembled by the model guessing at cell positions. Paste that RLE into our simulator and watch it run.

What's next

We're actively extending this tool set toward an eval-sandbox direction — letting an agent run a pattern forward N generations and check its own predictions against the real simulation, rather than only fetching known patterns. That's a natural fit for the LLM-simulation-accuracy research covered in our LLM benchmark piece; more on it once it's live and verifiable end to end, same standard as everything above.

If you're curious how the underlying rules work before wiring up an agent, our introduction to Conway's Game of Life covers the four-rule basics this whole server is built on. And if you just want to see the tools in action without writing any code, the /mcp page has copy-paste configs for Claude Desktop, curl, JavaScript, and Python, plus the full live tool list.