pyxel-mcp
This server lets an AI agent run and inspect Pyxel games headlessly — validating scripts, simulating input, capturing screenshots/frames, and reading game state, assets, audio, and pixels — without opening a window.
Validate scripts with AST parsing and anti-pattern checks before running (
validate_script).Run and screenshot a script after N frames, with scale and timeout control (
run_and_capture).Capture multiple frames for animation/transition verification (
capture_frames, comma-separated frame list).Simulate play by sending scheduled keyboard/mouse input and capturing frames (
play_and_capture).Read game state: dump App instance attributes as JSON, single-frame or multi-frame diffs (
inspect_state).Inspect the screen as a compact palette-index grid for programmatic comparison (
inspect_screen).Compare two frames to find changed pixels, percentage, and regions — visual regression testing (
compare_frames).Analyze palette/color usage and contrast issues across Pyxel's 16 colors (
inspect_palette).Inspect sprites: pixel data, symmetry checks, color usage in an image bank (
inspect_sprite).Render a whole image bank (256×256) as a screenshot to check sheet organization (
inspect_bank).Inspect tilemaps: tile grid, usage stats, bounding box, imgsrc (
inspect_tilemap).Analyze layout: text positions, horizontal balance, centering problems (
inspect_layout).Render audio: export a sound or music slot to WAV with waveform/note analysis (
render_audio).Get Pyxel info: package location, examples path, API stubs (
pyxel_info).
Note: the schema's tool names and granularity differ from the README's documented 8-tool set (e.g., run, read_image, read_tilemap, read_audio, diff_frames), so clients should follow the schema as the source of truth.
Enables AI to autonomously run, verify, and iterate on retro game programs created with the Pyxel engine, providing tools for Python script validation, state inspection, and visual/audio analysis.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@pyxel-mcpRun main.py and capture a screenshot to verify the game visuals"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
pyxel-mcp
Let AI agents play, watch, and measure Pyxel games. pyxel-mcp is an MCP server that runs a Pyxel script headlessly, feeds it scheduled input, stops when a condition holds, and hands back the facts: screenshots, pixel grids, game state, assets, audio, and frame diffs.
Why
An agent can write a Pyxel game in seconds, but it cannot open a window, press the arrow keys, or look at the screen. Editor-bound engines solve this with MCP servers that live inside the editor. Pyxel has no editor process to attach to, so pyxel-mcp drives the game itself:
Headless and deterministic. Every call runs the script in a fresh subprocess with SDL dummy drivers, an optional RNG seed, and a frame budget. The same call gives the same frames on a laptop or in CI.
Input as data. Buttons, axes, and mouse position are scheduled per frame, so a playtest is a JSON document the agent can rerun and extend.
Stop on the event, not the clock.
until="score >= 1"ends the run at the first frame where a game attribute holds, and"frame": "end"snapshots capture that moment.Facts, not scores. Tools report pixels, values, and measurements. Deciding whether the game is good stays with the agent and the person asking for it.
See the frame in the result.
inline: truereturns a PNG as MCP image content, so the model looks at the screen without a second file read.
Related MCP server: Aseprite MCP
Install
Register the stdio server with your client:
claude mcp add --scope user pyxel -- uvx pyxel-mcpcodex mcp add pyxel -- uvx pyxel-mcpgemini mcp add pyxel uvx pyxel-mcpFor Cursor (~/.cursor/mcp.json), a project-scoped Claude Code .mcp.json, or any other client that reads the common JSON format, add:
{
"mcpServers": {
"pyxel": {
"command": "uvx",
"args": ["pyxel-mcp"]
}
}
}VS Code uses .vscode/mcp.json with a top-level servers key and "type": "stdio"; Codex CLI can also be configured in ~/.codex/config.toml as [mcp_servers.pyxel]. Run uvx pyxel-mcp install to print every variant.
Claude Code users can instead install the pyxel-skill plugin, which registers this server together with the skill that teaches agents how to use it:
claude plugin marketplace add kitao/pyxel-skill && claude plugin install pyxel@pyxel-skillRestart the client after changing its configuration. The server writes this diagnostic to stderr:
[pyxel-mcp] starting - 8 toolsPython 3.11+ is required, and Pyxel >= 2.9.6 is installed as a dependency. Script tools execute local Python in subprocesses to isolate Pyxel state, but they do not sandbox untrusted code. See SECURITY.md.
How an agent uses it
flowchart LR
W["Write or edit<br>game.py"] --> V["validate"]
V --> R["run<br>inputs · until · snapshots"]
R --> O{"Inspect facts<br>state · pixels · log"}
O -- "defect" --> W
O -- "looks right" --> A["read_image · read_tilemap<br>read_audio · diff_frames"]
A --> D["Report evidence"]The loop is deliberately small. The separate pyxel-skill project teaches agents when to use each tool and what counts as enough evidence; this package only supplies the observations.
Tools
Every script argument is a file path, not Python source. Relative asset paths inside the script resolve from the script's directory, exactly as under python game.py.
Tool | Returns |
| Syntax errors and recognizable Pyxel code patterns, without executing. |
| Headless frames, scheduled input, logs, and |
| Installed versions, paths, bundled examples, and resource URIs. |
| Palette colors and image-bank indices in use. |
| Image-bank pixels and an optional PNG render. |
| Tile coordinates, source bank, usage counts, bounds, and an optional render. |
| A rendered sound or music WAV plus measurable audio data. |
| Pixel differences between two PNG files. |
All tools declare input and output schemas. Every result includes ok and errors.
Captured PNGs can travel inside the result: set inline: true on a screen_image snapshot, or inline=true on read_image and read_tilemap, and the PNG is returned as MCP image content next to the structured data. A single inline frame may omit its output path; the file is then written under the system temp directory and its path is still reported, so diff_frames and later comparisons keep working. At most 12 images are embedded per call.
Example
Hold right, jump at frame 25, stop as soon as the score changes, and look at that frame:
{
"script": "/absolute/path/game.py",
"frames": 600,
"random_seed": 7,
"inputs": [
{"frame": 0, "buttons": ["KEY_RIGHT"]},
{"frame": 25, "buttons": ["KEY_RIGHT", "KEY_SPACE"]},
{"frame": 26, "buttons": ["KEY_RIGHT"]}
],
"until": "score >= 1",
"snapshots": [
{"kind": "state", "frame": "end", "attrs": ["score", "player.x"]},
{"kind": "screen_image", "frame": "end", "scale": 3, "inline": true}
]
}The result reports until_met, the reached frame_count, the requested state values, the PNG path, and the PNG itself as image content. Artifact paths you choose must be absolute. Read log even when ok is true, and inspect captured images directly when appearance matters.
Resources
pyxel://run-snapshots-schema— completerun.snapshotsgrammar, including"end", ranges, andinline.pyxel://validation-patterns— categories reported byvalidate.pyxel://palette/default— default palette table.pyxel://examples/{name}— source for an example bundled with the installed Pyxel package; discover names withpyxel_info.
Update
uvx caches packages. Force a refresh with:
uvx --refresh-package pyxel-mcp pyxel-mcp installTroubleshooting
If tools do not appear, look for the
starting - 8 toolsdiagnostic and restart the client.If
runfails, inspecterrors,exit_status, andlog.If a script cannot find an asset, check the path relative to the script file, not to the client's working directory.
If a validation category is unfamiliar, read
pyxel://validation-patterns.
Related
Pyxel — the retro game engine this server observes.
pyxel-skill — the Agent Skill that turns these tools into a build-and-verify workflow.
CHANGELOG.md — what changed in each release.
MCP Registry
mcp-name: io.github.kitao/pyxel-mcp
License
MIT — see LICENSE.
Available Tools
8 toolsdiff_framesARead-onlyIdempotent
Compare two PNG frames pixel by pixel and return their changed region and ratio.
| Name | Required | Description | Default |
|---|---|---|---|
| frame_a | Yes | ||
| frame_b | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | |
| ratio | No | |
| errors | Yes | |
| region | No | |
| size_a | No | |
| size_b | No | |
| warnings | No | |
| identical | No | |
| size_match | No | |
| total_pixels | No | |
| changed_pixels | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds behavioral detail: pixel-by-pixel comparison and the output of a changed region plus a ratio. This goes beyond the annotations without contradicting them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, efficient sentence with no filler. It front-loads the core operation and the output, making it easy to scan and understand quickly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values do not need to be described. However, the missing input format details and lack of guidance on edge cases like mismatched image sizes make the description incomplete for confident invocation. It is adequate but has a clear gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema only defines two required strings with no format, and schema description coverage is 0%. The description identifies the parameters as 'PNG frames', which adds some meaning, but it does not clarify whether frame_a and frame_b are file paths, data URIs, raw byte strings, or something else. This leaves a critical ambiguity for the agent.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Compare'), identifies the resource ('two PNG frames'), and states the result ('changed region and ratio'). This clearly distinguishes it from sibling tools like read_image or run, which perform different operations.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The purpose implies when it should be used: whenever two PNG frames need to be compared. However, there is no explicit guidance about when to use this tool instead of alternatives, no exclusions, and no mention of prerequisites such as matching dimensions or format.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pyxel_infoARead-onlyIdempotent
Report installed versions, paths, examples, and Pyxel resource URIs.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | |
| errors | Yes | |
| examples | No | |
| resources | No | |
| stubs_path | No | |
| pyxel_version | No | |
| python_version | No | |
| pyxel_mcp_version | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is fully covered. The description adds useful behavioral detail by specifying exactly what the tool reports, which is beyond what the empty input schema and annotations reveal.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence with the verb and key output categories front-loaded. Every word contributes meaning, and there is no redundancy or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter, read-only, non-destructive tool with an output schema and strong annotations, the description is sufficient for an agent to select and invoke it correctly. The only minor gap is the lack of explicit guidance about when to prefer it over sibling tools, but this does not hinder correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so the baseline of 4 applies. There is nothing for the description to explain about parameters, and the description correctly focuses on the tool's output rather than input semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Report') and names an exact set of outputs: installed versions, paths, examples, and Pyxel resource URIs. This clearly distinguishes it from sibling read_* tools that target game assets such as palettes, images, tilemaps, and audio.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no explicit when-to-use or when-not-to-use guidance or mention of alternatives. However, the tool's purpose is strongly implied by its name and content: use it to introspect the Pyxel environment rather than to execute or validate game resources. The guidance is implicit, not explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
read_audioA
Render one Pyxel sound or music slot to WAV and return measurable audio data.
| Name | Required | Description | Default |
|---|---|---|---|
| script | Yes | ||
| target | Yes | ||
| output_path | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | |
| path | No | |
| notes | No | |
| errors | Yes | |
| channels | No | |
| warnings | No | |
| sample_rate | No | |
| peak_amplitude | No | |
| duration_seconds | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds meaningful behavior beyond the annotations: it discloses that the tool renders to WAV and returns measurable audio data. However, it does not clarify whether the WAV is written to output_path, whether the script is executed, or what side effects might occur beyond the readOnlyHint=false annotation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single, front-loaded sentence with no fluff. It conveys the core operation, output format, and return value type without wasting words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has three required parameters and no schema descriptions, yet the description explains only the audio target concept. It leaves the script parameter and the mutual exclusivity or interaction between music and sound unaddressed, making the definition incomplete for an agent to call the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description partially documents the target parameter by mentioning sound or music slot, but it does not explain the required 'script' parameter or 'output_path' semantics. Since schema description coverage is 0%, the description does not sufficiently compensate for the total lack of parameter explanations.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action ('render') and resource ('one Pyxel sound or music slot to WAV'), making the tool's purpose immediately clear. It also distinguishes this tool from the image/tilemap/palette reader siblings by focusing on audio output.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage context is implied: use this tool when you need audio data from a Pyxel sound or music slot. However, there is no explicit guidance about when not to use it, no alternative tools are named, and no prerequisites such as needing a loaded Pyxel script are mentioned.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
read_imageA
Read palette-index pixels from a Pyxel image-bank region and optionally render it to PNG; inline=true returns the render as image content and makes render_path optional.
| Name | Required | Description | Default |
|---|---|---|---|
| h | No | ||
| w | No | ||
| x | No | ||
| y | No | ||
| image | Yes | ||
| inline | No | ||
| script | Yes | ||
| render_path | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | |
| errors | Yes | |
| pixels | No | |
| region | No | |
| rendered | No | |
| bank_size | No | |
| color_count | No | |
| image_index | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses a non-read-only side effect (optional PNG rendering) and explains that inline=true returns image content, going beyond the sparse annotations. This is consistent with readOnlyHint=false because rendering is a write-capable path.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One compact, front-loaded sentence that puts the core read action first and then adds the conditional rendering behavior. No filler or redundant restatement of the tool name.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers the primary read/render flow and the inline behavior, and the output schema can handle return-value details. However, it does not explain the required script parameter or the coordinate-region semantics, so an agent must infer important calling details.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Adds meaningful semantics for inline and render_path by explaining their relationship, but leaves the required script parameter and the coordinate parameters x/y/w/h unexplained. With 0% schema description coverage, this is a substantial gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific action: read palette-index pixels from a Pyxel image-bank region and optionally render to PNG. The resource ('image-bank region') and pixel-mode clearly distinguish it from sibling read tools like read_palette and read_tilemap.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides a clear condition for inline mode and render_path optionality, but gives no guidance on when to choose read_image over alternatives such as read_palette or read_tilemap. Tool-selection context is only implied by the purpose rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
read_paletteC
Read the active Pyxel palette and the palette indices used by image banks.
| Name | Required | Description | Default |
|---|---|---|---|
| script | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | |
| colors | No | |
| errors | Yes | |
| palette_size | No | |
| used_indices | No | |
| extended_palette | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description frames the operation as a read ('Read the active Pyxel palette'), but the annotations set readOnlyHint to false, which contradicts the clear read-only semantics of the description. It also sets idempotentHint to false for an operation that should be idempotent. This is an annotation contradiction, and the description adds no further behavioral context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single front-loaded sentence with no filler words; it names the action and the resource in the order an agent needs. It is concise without sacrificing the core object.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Although the tool is simple and an output schema exists, the description omits the meaning of the required 'script' parameter and does not clarify the exact relationship between the active palette and image-bank indices. Combined with the misleading annotations, the description is incomplete for reliable invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The single required parameter 'script' has 0% schema description coverage, and the description does not mention or explain how 'script' relates to reading the palette. With no parameter details in the schema, the description fails to compensate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific action ('Read') on a specific resource ('active Pyxel palette and the palette indices used by image banks'). This distinguishes it from sibling tools like read_image, read_tilemap, and read_audio, so an agent can identify the tool's scope.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies this tool is for retrieving palette data, but it does not explicitly state when to choose read_palette over read_image, read_tilemap, or read_audio, nor does it list exclusions or prerequisites such as needing a script.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
read_tilemapA
Read Pyxel tile coordinates, usage, bounds, source bank, and optional rendered output; inline=true returns the render as image content and makes render_path optional.
| Name | Required | Description | Default |
|---|---|---|---|
| inline | No | ||
| script | Yes | ||
| tilemap | Yes | ||
| render_path | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | |
| size | No | |
| tiles | No | |
| usage | No | |
| errors | Yes | |
| imgsrc | No | |
| region | No | |
| rendered | No | |
| tilemap_index | No | |
| zero_tile_used | No | |
| zero_tile_nonempty | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With all annotations false, the description carries the burden of behavioral disclosure. It explains the inline rendering behavior and the optional render_path, but does not clarify potential file-writing side effects when render_path is used, nor the meaning of 'source bank'. It adds some behavioral context but leaves important details implied.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single dense sentence with no filler, front-loading the main action and then adding the conditional inline behavior. It is concise, though the semicolon-heavy structure and slight repetition of 'optional rendered output' vs 'inline=true' could be streamlined.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the output schema existshare, return-value documentation is not needed, and the description covers the tool's core purpose and inline mode. However, the required `script` parameter is unexplainedeing, and the behavior of render_path when inline=false is ambiguous. This is adequate but not complete for a 4-parameter tool with no annotation support.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It explicitly explains the inline and render_path relationshipbell, and 'tilemap' is contextually clear. However, the required `script` parameter is not described at all, and the exact roles of `script` and `tilemap` as inputs are left to inference.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies the resource (Pyxel tilemap) and lists specific data it reads: tile coordinates, usage, bounds, source bank, and optional rendered output. This is more specific than sibling read_* tools and leaves little ambiguity about the tool's function.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives a concrete usage condition: inline=true returns render as image content and makes render_path optional, which helps the agent decide between inline and path-based output. It does not explicitly name sibling alternatives or exclusions, but the context of reading tilemaps is clear enough.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
runA
Run a Pyxel script headlessly for a frame budget or until a condition holds, with scheduled input and state, screen, or video capture. screen_image snapshots with inline=true also return the PNG as image content, and a single inline frame may omit its output path.
| Name | Required | Description | Default |
|---|---|---|---|
| until | No | ||
| frames | Yes | ||
| inputs | No | ||
| script | Yes | ||
| timeout | No | ||
| snapshots | No | ||
| random_seed | No | ||
| stall_window_frames | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | |
| log | Yes | |
| errors | Yes | |
| seeded | Yes | |
| snapshots | Yes | |
| until_met | No | True once `until` held, False when it was evaluated without ever holding, None when it was never evaluated. |
| exit_status | Yes | |
| frame_count | Yes | |
| elapsed_seconds | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations convey it is not read-only, not necessarily idempotent, and not destructive. The description adds meaningful behavioral context beyond annotations: that runs are headless, bounded by frame budget or a condition, and that screen_image snapshots with inline=true return PNG content while a single inline frame may omit its output path. This details side effects and special capture behaviors without contradicting the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a compact two-sentence summary that front-loads the core purpose and key behavioral distinctions. It covers a complex, multi-capability tool without redundancy. It could be slightly more structured, but it remains one dense, information-rich paragraph appropriate to the tool's complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with an output schema and eight parameters, the description does well: it explains the central execution semantics, input scheduling, and snapshot return behavior (including the inline PNG nuance). It omits explicit guidance on side-effect-like details such as file outputs for video or temporary files, but the output schema covers return values and the annotations cover mutation hints. Almost complete, with only minor missing nuances.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description carries the burden for explaining parameters. It effectively explains the overall execution model (frame budget/until condition), scheduled inputs, and snapshot capture including the inline PNG behavior. It does not detail every parameter such as random_seed, timeout, or stall_window_frames, but the description provides the framework in which those parameters make sense.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Run'), names the resource ('a Pyxel script'), and specifies the execution mode ('headlessly') and termination conditions ('frame budget or until a condition holds'). It also enumerates the main capabilities (input scheduling, state/screen/video capture), which distinguishes it from siblings like validate, read_image, and diff_frames.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description makes the tool's scope clear: running scripts headlessly in a controlled environment, suitable for generating snapshots while 'validate' likely just checks scripts. It does not explicitly name sibling alternatives or state when not to use it, but the context of being the only runner among siblings implies its usage. A small gap is lacking an explicit 'use X instead when...' statement.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
validateARead-onlyIdempotent
Check Python syntax and report recognizable Pyxel code patterns.
| Name | Required | Description | Default |
|---|---|---|---|
| script | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | |
| errors | Yes | |
| issues | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, covering the safety profile. The description adds valuable behavioral context by specifying that the tool performs syntax checking and pattern recognition, which implies a non-executing, analysis-only behavior. This goes beyond what annotations state, though it stops short of detailing exactly what patterns are recognized or how results are reported.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence with zero filler. It wastes no words and communicates the core action and focus immediately, making it easy for an agent to parse and act on quickly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has a single parameter and an output schema (which presumably documents the return structure), the description covers the essentials: what the tool does and on what input. It does not explain potential edge cases (e.g., handling of invalid syntax) but those are likely covered by the output schema. The description is sufficiently complete for a straightforward validation tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has zero description coverage for its single parameter, so the description must convey parameter meaning. It does so by implication: the tool validates Python syntax, so 'script' is the Python code to be checked. However, it does not explicitly state that the parameter contains the source code, and gives no hints about expected encoding, length limits, or file references. This is adequate for a single simple parameter but not fully explicit.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Check') and a clear resource ('Python syntax' and 'Pyxel code patterns'), which precisely distinguishes it from sibling tools like 'run', 'read_palette', and 'read_tilemap' that perform execution or read operations. An agent can immediately understand this is a validation tool, not a runtime or read tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives no explicit guidance on when to use this tool versus alternatives. It does not mention typical workflows (e.g., 'use before run'), nor does it reference any sibling tools, leaving the agent to infer usage context from the tool's name and purpose alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
21 tool updates
v1.3.0- Removed
capture_frames - Removed
compare_frames - Added
diff_frames - Removed
inspect_bank - Removed
inspect_layout - Removed
inspect_palette - Removed
inspect_screen - Removed
inspect_sprite - Removed
inspect_state - Removed
inspect_tilemap - Removed
play_and_capture - Changed
pyxel_info13 fields changed- added
Output schema / $defsAdded value: +{ + "ExampleInfo": { + "additionalProperties": false, + "properties": { + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Description" + }, + "name": { + "title": "Name", + "type": "string" + }, + "path": { + "title": "Path", + "type": "string" + } + }, + "required": [ + "name", + "path" + ], + "title": "ExampleInfo", + "type": "object" + }, + "ToolErrorRecord": { + "additionalProperties": false, + "properties": { + "frame": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Frame" + }, + "message": { + "title": "Message", + "type": "string" + }, + "path": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Path" + }, + "phase": { + "title": "Phase", + "type": "string" + }, + "traceback": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Traceback" + } + }, + "required": [ + "phase", + "message" + ], + "title": "ToolErrorRecord", + "type": "object" + } +} - added
Output schema / additionalPropertiesAdded value: +false - added
Output schema / properties / errorsAdded value: +{ + "items": { + "$ref": "#/$defs/ToolErrorRecord" + }, + "title": "Errors", + "type": "array" +} - added
Output schema / properties / examplesAdded value: +{ + "items": { + "$ref": "#/$defs/ExampleInfo" + }, + "title": "Examples", + "type": "array" +} - added
Output schema / properties / okAdded value: +{ + "title": "Ok", + "type": "boolean" +} - added
Output schema / properties / python_versionAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Python Version" +} - added
Output schema / properties / pyxel_mcp_versionAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Pyxel Mcp Version" +} - added
Output schema / properties / pyxel_versionAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Pyxel Version" +} - added
Output schema / properties / resourcesAdded value: +{ + "additionalProperties": { + "type": "string" + }, + "title": "Resources", + "type": "object" +} - removed
Output schema / properties / resultRemoved value: -{ - "title": "Result", - "type": "string" -} - added
Output schema / properties / stubs_pathAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Stubs Path" +} - changed
Output schema / requiredPrevious value: -[ - "result" -]New value: +[ + "ok", + "errors" +] - changed
Output schema / titlePrevious value: -"pyxel_infoOutput"New value: +"PyxelInfoResult"
- Added
read_audio - Added
read_image - Added
read_palette - Added
read_tilemap - Removed
render_audio - Added
run - Removed
run_and_capture - Added
validate - Removed
validate_script
14 tool updates
v0.8.0- First observed
capture_frames - First observed
compare_frames - First observed
inspect_bank - First observed
inspect_layout - First observed
inspect_palette - First observed
inspect_screen - First observed
inspect_sprite - First observed
inspect_state - First observed
inspect_tilemap - First observed
play_and_capture - First observed
pyxel_info - First observed
render_audio - First observed
run_and_capture - First observed
validate_script
TDQS
Scored across 8 tools
Each tool maps to a distinct concern: environment info, execution, syntax validation, and per-resource reads for palette, image, tilemap, and audio, plus frame comparison. There is no meaningful overlap or ambiguity; the read_* tools are clearly differentiated by resource type.
The four resource readers follow a consistent read_<resource> pattern, and the other tools are reasonably clear. The set is slightly mixed because pyxel_info uses a noun-style name and run/validate are bare verbs, but the conventions are still predictable and readable.
Eight tools is a well-scoped size for a Pyxel inspection/execution server. Each tool covers a distinct capability without bloat, and the count is comfortably in the ideal range.
The surface covers the main Pyxel asset types (palette, image bank, tilemap, audio), plus script validation, headless execution/capture, frame comparison, and environment info. No major dead ends or obvious missing operations for the server's stated role.
Maintenance
Related MCP Connectors
Generate authentic pixel art - sprites, animations, and tilesets - from any MCP client
MCP server for building and testing AI agents with multi-model experimentation and insights.
Generate game-ready 3D models, textures, and audio from natural language, over MCP.
Hosted MCP server connecting claude.ai, ChatGPT and other AI apps to your own computer
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceMCP server for programmatically creating and editing Aseprite sprites, enabling AI agents to draw, manage layers and frames, and iterate until the desired result is achieved.MIT
- AlicenseBqualityCmaintenanceAn MCP server that lets AI agents create and edit Aseprite sprites headlessly, enabling pixel art, animation, and export via 98 tools.1008MIT
- FlicenseAqualityDmaintenanceAn MCP server that enables AI coding agents to create pixel art programmatically by providing canvas manipulation tools and PNG export.1018 npm2-
- AlicenseNot gradedqualityAmaintenanceAn AI-native game engine MCP server that enables AI agents to create, modify, and run games using 53 tools for scene creation, physics, audio, 3D rendering, and AI-generated images and music.1MIT