GUIDE
How can Codex use game art assets?
Codex does not draw sprites. What it can do is read a structured art project over a read-only MCP endpoint and turn it into working code. Connect it to PX-Art with an HTTP MCP entry, and it can resolve which asset to use, download the file into your repo, and write frame math, foot pivots, nine-slice panels and tile lookups that match the real metadata.
Where the boundary is
Codex is a coding agent. It reads repositories, writes code and runs commands. It does not produce pixel art, and no MCP connection changes that — the PX-Art surface it connects to is read-only, with no generation tool in it.
What changes is the quality of the code it writes about art. Without a connection, Codex is guessing: it hardcodes a frame width, assumes eight frames, stretches a panel and centres a sprite on its bounding box. With a connection, every one of those numbers is a value it looked up.
Connecting Codex
- Unlock and issue the token in PX-ArtTools area, MCP access, or Settings and MCP access. The plaintext appears once — copy it then. Any subscription payment or top-up purchase unlocks read-only MCP permanently; there is no separate MCP charge.
- Add an HTTP MCP server entry to Codex's configCodex reads MCP server definitions from its own configuration file. The three values it needs are the transport (HTTP, not stdio), the URL
https://px-art.com/api/mcp, and the headerAuthorization: Bearer pxr_YOUR_TOKEN. Consult your installed Codex version for the exact key names — the endpoint side is what is fixed here. - Verify outside the agent firstRun the
tools/listPOST by hand before debugging inside Codex. If curl returns twelve tools and Codex does not, the problem is in the client config, not the server. - Keep the token out of the repositoryIt belongs in your local agent config. A token committed to a repo is a leaked credential; regenerate it in the panel, which invalidates the old one immediately.
- Give Codex the orientation order in your prompt
list_games, thenlist_game_structureandlist_characters, thenlist_asset_families, thensearch_assets, thenpreview_assets, and only then downloads. Skipping tosearch_assetswith a made-up notebook ID is the most common wasted turn.
What Codex should ask for, and in what order
list_games -> notebookId 12, design {styleKey, tags, tileSize}
list_game_structure -> pageId / tagId meanings
list_characters -> one logical character's views, tags and assets
list_asset_families -> which family can cover this screen at all
search_assets -> shortlist with role, family, component params
preview_assets -> look at up to 8 candidates before committing
get_asset_downloads -> up to 50 originals, short-lived URLs
list_asset_families is the step agents most often skip and most benefit from. A family is one generated set — a UI kit, or the phases of one effect — and it reports a role distribution such as {"panel":2,"button":4,"bar":1,"slot":2} plus the original generation description. That answers "can this set cover my HUD" in one call, instead of paging through assets whose names are auto-numbered.
Turning metadata into correct code
Frame math
A multi-frame asset is one horizontal strip. The catalogue gives both the strip size and the single-frame size, and the relationship is exact:
w = frameWidth * frames // whole strip
h = frameHeight // single frame height
frame i = crop at (i * frameWidth, 0), size frameWidth x frameHeight
The trap: a scene node's rect is the single-frame size, not the strip width. Codex laying out with w will place every animated node several times too wide, and collision boxes will follow it.
Never play a strip blindly
Check stripKind before writing playback code:
stripKind | Meaning | Correct handling |
|---|---|---|
animation | Real animation — character action, effect, animated tile | Loop at the given fps |
states | Button states | Index by interaction; names in component.states, such as normal, hover, pressed, disabled |
glyphs | Glyph row such as 0-9 | Index by character; range in component.glyphs |
fps is only present when stripKind is animation. If Codex reaches for fps and finds nothing, that is the signal to stop writing a tween.
UI components
UI assets carry a component block, and ignoring it produces visibly wrong output:
"component": {"type": "panel9", "slice": {"l": 8, "r": 8, "t": 8, "b": 8}}
That is a nine-slice instruction: corners never scale, edges stretch along one axis only, the centre stretches both ways, and the slice values are pixel insets from each edge. Straight-stretching this panel smears its rounded corners and its outline. button4 means a four-state strip, numbers means a bitmap digit row with a glyphs range, and tile carries tileSize and loop.
Sampling
Every asset declares sampling as nearest, linear or auto. Pixel art rendered with linear turns to mush. This is a one-line setting that Codex can get right automatically once it reads the field.
Anchoring
Sprite sheet exports carry the foot pivot as an Aseprite slice, in cell-local coordinates. Anchoring a character to its bounding-box centre instead of its foot pivot is what makes characters sink into the floor on some frames and hover on others.
Delivering a whole scene into the repo
For a full arranged screen, get_scene_bundle gives Codex a complete, verifiable file plan:
scene-42-r7/
scene.json # written verbatim from the "content" field
map.tmj # Tiled map; absent for non-map scenes
assets/88-grass.png # downloaded from downloadUrl, then size + hash checked
Four rules cover the whole procedure: create the root directory; write any file that has content; download any file that has a downloadUrl; verify size and the returned SHA-256. Paths in scene.json and map.tmj already reference assets/{assetId}-{filename}, so nothing needs rewriting.
For tilesets specifically, the in-app export ZIP already contains four files that a code agent can consume directly:
atlas.png # tiles laid out by row and column
tileset.json # name, image, tileSize, columns, tileCount, tiles[]
tileset.tsx # Tiled tileset XML, per-tile role / sourceRow / sourceCol / assetId
tileset.tmj # a preview map that opens in Tiled directly
Each entry in tiles[] carries id, assetId, name, file, role, sourceRow, sourceCol, atlasCol and atlasRow — enough for Codex to build a role-keyed lookup rather than hardcoding atlas indices:
{"name": "forest", "image": "atlas.png", "tileSize": 32,
"columns": 8, "tileCount": 24,
"tiles": [
{"id": 0, "assetId": 301, "name": "grass 01", "file": "301.png",
"role": "fill", "sourceRow": 0, "sourceCol": 0,
"atlasCol": 0, "atlasRow": 0}
]}
Limits and caveats
- Codex cannot generate art through this connection. Read-only means read-only; new assets come from the app.
- It cannot see the assembled scene. Thumbnails per asset exist, capped at 220px on the longest side. There is no whole-scene render, so visual acceptance still happens in your engine.
- Download URLs expire. Codex should fetch into the repo in the same turn and never write a URL into a config file or commit one.
- Batch limits are real.
preview_assetstakes at most 8 IDs,get_asset_downloadsat most 50, and a scene bundle packs at most 50 dependent assets — over the limit the tool errors clearly instead of silently truncating. - Back off on 429. Bulk parallel pulls trip the rate limit; use the
Retry-Aftervalue. - Do not claim engine support that is not there. There is a thin adapter on the Godot side; Tiled files and Aseprite-format JSON are standard interchange formats. Anything else is integration you write.
- Generation is probabilistic — assets need human review before production. Commercial use of legitimately generated assets is permitted, but third-party rights, applicable law and AI provider terms remain your responsibility, and AI output is neither guaranteed exclusive nor guaranteed copyrightable.
More on the agent-facing data model: AI game assets for coding agents and MCP game assets. What the strips themselves are made of: sprite sheet generator.
FAQ
Can Codex generate pixel art or sprites?
No. Codex is a coding agent with no image model in this loop, and the PX-Art MCP surface it connects to is read-only with no generation tool. Art is generated by you in the app; Codex reads the result and writes the code that loads it.
How do I connect Codex to PX-Art?
Add an HTTP MCP server entry to Codex's configuration pointing at https://px-art.com/api/mcp with an Authorization: Bearer pxr_... header. The transport is Streamable HTTP rather than stdio. Verify the connection with a plain tools/list POST via curl before debugging inside the agent.
What is the single most common mistake an agent makes with sprite data?
Using the strip width where the frame width belongs. A multi-frame asset stores w as frameWidth multiplied by frames, while a scene node's rect is the single-frame size. Laying out with w makes every animated node several times too wide and drags collision boxes along with it.
How does Codex know whether to animate a multi-frame asset?
By reading stripKind. Only animation should be played, at the fps the asset provides. states means index by interaction using component.states, and glyphs means index by character using component.glyphs. The fps field is present only for animation strips.
What does Codex do with a tileset export?
The tileset ZIP contains atlas.png, tileset.json, tileset.tsx and tileset.tmj. tileset.json lists each tile with id, assetId, name, file, role, sourceRow, sourceCol, atlasCol and atlasRow, which lets an agent build a role-keyed lookup instead of hardcoding atlas indices. tileset.tsx and tileset.tmj open in Tiled directly.
Does connecting Codex cost credits?
No. MCP calls are read-only and free. Credits are spent only on generation in the app. Read-only MCP is unlocked permanently by any subscription payment or top-up purchase, and paid status is checked both at token issue and on every call.
Related
Give Codex real numbers instead of guesses
Frame widths, strip kinds, nine-slice insets, sampling modes and foot pivots — read from your own project rather than assumed.
Create a free accountSee pricingNew accounts start with 20 credits. Formal checkout is still under review and not open yet.