# Connect and publish

New games and replacement builds are published through MCP by signed-in creators. Creators manage only their own work.

> **Private preview.** Publishing works for invited preview accounts through the AppAfterApp publisher helper: a local MCP server, named `appafterapp-publisher` (formerly `vibedemo-publisher`), that runs on the creator's own computer. Either name may appear in your client; they are the same tools. The hosted AppAfterApp connector is set up as in [Connect your assistant](#connect-your-assistant), but only invited preview accounts can approve it. Public sign-up and a downloadable helper are not available yet. If your client lists none of the AppAfterApp connector's tools, the `appafterapp-publisher` tools or the `vibedemo-publisher` tools, stop: return the prepared package and report **Not submitted: publisher tools not connected.** Do not invent a server URL, installation command, access token or successful upload.

## Connect your assistant

> **Creators can't publish yet.** Only invited preview accounts can approve the connection, so for everyone else these steps stop at AppAfterApp's approval page. They are here so setup is ready when publishing opens.

Add the AppAfterApp connector once in each app. Its address is `https://appafterapp.com/mcp`. The first time it's used, your browser opens AppAfterApp: sign in and press **Approve**. Uploading a build runs one command on your computer, so publish from an app that can run commands: the **Code** tab of the Claude desktop app, Claude Code in a terminal, or Codex.

**Added AppAfterApp before?** Remove the connector you added earlier, then add it again with the steps below, so it uses `https://appafterapp.com/mcp`. In Codex, **Uninstall** the saved server first (in a terminal: `codex mcp remove` and its name).

