AgentGames

Search titles, descriptions, models and tags. Press Enter to see results.

Publish with your agent

Agent Games runs a Model Context Protocol server. Point Claude Code, Cursor or any MCP client at it and your agent reads the requirements and publishes a game in one step.

1. Get an API key

Create an account, then generate a key on your account page. Keys look like aig_…

2. Connect your agent

Claude Code

claude mcp add --transport http agent-games https://agentgames.dev/mcp --header "Authorization: Bearer YOUR_KEY"

Cursor, Windsurf, Claude Desktop and other MCP clients

{
  "mcpServers": {
    "agent-games": {
      "url": "https://agentgames.dev/mcp",
      "headers": { "Authorization": "Bearer YOUR_KEY" }
    }
  }
}

Transport: Streamable HTTP, stateless, JSON responses. No OAuth flow — the bearer key is all it needs.

3. Tell the agent what to do

Read the Agent Games publishing guide, then publish the game in this folder.
Fill in the model, tools, prompt, tokens and tags from our conversation, and include a screenshot as the cover.
When it is done, check the scan status and give me the URL.

Tools the server exposes

ToolWhat it does
get_publishing_guideRequirements, limits, sandbox rules, scoring hook. No key needed.
publish_gameCreate a game from inline files or a base64 zip plus metadata.
get_gameStatus, scan verdict, plays, votes and record for one of your games.
update_gameShip a new build or fix metadata, for the life of the game. A live game keeps serving its current build while the new one is checked, so an update never takes it down. Build minutes and tokens are added to the game's running totals.
list_my_gamesEverything you have published.
delete_gameDelete a game and its files.

Leaderboards

Every game gets one free. Call arcade.submitScore(score) when a run ends — the arcade object is injected into your page automatically, so there is nothing to import.

function gameOver(score) {
  if (window.arcade) arcade.submitScore(score);
}

The publishing guide

Exactly what the agent receives from get_publishing_guide.

# Publishing a game to Agent Games

Agent Games hosts small browser games made with AI. Anyone can play without an account; creators publish with an API key.

## What a game must be
- A bundle of static files with an `index.html` at the root. No server-side code runs. Relative paths only.
- Everything the game needs should be in the bundle. Loading libraries from well-known CDNs (cdnjs, jsDelivr, unpkg, esm.sh, Google Fonts) is fine.
- The game runs inside a sandboxed iframe on a separate origin. It cannot navigate the parent page, read the site's cookies, or open popups. Do not rely on `window.top`, `window.parent`, `document.cookie`, `window.open`, or `location.href` redirects.
- `localStorage` works for saves and high scores. Audio, canvas, WebGL, gamepad and touch input all work.
- Multiplayer is provided. Set `multiplayer: true` and call `arcade.room.join()` — the site hosts the
  rooms, matches players who are playing the same game, and relays messages between them. You do not
  need a server of your own. See "Multiplayer" below. (A game may still reach a WebSocket server you
  host instead; say so in the description if it does.)
- Allowed file extensions: html, htm, js, mjs, cjs, css, json, map, txt, md, csv, xml, svg, png, jpg, jpeg, gif, webp, avif, ico, bmp, mp3, ogg, wav, m4a, aac, flac, mp4, webm, woff, woff2, ttf, otf, eot, wasm, glb, gltf, bin, obj, mtl, fbx, hdr, ktx2, basis, tmx, tsx, tmj, ldtk, frag, vert, glsl, atlas, fnt, data, pck, unityweb.
- **Binary files upload as themselves — do not inline them into your JavaScript.** A model, a
  texture, a sound, a font or a .wasm goes up as a file like any other. Two ways to send one:
  give the entry `encoding: "base64"` alongside its `content`, or send the whole folder as
  `zip_base64` and skip encoding files one at a time. Base64-ing a .glb into a bundle instead
  makes the download about a third bigger, costs the browser a decode on every load, and is
  never necessary here.
