Metadata-Version: 2.4
Name: astrocade-creator-mcp
Version: 0.2.0
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.
- `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`, plus `persistent_storage_config.json` when the game uses
persistent storage) 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.
