Metadata-Version: 2.4
Name: astrocade-creator-mcp
Version: 0.2.3
Summary: Astrocade Creator MCP — pull and edit your Astrocade games locally over MCP (stdio).
Requires-Python: >=3.13
Description-Content-Type: text/markdown
Requires-Dist: mcp<2,>=1.23
Requires-Dist: pydantic<3,>=2
Requires-Dist: PyJWT[crypto]<3,>=2.13
Requires-Dist: requests<3,>=2.32.4
Requires-Dist: aiohttp<4,>=3.11
Requires-Dist: html5lib==1.1
Provides-Extra: dev
Requires-Dist: pytest; extra == "dev"
Requires-Dist: pytest-asyncio; extra == "dev"
Requires-Dist: mypy==1.17.0; extra == "dev"

# Astrocade Creator MCP

A local (stdio) [MCP](https://modelcontextprotocol.io) server that lets a creator pull, edit,
push, and publish the games already on their Astrocade account — as ordinary local files.

## Add to your MCP client

Point your MCP client (Claude Code, Claude Desktop, …) at it — no install step, `uvx` fetches it
from PyPI on demand:

```json
{
  "mcpServers": {
    "astrocade": {
      "command": "uvx",
      "args": ["astrocade-creator-mcp@latest"]
    }
  }
}
```

Or via the Claude Code CLI: `claude mcp add astrocade -- uvx astrocade-creator-mcp@latest`.

Targets **prod** by default — a creator sets nothing. To point at stage instead, add
`"env": { "ASTROCADE_CREATOR_MCP_ENV": "stage" }` to the entry.

### Sign-in

Sign in once, ahead of time — this prints a URL to open in your browser (**Google or Apple**):
```bash
uvx astrocade-creator-mcp login
```
The tokens are cached under `~/.astrocade` and silently refreshed after that, so you only do this
once (until you `logout` or the session is revoked). Username/password accounts aren't supported yet.

On a **headless / WSL / remote box** with no desktop browser, `login` still prints the URL — open
it on your host (WSL2 forwards the `localhost` callback back automatically). Tool calls themselves
never open a browser: one made without a valid session fails fast telling you to run `login`,
rather than silently hanging on a callback you can't see.

`uvx astrocade-creator-mcp logout` revokes and clears the cached tokens (e.g. to switch accounts).
Token cache dir: `~/.astrocade` (override with `ASTROCADE_TOKEN_CACHE_DIR`).

## Tools

- `list_my_games` — your games (drafts included).
- `pull_game` / `push_game` — check a game out (files + metadata, as JSON), save edits back as a draft. `push_game` can also update metadata (`title`, `description`, `thumbnail_url`).
- `publish_game` — first-time publishing submits the game for review; on an already-published game it pushes the saved draft live. Returns the play URL. Your agent asks you to confirm before it publishes, and is told not to publish unless you ask it to — publishing reaches real players and can't be undone from here.
- `upload_asset` — upload a local image/audio/3D file to the Astrocade CDN and get its URL. Asset URLs in `asset_map.json` must come from here (or from a `generate_*` tool) — external / `data:` URLs are rejected on push.
- `generate_image` / `generate_sound_effect` / `generate_music` / `generate_animation` — generate an asset with AI. See [Generating assets](#generating-assets).
- `check_asset_generation_status` — collect the result of a `generate_*` call.
- `check_wish_status` — poll an AI "wish" that's in flight (wishes are submitted on astrocade.com; `push_game`/`pull_game` surface the request id when one is running).
- `list_lib_apis` / `get_lib_api` — browse the Astrocade `lib` API reference.
- `get_game_guidelines` — the platform's rules for writing game code (sandbox limits, mobile-first layout, persistence). Read this before writing or editing `game_code.html`.

### Generating assets

Each `generate_*` tool submits the job and returns a `request_id` right away; poll
`check_asset_generation_status` with it until the status is terminal. Images take around two
minutes, audio around ninety seconds, and animation up to ten. `generate_animation` needs a source
image that is already on the CDN, so generate or upload one first and pass the URL it returned.

On `success` the response carries an `asset_map_entry` — a ready-to-merge `{asset_id: {...}}`
object. Merge it into your local `asset_map.json` keeping **every** field (animation and audio
entries carry metadata beyond the URL), then `push_game`. Nothing is written to the game for you,
same as `upload_asset`.

Generation costs the creator money, and results live only in the running MCP server: if it
restarts mid-flight, the result is lost. So never resubmit an asset that is still in progress.
Terminal responses carry `safe_to_retry` and `may_have_been_charged` — trust those rather than
inferring from the status name.

### The editing session

The first `pull_game` is a checkout: write the returned files (`game_code.html`,
`game_config.json`, `asset_map.json`, and `persistent_storage_config.json`, which is empty until
the game stores something) to a local folder together with a `.astrocade.json` session
file (`{game_id, sync_token, env}`). Add `.astrocade.json` to the folder's `.gitignore` — it's
per-machine session state, not project content. Edit the files with your normal tools, then
`push_game` the changed ones by their local file *paths*, passing the session's `sync_token` as
`expected_version` so a concurrent change upstream is usually caught (a stale write surfaces as a
conflict to reconcile, rather than silently overwriting the other change). Every successful push
returns a new sync token — update `.astrocade.json` with it.

Because `push_game` takes the file *paths* (the server reads them off disk) rather than inline
content, even a large `game_code` never hits an MCP client's inline-argument size cap.
