> For the complete documentation index, see [llms.txt](https://wiki.playgama.com/playgama/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://wiki.playgama.com/playgama/mcp.md).

# MCP Server: Publish Games from Your AI Agent

Connect Codex, Claude Code, Cursor, VS Code or claude.ai to your Playgama cabinet: create a game, upload builds and covers, edit in-app items, publish a sandbox.

The Playgama MCP server connects your AI coding agent — Codex, Claude Code, Cursor and others — to your Playgama developer cabinet. Instead of switching to the browser to fill in the game form, upload a new build or fix a price in the in-app catalog, you ask the agent to do it from the project you are already working in.

It is a remote server built on the [Model Context Protocol](https://modelcontextprotocol.io), an open standard for how an AI assistant discovers and calls tools.

**Endpoint:** `https://developer.playgama.com/api/mcp`

## What you can do with it

* **Create a game and fill in its form** — title, description, how-to-play, supported devices and languages, screen orientation, distribution.
* **Upload a build** — the agent packs the zip, uploads it and adds it to the game's form, then polls until unpacking and the build check are finished.
* **Publish to a sandbox** — a public link anyone can play, without moderation, for playtesting and sharing a work in progress. Like every game on Playgama, the build must have the Playgama Bridge SDK integrated.
* **Bring players to the sandbox** — share the game on any platform and get a free boost: an ad campaign built from the game's covers that sends players to the sandbox link.
* **Upload covers** — square, portrait and landscape, checked against the exact size the form requires.
* **Manage the in-app catalog** — read the products, change one, write the whole catalog back.
* **Create and edit leaderboards** — the same tags your game passes to the Bridge SDK.
* **Test before submitting** — get a QA Tool link for an uploaded build, or for a game you are serving from `localhost`.
* **Read moderation feedback** — the correspondence on a game and whether it can be submitted right now.

Submitting a game to moderation is deliberately **not** on this surface — see [What a connected agent can and cannot do](#what-a-connected-agent-can-and-cannot-do).

## Before you start

* A [Playgama developer account](https://developer.playgama.com/) with the sign-up finished. Until it is, the cabinet refuses the connection — there would be no games for the agent to reach.
* One of the supported clients: **Codex**, **Claude Code**, **Cursor**, **VS Code** (with Copilot / MCP support), **claude.ai** or **Claude Desktop**.
* **A game with the Playgama Bridge SDK integrated.** Bridge is required for every game on Playgama — the sandbox included, and the sandbox takes **Playgama Bridge 2.2.0 or newer**. If your game does not have it yet, ask the agent to integrate it before the first upload: `get_bridge_sdk_docs` serves the [Bridge SDK docs](/playgama/bridge-sdk/getting-started.md), and the [Game checklist](/playgama/mcp/game-checklist.md) lists the required steps in order.

There is no token to create or copy. The server uses OAuth: your client finds the sign-in from the endpoint, opens the cabinet in your browser, and you allow the connection there.

## Step 1. Add the server to your client

The [MCP page in the cabinet](https://developer.playgama.com/mcp) shows the same snippets with the endpoint filled in.

{% tabs %}
{% tab title="Codex" %}
Run this once:

```bash
codex mcp add 'playgama-developer-cabinet' --url 'https://developer.playgama.com/api/mcp'
```

Codex opens the browser to sign in right away.
{% endtab %}

{% tab title="Claude Code" %}
Run this once:

```bash
claude mcp add --transport 'http' 'playgama-developer-cabinet' 'https://developer.playgama.com/api/mcp'
```

Then run `/mcp` inside Claude Code, pick `playgama-developer-cabinet` and choose to authenticate.
{% endtab %}

{% tab title="Cursor" %}
Add this to `~/.cursor/mcp.json`:

```json
{
  "mcpServers": {
    "playgama-developer-cabinet": {
      "type": "http",
      "url": "https://developer.playgama.com/api/mcp"
    }
  }
}
```

Cursor asks you to sign in when it first connects to the server.
{% endtab %}

{% tab title="VS Code" %}
Add this to `.vscode/mcp.json`:

```json
{
  "servers": {
    "playgama-developer-cabinet": {
      "type": "http",
      "url": "https://developer.playgama.com/api/mcp"
    }
  }
}
```

The file holds no secret, so it is safe to commit. VS Code asks you to sign in when it starts the server.
{% endtab %}

{% tab title="claude.ai / Claude Desktop" %}
Open **Settings → Connectors → Add custom connector** and enter the endpoint `https://developer.playgama.com/api/mcp`. Then click **Connect** on the new connector.
{% endtab %}
{% endtabs %}

## Step 2. Allow the connection

The client opens a page on `developer.playgama.com` in your browser.

1. Sign in to the cabinet if you are not signed in yet.
2. Check what the page shows: the **account** and **organization** the agent will act for, the **agent** asking, **where it returns** after you answer, and what it will be able to do.
3. Click **Allow**. The browser hands control back to the client, and the agent is connected.

{% hint style="warning" %}
Allow only a connection you started yourself. If the page opens without you having just added the server — or it names an agent or a return address you do not recognise — click **Deny**.
{% endhint %}

The request on that page is valid for 10 minutes. If it has expired, start the connection again from the client.

{% hint style="info" %}
The server registers under the name `playgama-developer-cabinet`. Keep it as-is — clients use it as an identifier, and the name says which environment this is, so connecting more than one Playgama deployment from the same machine does not overwrite the other.
{% endhint %}

## Step 3. Check that it works

Ask the agent:

> List my games on Playgama.

If the connection is good, it calls `list_applications` and answers with your games. A brand-new account has none yet, and an empty list is just as good an answer — the connection works, and you can ask the agent to create the first game right away:

> Create a game called "Coin Town" on Playgama — it is made with Unity.

If the agent reports an authentication error instead, see [Troubleshooting](#troubleshooting).

## What a connected agent can and cannot do

**A connected agent reaches exactly the games you see in your cabinet, and nothing else.**

<table><thead><tr><th width="220">Can</th><th>Tools</th></tr></thead><tbody><tr><td>Read your games</td><td><code>list_applications</code>, <code>get_application</code>, <code>get_submission_state</code>, <code>list_moderation_comments</code>, <code>get_archive_qa_tool_link</code>, <code>get_local_game_qa_tool_link</code>, <code>get_sandbox_state</code>, <code>get_sandbox_share</code>, <code>get_sandbox_traffic</code>, <code>get_launch_steps</code></td></tr><tr><td>Create new games</td><td><code>create_application</code></td></tr><tr><td>Edit the game form</td><td><code>update_application_form</code></td></tr><tr><td>Manage the in-app catalog</td><td><code>list_in_app_products</code>, <code>replace_in_app_products</code></td></tr><tr><td>Create and edit leaderboards</td><td><code>list_leaderboards</code>, <code>create_leaderboard</code>, <code>update_leaderboard</code></td></tr><tr><td>Upload game builds</td><td><code>start_archive_upload</code>, <code>get_archive_status</code>, <code>confirm_archive_upload</code></td></tr><tr><td>Upload cover images</td><td><code>start_cover_upload</code>, <code>confirm_cover_upload</code></td></tr><tr><td>Publish a game to the sandbox: a public link, no moderation</td><td><code>publish_sandbox</code></td></tr><tr><td>Bring players to the sandbox with an ad campaign that cannot be undone</td><td><code>start_sandbox_traffic</code></td></tr><tr><td>Read the Playgama Bridge SDK docs and the game checklist</td><td><code>get_bridge_sdk_docs</code>, <code>get_game_checklist</code></td></tr></tbody></table>

Deliberately withheld — these stay actions a human takes in the cabinet:

* **Submit a game to moderation.** The agent prepares everything; you press the button.
* **Roll a game back to the last submitted version.** It would erase changes made in the browser too, not only the agent's own.
* **Upload or delete screenshots and other assets**, and remove any attachment from the form.
* **Delete a leaderboard.** Deleting takes its scores with it and cannot be undone.
* **See payouts.** Financial data is not on this surface at all.

Deleted games are not part of this surface: they never appear in a list, and every tool refuses their id.

The full list with parameters is in the [Tools reference](/playgama/mcp/tools.md).

## A typical session

Uploading a new version of a game, end to end:

> Take the build in `./dist`, zip it, upload it to my game "Coin Town" as version 1.4.2, and tell me when it has finished processing.

The agent finds the game with `list_applications` and reads `get_launch_steps` for it — its path in order and the step it is on — reading it again after each step. It reads `get_game_checklist` and checks the build against each item, then calls `start_archive_upload`, PUTs the zip itself, calls `confirm_archive_upload`, then polls `get_archive_status` until its `state` leaves `CHECKING`, and reads back what the check says — a build the check does not pass is fixed and uploaded again, never published.

Other things worth asking for:

> Read the moderation comments on Coin Town and fix what they asked for in the form.

> Test this game locally — I'm serving it on `http://localhost:5503/`.

> Add a consumable product `coins_500` for $4.99 to Coin Town's catalog.

> Which of my games can be submitted to moderation right now, and what is blocking the rest?

When the agent is done, open the game in the cabinet, click **Test Game** to run the QA Tool, and then **Submit Game**.

## The sandbox

A **sandbox** is a public page where anyone with the link plays the build you uploaded — no submit, no certification, no moderation. It is meant for playtesting and for showing a work in progress; the main Playgama catalog is still reached only through moderation.

> Publish the latest build of Coin Town to its sandbox and give me the link.

The agent calls `publish_sandbox` with an archive that has finished unpacking, after the build check has answered: a build it passes is published, and one it reports a problem on, or could not check, is refused — the agent tells you what the check says, in its own words (`get_bridge_sdk_docs` has the integration docs). The Playgama Bridge SDK is required for every game, the sandbox included, and a build it was not detected in is one of the builds the check refuses: the agent hands you the QA Tool certification link that shows why the SDK did not start, fixes the integration and uploads a new build. The sandbox also takes Playgama Bridge 2.2.0 or newer only: a build on an older version, or one whose version the check could not read, is refused, and the agent updates the SDK and uploads a new build. After the publish it hands you the `url` from the answer, then offers you the ready post and share links from `get_sandbox_share`. What is worth knowing before you ask for it:

* **The game goes live immediately.** There is no draft state and no review step.
* **One sandbox per game, and its address never changes.** Re-publishing replaces what is live and keeps the players' saved progress, because the origin stays the same.
* **A repeat is safe.** Publishing the same archive with the same form again writes nothing and answers the link that is already live.
* **Three publications per rolling hour.** Enough for iterating by hand, low enough to stop an agent that publishes on every loop. Only publications that actually change something count.
* **A sandbox can be blocked.** If it is, the page stops serving and `publish_sandbox` is refused until the block is lifted.
* **The cabinet publishes to the same sandbox.** The game's page has a publish button beside **Test Game** and shows the live link with the build that is on it, so a sandbox the agent published is visible — and replaceable — in the browser too.

A published sandbox still has no players until someone shares the link. To bring some:

> Bring traffic to Coin Town's sandbox.

The agent reads `get_sandbox_traffic` — whether the game is eligible and what the package is — and helps you share the game with the post and links from `get_sandbox_share`. Once you have posted, it asks you to paste the links to your published posts, and when you agree to the run it calls `start_sandbox_traffic` with them. It creates an ad campaign in the Playgama DSP with banners cut from the game's covers, pointed at the sandbox page, and follows the run it started until it leaves `PENDING`.

* **Free traffic is a bonus for sharing the game.** Post about it on any platform and give the agent one to three public HTTPS post links — one is enough, and more posts do not make the boost bigger. The links are checked for format, not content; the agent never posts for you and must not make links up.
* **Once per game, for up to three games per organization over its lifetime.** Earlier free launches without sharing do not use this bonus. How long a boost serves and how many bonuses are left come from the `offer` the agent reads — ask it to show you before it starts. Paid traffic is available in the cabinet; MCP does not purchase it.
* **A started run cannot be undone.** It spends its budget over its window.
* **It needs covers and the Bridge SDK.** The banners are cut from the covers of the live revision, and traffic goes only to a build in which the Bridge SDK was found — upload covers and publish again first.
* **Whether a run can start is the current verdict.** `get_sandbox_traffic` answers it, campaign capacity included; earlier free or paid campaigns can run alongside the share bonus. A run that failed gives the bonus back, so starting again with the same post links is safe.

## Security

* **Verify the endpoint.** The only official address is `https://developer.playgama.com/api/mcp`. Take snippets from the [MCP page in the cabinet](https://developer.playgama.com/mcp), not from third-party marketplaces.
* **Check the consent page before you allow.** It is always on `developer.playgama.com`, and it names the account, the agent and where it returns. A page elsewhere asking for your cabinet password is not ours.
* **See and revoke connected agents.** The [MCP page](https://developer.playgama.com/mcp) lists every agent connected to your account, when it was connected and when it last refreshed its access. **Revoke** cuts it off on its very next call; to use it again, connect it again.
* **Access renews itself and lapses on its own.** The agent's access lasts an hour and the client renews it quietly; an agent unused for 30 days has to connect again. Each client keeps its own connection, so a laptop and claude.ai are two lines you can revoke separately.
* **Nothing to leak into a repository.** No config above holds a secret. The client keeps its access in its own storage.
* **Connecting an agent gives it the access the "Can" list describes.** Review what it is about to do — keep your client's confirmation prompts on for write operations. Every write tool on this surface is annotated as destructive precisely so your client asks before running it.
* **Two capabilities reach outside the cabinet.** `publish-sandbox` puts a game in public, and `start-sandbox-traffic` starts an ad campaign that sends players to it and cannot be undone. Each has its own line on the consent page. If you do not want an agent publishing or advertising anything at all, do not ask it to — and review the call when it does.
* **Beware of prompt injection.** Text your agent reads — a moderation comment, an issue, a web page — can contain instructions aimed at your tools. Do not let an agent act on untrusted text without review.
* **An agent you do not recognise is a reason to revoke.** If the list shows a connection you did not make, or one still refreshing after you stopped using it, revoke it.

## Limits and behaviour worth knowing

* **A form save is partial.** A field the agent leaves out keeps its stored value. Enum arrays (devices, languages, excluded platforms) are replaced whole.
* **The in-app catalog write is not partial.** `replace_in_app_products` takes the target state: a product left out is deleted. The agent must read the catalog first and pass its `checksum` back, so a change someone made in the browser meanwhile cannot be silently overwritten — the call is refused instead.
* **Uploads never travel through MCP.** Both archives and covers are three steps: start (you get a URL signed for one hour, for exactly that byte length and content type), PUT the file yourself, confirm. Limits: **300 MB** per build zip, **10 MB** per cover.
* **A new archive is added, not swapped in.** Every archive stays in the form next to the earlier ones, which is why builds should be named with their version. Removing one is a human action in the cabinet.
* **A cover replaces the one in its slot** — square 800×800, portrait 1080×1920, landscape 1920×1080, PNG or JPEG, exactly those dimensions.
* **A sandbox publication is public and immediate**, capped at 3 changing publications per rolling hour per game. Re-publishing the same thing writes nothing.
* **Free sandbox traffic is a share bonus** — once per game, for up to three games per organization over its lifetime; earlier free launches without sharing do not count. `start_sandbox_traffic` takes 1–3 public post links. Whether a run can start now is what `get_sandbox_traffic` answers, and the package is in its `offer`.
* **`list_applications` takes paging only** — no status filter and no search, 20 rows by default and 100 at most. The order is fixed (newest first), so paging visits every game exactly once. Games with an empty title are not listed, matching the cabinet.
* **A refusal is an answer, not a failure.** Business errors (a field that failed validation, a game that is not yours, a stale catalog checksum) come back as readable tool results the agent can act on.
* **The transport is stateless Streamable HTTP over `POST`.** No session is kept between calls, and one request may carry at most 32 JSON-RPC messages — relevant only if you write your own client; the supported clients call tools one at a time.
* **A failed write may still have landed.** If the server answers 5xx or the connection drops during a write, the outcome is genuinely unknown — the agent is told so and should read the state back rather than retrying blindly.

## Troubleshooting

<table><thead><tr><th width="260">What you see</th><th>What to do</th></tr></thead><tbody><tr><td>Every call fails with 401, or the client says it needs to authenticate</td><td>The agent was revoked, or it went unused for 30 days. Connect it again from the client — in Claude Code through <code>/mcp</code>.</td></tr><tr><td>The browser never opens</td><td>Run the connect step again; most clients print the sign-in link, which you can open by hand. Make sure the client config has only <code>type</code> and <code>url</code>.</td></tr><tr><td>The consent page says the request has expired, was already answered or cannot be found</td><td>The request lives 10 minutes and can be answered once, by the account that opened it. Start the connection again from the client.</td></tr><tr><td>The consent page refuses because there is no organization</td><td>The registration is not finished, so the agent would reach no games. Finish it in the cabinet and connect again.</td></tr><tr><td>The client reports <code>invalid_redirect_uri</code> when connecting</td><td>That client returns to an address the server does not accept yet. Use one of the supported clients, and tell <a href="mailto:developer.success@playgama.com">developer.success@playgama.com</a> which client you tried.</td></tr><tr><td>Your config still sends an <code>Authorization</code> header with a <code>pgm_mcp_</code> token</td><td>It keeps working for now. Remove the header and connect again as in Step 1.</td></tr><tr><td>A tool answers 403 for a game you own</td><td>The id belongs to someone else's account, or the game is deleted. Re-read the id from <code>list_applications</code>.</td></tr><tr><td>A game is missing from <code>list_applications</code></td><td>It has no title yet, or it is deleted. An untitled draft is still reachable if the agent already has its id — give the agent the id from the cabinet URL.</td></tr><tr><td><code>confirm_archive_upload</code> / <code>confirm_cover_upload</code> answers 409</td><td>Nothing is stored at the upload URL yet: the PUT did not finish. Retry the PUT, or start the upload again if the hour has passed.</td></tr><tr><td>A cover confirm answers 422</td><td>The file is not the format the upload was started as, not the exact size of its slot, or not a complete image. Fix the file and start a new upload.</td></tr><tr><td>The catalog replace answers 409</td><td>The catalog changed since it was read. The agent should read it again, re-apply the change and retry.</td></tr><tr><td><code>publish_sandbox</code> is refused</td><td><code>ARCHIVE_PENDING</code> — the build has not finished unpacking (poll <code>get_archive_status</code>; if it already says <code>DONE</code>, the archive cannot be served — upload it again); <code>ARCHIVE_FAILED</code> — the zip could not be used, upload a fixed one; a build-check refusal — it carries the check's own reason code and a message saying what is wrong and what to do; fix the build and upload a new archive; <code>ARCHIVE_CHECKING</code> — the check has not answered yet, poll <code>get_archive_status</code>; <code>BRIDGE_VERSION_OUTDATED</code> — the build runs a Playgama Bridge older than 2.2.0, update the SDK and upload a new archive; <code>BRIDGE_VERSION_UNKNOWN</code> — the check could not read the Bridge version, make sure the game uses 2.2.0 or newer and upload it again; <code>NO_TITLE</code> — fill in the game's title first; <code>RATE_LIMITED</code> — 3 publications in the last hour, wait; <code>BLOCKED</code> — the sandbox was blocked, contact support.</td></tr><tr><td>The agent will not publish: the Bridge SDK was not detected in the build</td><td>That is the rule, not a fault: every game needs the Playgama Bridge SDK, the sandbox included, and the build check refuses a build it was not detected in — <code>publish_sandbox</code> would answer that refusal too. Open the certification link from <code>get_archive_qa_tool_link</code> — its Build Startup section shows why the SDK did not start — fix the integration (the agent reads the docs with <code>get_bridge_sdk_docs</code>) and upload a new build.</td></tr><tr><td><code>start_sandbox_traffic</code> is refused</td><td><code>SHARE_REQUIRED</code> — no post links were passed: share the game and give the agent 1–3 public post links; <code>INVALID_POST_URL</code> — a link is not a valid public HTTPS URL, or the same link is given twice; <code>NO_SITE</code> — publish to the sandbox first; <code>NO_COVERS</code> — upload covers and publish again; <code>ANALYSIS_PENDING</code> — the build is still being analyzed, ask again shortly; <code>NO_BRIDGE</code> — integrate the Bridge SDK (the agent reads the docs with <code>get_bridge_sdk_docs</code>) and publish again; <code>RUN_IN_PROGRESS</code> — a campaign is already pending or live, or campaign capacity is full; <code>PAYMENT_REQUIRED</code> — the game's share bonus is used, paid traffic is in the cabinet; <code>ORG_LIMIT</code> — the organization has used its three share bonuses, lifetime; <code>BLOCKED</code> — the sandbox was blocked; <code>DSP_DISABLED</code> — not available right now. The full list is in the <a href="/playgama/mcp/tools.md#get_sandbox_traffic">Tools reference</a>.</td></tr><tr><td>A traffic run shows <code>FAILED</code></td><td>Its <code>failureReason</code> says why. The share bonus was given back, so fix the cause and start again with the same post links.</td></tr><tr><td>The client reports the server does not support <code>GET</code>/<code>DELETE</code></td><td>Expected: the transport is stateless Streamable HTTP over <code>POST</code> only. Make sure the client is configured with type <code>http</code>, not <code>sse</code>.</td></tr></tbody></table>