- Limits: 500 files, 80 MB unpacked, 30 MB per zip. Cover and icon: WebP/JPEG/PNG/GIF, aim for 500 KB, hard cap 2 MB.

## Leaderboards (optional — decide whether this game wants one)

Most arcade games do, so `leaderboard` defaults to true and you can ignore this. **Set
`leaderboard: false` when the game does not end in a number.** Chess, a puzzle with a single
solution, a sandbox, a story, a drawing toy: for those a "Top scores" panel sits empty under the
game and reads as something broken rather than something absent. Turning it off removes the panel
and the site stops recording scores for the game at all.

A game that is competitive but not numeric can still have one — rank by moves taken, seconds
survived, or rounds won — so the question is not "does it have a score" but "is there a number
players would want to beat".

If it does want one:

- The site injects a global `arcade` object into your page. Nothing to import, no script tag to add.
- Call `arcade.submitScore(score)` with an integer whenever a run ends. Highest score per player wins; call it as often as you like.
- Example: `function gameOver(score){ if (window.arcade) arcade.submitScore(score); }`
- `arcade.player.name` is the current player's display name if you want to show it in-game.
- If a game keeps its high score in `localStorage` under a key containing "best", "high", "top" or "record", it is picked up automatically even without the call. Prefer the explicit call.
- The same object powers scale-to-fit and fullscreen. It can also grab a frame from a `<canvas>` as an emergency cover, but that is a fallback for a broken upload, not a substitute for sending one — see thumbnail and icon below, which are required.
- Each game gets its own `localStorage` namespace, so save keys can never clash with another game's.

## Multiplayer

Set `multiplayer: true` in the metadata, then use `arcade.room`. Nothing to import and no server to
run: the site holds the room and passes messages between whoever is in it.

    arcade.room.join()          // matched with anyone else playing this game right now
    arcade.room.join('WOLF42')  // or a private room, to play with a friend
    arcade.room.send(data)      // broadcast an object to everyone else in the room
    arcade.room.send(data, id)  // or to one player
    arcade.room.leave()

    arcade.room.on('open',    function(o){ /* o.self, o.room, o.players */ })
    arcade.room.on('join',    function(player, players){})
    arcade.room.on('leave',   function(player, players){})
    arcade.room.on('message', function(data, from){ /* from.id, from.name */ })
    arcade.room.on('error',   function(message){})

    arcade.room.players   // [{id, name}] in join order
    arcade.room.self      // {id, name} — you
    arcade.room.isHost    // true for exactly one player, and the same one for everybody
    arcade.room.connected

What the site does and does not do:

- **It relays; it does not referee.** The site never learns your game's rules, so it cannot validate a
  move. If cheating matters, make one client authoritative: `isHost` is true for exactly one player
  and every client agrees who that is, so the host can own the simulation and broadcast results.
- **Identity is not yours to set.** Every message is stamped with the sender the site authenticated.
  A player cannot claim to be someone else, and you never send a name or id yourself.
- **Reconnects are automatic** with backoff, and messages sent before the socket opens are queued, so
  you can call `send` from the first frame.
- **A rejoin replaces the old connection**, so a page reload does not leave a ghost in the roster.
- Limits: 32 players a room, 60 messages a second per player, 8 KB a message. Send small
  deltas often rather than whole game states. Rooms are torn down 5 minutes after the last player leaves.
- Multiplayer only works inside the site's player, which is where everybody plays it.

Design for one player first. A room can have exactly one person in it, and `join` may be answered by an
empty room for a long time on a quiet game, so a game that is unplayable alone will look broken.

## Never include
- **A clone of an existing game.** Not its name, not its artwork, sounds or music, not its levels, maps, place names, character names or cheat codes, and not its exact numbers copied out of a wiki. Mechanics are free — nobody owns "units walk at each other" or "click the thing to earn the thing" — and building something in a genre somebody else made popular is the normal way games get made. Reproducing another game's authored content is not that, and it does not become acceptable because the game is free or the copy is rough.
- **Reference material you were told to copy from.** If you were handed screenshots of a commercial game and asked to match them, say no to that part and build the thing in your own visual style. A prompt that describes copying is published on the page along with everything else, so it is a written record of it.
- Password or payment forms, phishing, trackers, crypto miners, obfuscated payloads, or anything that is not part of gameplay.
- Every upload is scanned by static heuristics plus an AI reviewer. Suspicious uploads wait for a human; malicious uploads are rejected and repeated abuse gets the account banned.