- **Claude desktop app, Code tab:** while signed in to claude.ai, open [Add AppAfterApp to Claude](https://claude.ai/customize/connectors?modal=add-custom-connector&connectorName=AppAfterApp&connectorUrl=https%3A%2F%2Fappafterapp.com%2Fmcp). Check the name and address, add it, then choose **Connect** to sign in. It then appears in local sessions of the desktop app's Code tab. On Team and Enterprise plans, an admin adds it.
- **Claude Code in a terminal (beta):** add the connector with the same link. It appears in Claude Code when you're signed in with the same claude.ai account. The terminal asks you to sign in to AppAfterApp once more, even when the desktop app is already connected: run `/mcp`, choose **claude.ai AppAfterApp**, then **Authenticate**. On Windows, if PowerShell's script policy blocks `claude`, start it with `claude.cmd`.

    Having trouble? Email support@appafterapp.com.

**Codex (beta).** For now Codex is set up by hand; a listing in OpenAI's directory will replace these steps.

- **Codex app:** open **Plugins** → **MCPs** → **Add** → **Connect to a custom MCP**.
    1. Choose the type **Streamable HTTP** first. The default, STDIO, looks similar but silently fails, with no sign-in button.
    2. Name: `appafterapp`. URL: `https://appafterapp.com/mcp`. Leave Bearer token and Headers empty.
    3. Save. Then open **appafterapp**, choose **Authenticate**, and press **Approve** on AppAfterApp's page.
- **To change a saved server's type**, **Uninstall** it first, then add it again.

**Codex in a terminal** takes two commands. The Codex app and terminal share these settings, so set up either one.

```text
codex mcp add appafterapp --url https://appafterapp.com/mcp
codex mcp login appafterapp
```

**Which account?** Your AppAfterApp account is whichever account your browser is signed in to on appafterapp.com when you approve. Check the name on the approval page.

**If Codex stops showing the AppAfterApp tools, or doesn't offer to sign in,** its saved sign-in has expired, and reinstalling doesn't clear it. In a terminal, run `codex mcp logout appafterapp`, then `codex mcp login appafterapp`, press **Approve**, and restart Codex. On Windows, `codex` may not be on your PATH: it's at `%LOCALAPPDATA%\OpenAI\Codex\bin\<folder>\codex.exe`.

Having trouble? Email support@appafterapp.com.

The connector has three tools: `get_account`, `submit_build` and `get_submission`. `submit_build` takes the build's details, its TESTING report and the file's size and SHA-256, never its contents, and returns a one-time upload address. The assistant uploads the file there with one command, which the app asks you to approve, then calls `get_submission`.

## Client readiness

The publisher helper is set up only on the preview owner's computer. There is no download or setup guide for it, so creators can't publish yet.

| Client | Coverage | Private preview status |
| --- | --- | --- |
| Claude Code | MCP publishing through the local helper | Works on the preview owner's computer only. |
| Codex | MCP publishing through the local helper | Not set up: Codex has no publisher tools yet. |
| Claude Desktop | MCP publishing through the local helper | Works on the preview owner's computer only. |

Use a client running on the creator's computer: the helper reads the package from local disk, so a cloud or browser-chat session cannot reach it. Website file-upload forms are not part of this workflow.

## Metadata through MCP

The assistant fills in structured metadata through the creator's authorised MCP connection. The creator signs in and approves the connection in the browser when asked; they do not need to write JSON or fill in website forms. MCP is the primary submission route, and optional `demo.json` is a portable copy that fills gaps only. Explicit publishing-request values take priority.

Submit the exact tested build, its metadata and the separate private [TESTING record](docs-reference.html#testing-confirmation) using the tools' own input schemas. Do not place private testing information inside publicly served game files.

## Publish step by step

The helper has six tools. Read each tool's description and input schema before calling it; the schemas are authoritative.

**Say this once, at the start of an upload.** Tell the creator in one or two sentences that uploading is mostly mechanical, so maximum effort is not needed (a fast model, or their usual model at normal effort, is enough), and how long your play-test will take: about 5 minutes, or up to 10 for a bigger game. You cannot change your own model or effort; the creator decides whether to switch before you begin. Play-test it yourself by default. If your browser fails, retry once; only if it fails again, say what failed and offer the creator's choices from [Keep testing proportionate](docs-prepare.html#test-the-final-package): "Me (the creator): I'll test it and tell you the results" or "Me: I already tested it". Ask the creator one question at a time, with clear choices where possible; never bundle questions.

1. **`connect_account`** opens the creator's browser to approve the connection; if that browser is not signed in to AppAfterApp, the creator signs in first and the approval continues. It returns the account it connected. The game belongs to that account. Confirm it is the account the creator intends.
2. **Add the required cover, then place the final ZIP in the helper's build folder.** Every build needs a cover at `publishing/coverImage.webp` in the ZIP: AI-generated cover art, a designed SVG rendered to PNG or WebP, or a screenshot of the game. It must look like the real game and show the game's name in the image; see [Make a cover](docs-prepare.html#make-a-cover). A single HTML file can't carry a cover: package it as `index.html` in a ZIP with the `publishing/` folder. The helper reads only that one folder, set when the helper was installed; paths are relative to it. A path on another machine, or outside that folder, is not reachable.
3. **`begin_testing`** with that `packagePath` stages a clean private copy and returns a `testRunId` and a `servedRoot`. Its warnings say at once if the cover is missing or unusable. Serve `servedRoot` from a fresh local static server, test it in a fresh browser context against the [testing checklist](docs-prepare.html#test-the-final-package), and do not edit its files.
4. **`finish_testing`** with the `testRunId` and the compact TESTING report from the actual testing. Unperformed checks are Not run, never Pass.
5. **`submit_build`** with the `packagePath`, the `testRunId` and the metadata. For a replacement, pass the existing project's `projectId`; do not create a duplicate project. It refuses a build without a usable cover before uploading anything; otherwise it uploads the package and returns an `operationId`, the `projectId` and a state.
6. **`get_submission`** with the `operationId` reports the current state. **`amend_submission`** corrects details, or attaches a newly finished test report, without uploading unchanged files again.

Supply the title, build file, project type, phone capability, explicit Active yes/no, public `creationModels` attribution and the engine/framework in `engine`. Present optional `engineVersion` beside Engine as Version (optional); omit it if unavailable. Reuse existing valid values and ask for missing choices. If the creation model cannot be established, explicitly record `Unknown`; never guess or silently omit it. Optional files remain optional, including `demo.json`. Keep testing-model attribution in the separate private TESTING record.

Ask once whether the creator wants the One Shot label, and explain it in one line: one creator prompt, with no follow-up instructions or manual code changes. It is the creator's call: follow their answer, and don't refuse or argue. If yes, send `oneShot` true and their exact original prompt, verbatim, as `originalPrompt`; it is shown publicly. If no, leave both out.

For a replacement, preserve still-valid project details and the saved explicit Active answer unless the creator changes them. Reassess the submitted build's engine/version, creation models, capabilities and One Shot eligibility; use a fresh test run for the new files rather than inheriting stale claims. Reuse accurate information already available instead of asking the creator to re-enter it.

## Submission and checks

The platform receives a candidate, checks the package and assets, and assesses isolated hosted gameplay, UX and UI. A candidate is not playable simply because the transfer succeeded. During the private preview, a person also plays each candidate before it publishes. Failed, suspicious, incomplete or uncertain assessments remain held with reasons; the live build stays untouched until a replacement passes.

UX/UI findings block publication when they prevent normal play, such as essential controls that cannot be reached or required instructions that cannot be read. Cosmetic preferences and style suggestions are feedback, not blockers or review holds by themselves. Package/security and functional gameplay checks still apply.

### Cover codes

A build without a usable cover is refused at upload, before any check runs. The helper's `submit_build` refuses it before uploading anything, and the platform refuses it again if a submission arrives without one or the received package's cover breaks a rule. The refusal gives a `code` and a message saying what to add or fix:

| Code | Meaning |
| --- | --- |
| `cover_missing` | No `publishing/coverImage` file in the ZIP, or a single HTML file, which can't carry one. |
| `cover_ambiguous` | More than one recognised cover file, so none was chosen. Keep exactly one. |
| `cover_invalid` | The cover breaks a [format or size rule](docs-reference.html#build-limits): not a readable PNG, JPEG or WebP, an extension that doesn't match its real format, not landscape, smaller than 960 × 600, larger than 4096 px on a side, or over 2 MB. |

Add or fix the cover, run `begin_testing` and `finish_testing` on the new ZIP, and submit again. The game's name on the cover can't be checked automatically, so the reviewer checks it; a cover without it, or one that doesn't look like the real game, can be held.

Invalid optional metadata returns a warning and is ignored, keeping valid values. Such a warning alone does not reject or hold the build. Required details must still be valid. See [metadata](docs-reference.html#metadata).

## Understand the outcome

| Returned state | What to tell the creator |
| --- | --- |
| `needs_information` | Required details are missing or invalid. Ask for them and correct the submission with `amend_submission`; the files already received are kept. |
| `queued` / `checking` | The platform received the candidate and is checking it. The `phase` says which check is running; `manual` means it is waiting for the preview reviewer. It is not published yet. |
| `held` | The checks did not pass. Report the returned reasons and the correction needed. Do not claim the game is live or promise a review time. |
| `rejected` | The candidate will not publish. Report the reasons; a corrected build is a new submission. |
| `ready_for_private_play` | Published to the private preview. The project's page now plays this build. |

## Interruptions and corrections

Keep the `operationId` and `projectId` returned by `submit_build`. After a timeout or interruption, call `get_submission` before starting another submission. To resume an interrupted upload of the same unchanged package, pass the same `operationKey` to `submit_build`; changed files are a new test run and a new submission. Do not blindly duplicate uploads.

Use returned errors to correct the affected file or detail while preserving valid information. Each correction through `amend_submission` takes a new `amendmentKey`; reuse a key only to retry the same correction. Review response times are not guaranteed.

## Report back

Give the creator a compact, evidence-based result:

- **Artifact:** filename, format, size, SHA-256 and engine/export version.
- **Prepared details:** title, project type, phone capability, explicit Active answer, creation-model attribution including any explicit `Unknown`, Engine and optional Version; name any answers still missing.
- **Tests:** browser/device, real hardware or emulation, actions and Pass / Fail / Not run / Not applicable with reasons.
- **Submission:** not submitted (and why), or the returned `operationId`, `projectId` and state.
- **Publication and play:** whether publication was confirmed, and which hosted checks were actually performed.
- **Next action:** the specific correction, missing decision or remaining check.
