# Publish a game from Claude Code over MCP

Connect Claude Code to the FanZero MCP server with one command, then ask it to publish the game in your folder. It checks the build, asks you before it publishes anything or offers creators a share, submits the game and fixes what the review asks for. A human curator plays every game and gives the final yes before it is listed. Listing a game is free.

Codex, Cursor, VS Code and other MCP clients work the same way: their setup is [further down](#codex).

## What you need

- A browser game: an `index.html` that runs with no network, at most 8 MB in total. The [listing guidelines](https://fanzero.app/docs/listing-guidelines) have every rule. No game yet? Ask your agent to make one first; the server also has a one-file starter game (resource `fanzero://starter/index.html`).
- Claude Code, or another MCP client.
- A FanZero studio key (step 1).
- Your terms for creators: what content you suggest (a livestream, video, short, post or playtest) and the share you offer (above 0%, at most 50% of the game's net revenue). Your agent asks you; it never makes them up.

## 1. Get a studio key

Make a studio at the [studio desk](https://fanzero.app/studio) and copy its key, or let your agent do it: it asks you for a studio name and a contact, then calls `create_studio` once. The key starts with `gmk_` and is shown only once. There is no key recovery yet, so keep a copy in your password manager. Put it in an environment variable (your shell profile keeps it), never in git:

```
export FANZERO_API_KEY=gmk_your_key
```

## 2. Connect Claude Code

```
claude mcp add --transport http fanzero https://fanzero.app/mcp --header "Authorization: Bearer $FANZERO_API_KEY"
```

The shell fills in `$FANZERO_API_KEY` when you run the command, so Claude Code saves the key itself. In a game repo you can use a project `.mcp.json` instead, which reads the key from the environment each time Claude Code starts:

```json
{
  "mcpServers": {
    "fanzero": {
      "type": "http",
      "url": "https://fanzero.app/mcp",
      "headers": {
        "Authorization": "Bearer ${FANZERO_API_KEY}"
      }
    }
  }
}
```

Letting your agent create the studio? Connect before you have a key: `read_listing_guidelines`, `check_build`, `whoami`, `create_studio`, `browse_games` work without one, and in the session that creates the studio the agent passes the new key as `api_key` on every call. Add the key to your setup afterwards.

## 3. Hand it the game

From your game's folder, paste this into Claude Code:

```
Read https://fanzero.app/agents.md, then publish the game in this folder to FanZero.
```

Your agent reads [the guide written for it](https://fanzero.app/agents), then:

1. `read_listing_guidelines`: the build rules, the pitch and the pact rules.
2. `check_build` until the build passes. No key, nothing is saved.
3. `whoami`: which studio its key belongs to.
4. It asks you what it needs (next step).
5. `submit_game` with the pitch, the pacts and the build. The automated checks and the critic run inside that call.
6. It follows `next_step` in the answer: fix and resend, wait for the curator, or tell you the game is live.

## 4. What it asks you first

| it asks | why |
| --- | --- |
| Which game: the folder or file | So it publishes the right thing |
| The title, tagline and description it drafted | You approve the words creators read |
| Genre (arcade, action, puzzle, roguelike, platformer, cozy, strategy, rhythm, horror, weird) and stage (napkin, prototype, vertical-slice, alpha) | They place the game in the catalog |
| Every pact term: the action (livestream, video, short, post, playtest), `share_pct` (above 0, at most 50), optional requirement text and audience preference | A pact is a revenue offer, so the terms are yours |
| `store_url`, if the game already sells somewhere | Sales there count during a window too |
| Permission to publish, and that you own or may use every asset | The game goes public |
| Who pays the creators, and how | FanZero does not move money |

## 5. Three gates: Bouncer, Critic, Curator

| gate | what happens |
| --- | --- |
| The Bouncer | Automated checks on the code and the pitch: runs offline, has input, no trackers or external assets, pacts that make sense. Blocking issues come back as notes your agent can fix. |
| The Critic | An AI review that scores fun potential, clarity and the pitch (0 to 100) and leaves notes. It can ask for changes; it can't reject a game. Claude reviews when the server has an Anthropic API key (up to 50 builds a day by default), house heuristics otherwise. |
| The Curator | A person plays the game and gives the final yes before it is listed. Later builds of a listed game go live after the automated checks. |

| status | means |
| --- | --- |
| `checking` | The Bouncer and the critic are running. It only lasts while submit_game or update_game runs. |
| `changes_requested` | Blocking issues, a critic verdict of "changes", or a curator asked for changes. Fix it and send update_game. |
| `awaiting_curator` | Passed the automated checks. A human curator will play it; nothing to do but wait. |
| `listed` | Live in the catalog. Creators can request its open pacts with dated action plans. |
| `rejected` | A curator said no. Final for this game. |

There is no fixed time for the curator. Your agent checks `get_review` about once a day rather than in a loop.

## 6. Fix what the review asks for

On `changes_requested`, your agent fixes everything under `blocking` (and the critic's concerns or the curator's note), runs `check_build` again, then sends the new build with `update_game` and the `game_id`. Only a new build re-runs the review, and it never calls `submit_game` twice for the same game.

Once a game is listed, a new build that passes the automated checks goes live at once, with no person playing it first. Play a patch yourself before your agent ships it.

## 7. When creators request a pact

There are no notifications yet: your agent looks at `list_my_games` about once a day, and the [studio desk](https://fanzero.app/studio) shows the same requests and proposed content dates.

- **Accepting a request** commits you to your `share_pct`% of the game's net revenue, from every store it sells on, for 28 days starting at the earliest proposed action. The creator submits the formats and dates with the request; the studio accepts once.
- **Your yes for the request.** The server refuses an MCP acceptance without `human_approved: true`. The agent shows you the terms, actions and window dates first. New pacts have no proof review or second confirmation.
- **Money moves outside FanZero.** It records the pact, content plan and window dates; you pay the creator directly. Every rule: [pact rules](https://fanzero.app/docs/pact-rules).
- **Legacy only.** Older claims may still need `confirm_delivery` after you check the proof and approve it. That tool does not apply to new pacts.

What your agent does on its own: `read_listing_guidelines`, `check_build`, `whoami`, `get_review`, `list_my_games`, `browse_games`. What waits for your OK: `create_studio`, `submit_game`, `update_game`, `add_pact`, `close_pact`, `respond_to_claim`, `confirm_delivery`.

## Codex

```
codex mcp add fanzero --url https://fanzero.app/mcp --bearer-token-env-var FANZERO_API_KEY
```

Or in `~/.codex/config.toml`:

```toml
[mcp_servers.fanzero]
url = "https://fanzero.app/mcp"
bearer_token_env_var = "FANZERO_API_KEY"
```

Codex reads `FANZERO_API_KEY` when it starts. Then hand it the same line as in step 3.

## Cursor

`.cursor/mcp.json` in the project, or `~/.cursor/mcp.json` for every project. Cursor reads `FANZERO_API_KEY` when it starts.

```json
{
  "mcpServers": {
    "fanzero": {
      "url": "https://fanzero.app/mcp",
      "headers": {
        "Authorization": "Bearer ${env:FANZERO_API_KEY}"
      }
    }
  }
}
```

The [dev page](https://fanzero.app/devs) also has an install button for Cursor, with the config it installs printed next to it.

## VS Code

`.vscode/mcp.json`. VS Code asks you for the key (input `fanzero_key`).

```json
{
  "servers": {
    "fanzero": {
      "type": "http",
      "url": "https://fanzero.app/mcp",
      "headers": {
        "Authorization": "Bearer ${input:fanzero_key}"
      }
    }
  },
  "inputs": [
    {
      "type": "promptString",
      "id": "fanzero_key",
      "description": "FanZero studio API key",
      "password": true
    }
  ]
}
```

## Other MCP clients

The same URL and header, in your client's own format, often like this:

```json
{
  "mcpServers": {
    "fanzero": {
      "type": "http",
      "url": "https://fanzero.app/mcp",
      "headers": {
        "Authorization": "Bearer <your FanZero API key>"
      }
    }
  }
}
```

claude.ai, Claude Desktop and ChatGPT connectors sign in with OAuth or connect without auth, and FanZero has no OAuth yet. Connect without auth and let the agent pass `api_key` on each studio tool call; the key then sits in the conversation, so keep that chat private.

## No MCP client?

Any HTTP client works. This lists the tools:

```
curl -sS --json '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' https://fanzero.app/mcp
```

The [agent guide](https://fanzero.app/agents) shows how to call any tool this way, and how to send big builds over the HTTP API.

## Limits

- `submit_game` and `update_game` wait for the review. With the Claude critic that takes up to about 25 seconds by default, so allow tool calls at least 60 seconds.
- Builds: at most 8 MB.
- Calls per client address per hour (a deployment can change them; an error says the one in force and how long to wait):

| calls | per hour |
| --- | --- |
| create_studio (also POST /api/studios) | 10 |
| submit_game and update_game together (also over HTTP) | 60 |
| check_build | 120 |
| creator account sessions | 20 |
| creator pact requests (legacy bucket name: pitch) | 30 |
| plays counted on game pages (POST /api/games/:slug/play) | 60 |

## Common questions

### Does it cost anything?

No. FanZero charges nothing to list a game or to take a pact. You pay the creator the agreed share of revenue earned during an accepted pact's window.

### Can I publish a game that already sells on Steam or itch.io?

Yes. Send a browser build or a slice of it, pick the closest stage and add `store_url`. Sales there count during a creator's window.

### Does my agent decide anything for me?

It runs the checks, reads the review and sends fixes while the game is in review. Publishing, listing text, every pact term, anything on a listed game and every answer to a creator wait for your OK.

## More

- [The agent guide](https://fanzero.app/agents): what your agent reads (also as markdown at /agents.md)
- [MCP tools](https://fanzero.app/devs/mcp): every tool, and which ones wait for you
- [Listing guidelines](https://fanzero.app/docs/listing-guidelines): what gets a game listed
- [Pact rules](https://fanzero.app/docs/pact-rules): what accepting a request commits you to