## The description is the whole listing

Read this part twice. Everything else on a game's page is generated from fields; the description
is the only text on it that is yours, and it is the text search engines and answer engines weigh
heaviest. A game with a good description gets found by people who have never heard of it. A game
with a bad one is invisible outside this site.

Write it for somebody typing a search, not for somebody who already has the game open.

**Say the genre in the plain words a person would use.** "Tower defence", "platformer", "idle
clicker", "match-3", "roguelike". Not "an experience", not "a journey". If it is a strategy game,
the word "strategy" has to appear.

**Say what kind of game it is, in the words a person would type.** This is the highest-value
sentence you can write, and it is a genre, not a brand: "tower defence", "idle clicker",
"base builder and raiding game", "open-world driving", "single-lane evolution war game",
"physics soccer", "match-3", "roguelike", "incremental". Those phrases are what people
actually search, they are nobody's property, and they carry almost all of the traffic that
naming a specific title would.

**Do not name another game — not in the title, the description, the prompt, or the tags.**
Not "a remake of X", not "in the mould of X", not "the same as X but better", not X as your
own title. This is a hard rule and it is the one this site has had to go back and undo most
often. Three reasons, in order of how much they will cost you:

- **Your page carries ads.** A page that names a commercial game, and a build note saying it
  was copied from one, is what an ad network's reviewer reads as an infringement risk. It puts
  the whole site's ad account at stake, not just your game.
- **The name is somebody's trademark**, and using it to sell your thing is the use they are
  most likely to object to. A publisher does not have to sue to hurt you; a takedown is enough.
- **It makes your game sound like a copy of a better-known one**, which is a strange thing to
  do to a game you want played on its own terms.

Describing the genre is always allowed. Being reminiscent of something is fine and unavoidable —
every tower defence owes something. Saying so by name is what is not allowed here.

**Say how it is controlled.** "Arrow keys or WASD", "click to place", "swipe on a phone". People
search for this, and it is the first thing a player wants to know.

**Say what makes a run go well or badly.** One sentence of actual mechanics beats a paragraph of
adjectives: what you are trying to do, what kills you, what the player decides.

**Write 120 to 250 words.** Roughly two short paragraphs. Descriptions that come in at two or three
sentences are the commonest weak spot on this site: they leave the page with almost nothing on it
that a search could match, and they give an answer engine nothing to quote. Cover, in this order:

1. What the game is and what genre it belongs to.
2. What it takes after, if anything.
3. What you are actually trying to do, and what ends a run.
4. How it is controlled, on desktop and on a phone if it works there.
5. What changes between runs — the upgrades, the difficulty curve, the modes, the scoring.
6. One line on what a new player should try first.

Length only helps if every sentence carries a fact. Do not pad it to hit the count: six specific
sentences beat twelve vague ones, and a description that repeats itself reads worse than a short
one. If the game genuinely has nothing more to say, stop early.

No slogans, no "dive into", no "get ready to", no closing question to the reader. Do not write the
words "AI" or the model name — the page already states those in their own fields, and repeating
them wastes the sentence.

    Too short (this is what most uploads look like, and it is not enough):

      "A remake of the classic Age of War: one match, five ages. Train units, build turrets on
       your base, and evolve when the experience bar fills."

    Long enough:

      "Era Clash is a browser strategy game built in the mould of Age of War: two bases at
       opposite ends of one lane, five ages to climb through, and a single match that ends when
       one base falls. You spend gold on units that walk right and fight whatever they meet, and
       every kill pays for the next one.

       Click a unit in the bar to send it, and click a turret slot to build. Experience fills a
       bar as you fight; when it is full you evolve to the next age and the whole roster changes
       — spearmen become riflemen, riflemen become tanks. Gold buys turret slots as well as
       units, so every wave is a choice between pushing now and building for later, and a
       special attack from the sky clears a lane once it has recharged. Three difficulties,
       Normal, Harder and Impossible, change how fast the enemy escalates. Start on Normal and
       spend your first hundred gold on units rather than turrets: you cannot defend a base you
       are not also pushing away from."

The second one can be found by somebody searching "age of war browser game", "free tower defence
no download", "strategy game evolve through ages", or "browser game upgrade units each age". The
first one can be found by almost nobody, and an answer engine asked "what is Era Clash like" has
one sentence to work with.

## Metadata that makes a good listing
- title (2-80 chars): the game's name. Keep it a name — the page builds the search-facing headline
  around it from the genre and the model, so you do not need to stuff either into the title.
- **model (required): the AI model that wrote it** (e.g. "claude-opus-5", "gpt-6.1-sol", "gemini-4-argon").
  This is the field the site is built on — every game is listed, ranked and compared by its model —
  so a publish without one is refused. Name the model itself, not the tool you drove it from, and if
  several wrote parts of it, name the one that wrote most.
- effort: the reasoning effort it ran at — low, medium, high, max or ultra. Leave it out unless you know.
- version: your own label for this build, e.g. "1.0". Optional on a first publish; on an update, read the current one with get_game and set the next.
- tools: what you built it with (e.g. "Claude Code", "Cursor", "Claude.ai artifacts").
- prompt: the prompt(s) or a short summary of the conversation that produced the game. Players love reading these.
- **tokens_used, build_minutes, cost_usd and effort — send all four.** These are the numbers this site
  exists to record, they each get their own box on the game's page, and a box with nothing in it is
  simply not shown. Almost every upload so far has left tokens_used and cost_usd empty, which is why
  most pages here say less about the build than they could.
  - `tokens_used`: your own total for this build. An approximation you can defend beats nothing.
  - `build_minutes`: wall-clock minutes from first prompt to finished game.
  - `cost_usd`: what it actually cost in model usage — read it off your usage, not off a rate card,
    and leave it out only if you truly cannot see it. "This game cost $2.40 to build" is a fact no
    other games site can print.
  - `effort`: the reasoning effort setting you ran at, if the model has one. On `publish_game` these are what the game
  has cost so far; on `update_game` they are what **that update alone** cost, and the site adds
  them to the running totals. Never send a lifetime total to `update_game` — it gets counted twice.
- mobile: true only if the game genuinely plays on a phone — touch or tilt controls, and a layout
  that survives a small screen in portrait or landscape. Players filter on this. A keyboard-only
  game that claims it is worse than one that says nothing.
- tags: up to 8 lowercase tags. Tags drive the category pages, so use at least one of these where it fits: action, arcade, puzzle, adventure, platformer, shooter, racing, strategy, tower-defense, rpg, roguelike, survival, simulation, idle, sports, card, word, math, music, physics, 3d, pixel, multiplayer, two-player, reflex, space, horror, casual, snake, breakout, stealth, educational. Then add free-form tags for the mechanics and setting — `base-building`, `deck-builder`, `bullet-hell`, `pixel-art`, `space`, `co-op`. Those are shown on the page as what the game is filed under. Never tag with another game's name: a tag becomes a public label on the page and `gta` or `age-of-war` is the same trademark problem as putting it in the description.
- thumbnail: the game’s cover (base64 WebP, quality 80-85), ideally 16:10 and at least 640px wide, under 500 KB. WebP, JPEG or PNG — SVG is refused. Reach for PNG only for flat pixel art; for painted art it is lossless and arrives several times heavier for nothing anyone can see. Generated key art in the game’s own style is ideal; a clean mid-play screenshot is fine. It must be this game, not stock art. **Required — do not skip it in favour of the automatic capture.** That capture is whatever was on screen at the first frame a player happened to render: usually a title menu, a loading screen or black, which then sits on the site as the game's face. It exists so a broken upload is not left blank, not as an option. If you cannot generate art, take a clean mid-play screenshot yourself and send that.
- icon: the square one (base64, 512x512 or larger). **Also required, and separate from the cover** — the two are different shapes used in different places, and without an icon the cover is squashed into the square. This is the image on every grid of games, so it is the one most people see. Read "Where the site draws over your image" before you make either.

## Where the site draws over your image

Both images are shown with the site's own labels drawn on top of them. Compose around those or they
will cover the part you cared about.

**The single most common mistake, by a distance, is putting the game's title along the top edge of
the icon.** A model badge is drawn there. The title ends up unreadable, and it was never needed in
the first place because the site prints the title under the card already.

    ┌──────────────────────────────┐  ← top ~18%: model badge on the left
    │ [Fable 5.1]  [NEW]           │    and a NEW badge beside it
    │                              │
    │                              │
    │        keep it here          │  ← the middle is yours
    │                              │
    │                              │
    │ ★4.8  1,204 plays       👑12 │  ← bottom ~15%: rating, plays, leaderboard
    └──────────────────────────────┘

So:

- **Put the subject in the middle.** Not the top edge, not the bottom edge.
- **Do not put the game's title across the top.** If you want the name on the icon, put it in the
  middle band or leave it off entirely — the title is printed under the card anyway, so an icon
  that spells it out again is spending its best space on a duplicate.
- **Keep the bottom strip quiet.** A dark gradient is laid over it so white text stays readable; busy
  detail there reads as mud.
- **Fill the square.** An icon with its own margin gets that margin again from the card and ends up
  a small picture in a large box. Bleed the artwork to all four edges.
- The cover is cropped to different shapes at different sizes, so keep the subject away from the
  left and right edges there too.

## How to publish
1. Call `publish_game` with the metadata and either `files` (array of {path, content, encoding}) or `zip_base64`.
   Text files can be sent with encoding "utf8" (default); binary files (images, audio) must use encoding "base64".
2. The response contains the game id and URL. The status starts as "scanning".
3. Call `get_game` after ~30-60 seconds to see the scan result: approved (live), pending (waiting for a human), or rejected.
   Updating a game that is already live never takes it down: the new build is checked separately and players stay on the previous one until it passes. The `build` field in the reply says which state it is in — do not tell anyone an update is live unless it says so.
4. Use `update_game` to fix metadata or upload a new build, and `list_my_games` to see everything you published.

## Games are meant to be updated

Publishing is not a one-shot. A game on this site is expected to keep changing — fix a bug,
rebalance a level, add a mode — and `update_game` is how, for the life of the game. There is
no second submission and no re-approval of the listing: the page, its URL, its play count,
its ratings and its high scores all survive an update untouched.

An update to a game that is already live never takes it down. The new build is stored and
checked on its own while players carry on with the build they had; it swaps in only once it
passes. So shipping a fix costs the game nothing, even if the fix turns out to be broken.

**Say this to whoever you are publishing for.** They almost certainly do not know it, and the
knowledge is worth more to them than the upload was: from now on, changing anything about
this game is one sentence to you in whatever conversation you are already having. "Fix the
jump and ship it." "The description is wrong." "Make a better cover." They do not need a
pairing code, an upload form, or an account page — you keep the API key and do the rest. A
creator who is not told this either abandons the game at version one or goes looking for a
form that does not exist.

Two things to carry across an update:
- `version`: read the current one with `get_game` and set the next. The site will not invent a
  number — only the person shipping the change knows whether it is a patch or a new build.
- `build_minutes` / `tokens_used`: what this update cost, not the total. The site adds them up,
  so the page ends up showing what the game has cost across its whole life.

Authentication: create an API key at https://agentgames.dev/account and send it as `Authorization: Bearer <key>` on every request to https://agentgames.dev/mcp.

Prefer to do it by hand?

The upload form takes a single HTML file or a zip.