Skip to main content
Glama

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.

PyPI Python Tests License MCP Registry

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: true returns 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-mcp
codex mcp add pyxel -- uvx pyxel-mcp
gemini mcp add pyxel uvx pyxel-mcp

For 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-skill

Restart the client after changing its configuration. The server writes this diagnostic to stderr:

[pyxel-mcp] starting - 8 tools

Python 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

validate

Syntax errors and recognizable Pyxel code patterns, without executing.

run

Headless frames, scheduled input, logs, and state, screen_image, screen_grid, or video snapshots.

pyxel_info

Installed versions, paths, bundled examples, and resource URIs.

read_palette

Palette colors and image-bank indices in use.

read_image

Image-bank pixels and an optional PNG render.

read_tilemap

Tile coordinates, source bank, usage counts, bounds, and an optional render.

read_audio

A rendered sound or music WAV plus measurable audio data.

diff_frames

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 — complete run.snapshots grammar, including "end", ranges, and inline.

  • pyxel://validation-patterns — categories reported by validate.

  • pyxel://palette/default — default palette table.

  • pyxel://examples/{name} — source for an example bundled with the installed Pyxel package; discover names with pyxel_info.

Update

uvx caches packages. Force a refresh with:

uvx --refresh-package pyxel-mcp pyxel-mcp install

Troubleshooting

  • If tools do not appear, look for the starting - 8 tools diagnostic and restart the client.

  • If run fails, inspect errors, exit_status, and log.

  • 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.

  • 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 tools
diff_framesA
Read-onlyIdempotent

Compare two PNG frames pixel by pixel and return their changed region and ratio.

ParametersJSON Schema
NameRequiredDescriptionDefault
frame_aYes
frame_bYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
okYes
ratioNo
errorsYes
regionNo
size_aNo
size_bNo
warningsNo
identicalNo
size_matchNo
total_pixelsNo
changed_pixelsNo

TDQS

A3.8/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness3/5

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.

Parameters2/5

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.

Purpose5/5

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.

Usage Guidelines3/5

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_infoA
Read-onlyIdempotent

Report installed versions, paths, examples, and Pyxel resource URIs.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
okYes
errorsYes
examplesNo
resourcesNo
stubs_pathNo
pyxel_versionNo
python_versionNo
pyxel_mcp_versionNo

TDQS

A4.2/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines3/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
scriptYes
targetYes
output_pathYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
okYes
pathNo
notesNo
errorsYes
channelsNo
warningsNo
sample_rateNo
peak_amplitudeNo
duration_secondsNo

TDQS

A3.5/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness2/5

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.

Parameters2/5

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.

Purpose5/5

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.

Usage Guidelines3/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
hNo
wNo
xNo
yNo
imageYes
inlineNo
scriptYes
render_pathNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
okYes
errorsYes
pixelsNo
regionNo
renderedNo
bank_sizeNo
color_countNo
image_indexNo

TDQS

A3.8/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness3/5

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.

Parameters2/5

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.

Purpose5/5

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.

Usage Guidelines3/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
scriptYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
okYes
colorsNo
errorsYes
palette_sizeNo
used_indicesNo
extended_paletteNo

TDQS

C2.9/5.0
Behavior1/5

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.

Conciseness5/5

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.

Completeness2/5

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.

Parameters1/5

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.

Purpose5/5

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.

Usage Guidelines3/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
inlineNo
scriptYes
tilemapYes
render_pathNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
okYes
sizeNo
tilesNo
usageNo
errorsYes
imgsrcNo
regionNo
renderedNo
tilemap_indexNo
zero_tile_usedNo
zero_tile_nonemptyNo

TDQS

A3.8/5.0
Behavior3/5

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.

Conciseness4/5

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.

Completeness3/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
untilNo
framesYes
inputsNo
scriptYes
timeoutNo
snapshotsNo
random_seedNo
stall_window_framesNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
okYes
logYes
errorsYes
seededYes
snapshotsYes
until_metNoTrue once `until` held, False when it was evaluated without ever holding, None when it was never evaluated.
exit_statusYes
frame_countYes
elapsed_secondsYes

TDQS

A4.3/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

validateA
Read-onlyIdempotent

Check Python syntax and report recognizable Pyxel code patterns.

ParametersJSON Schema
NameRequiredDescriptionDefault
scriptYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
okYes
errorsYes
issuesNo

TDQS

A3.8/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines2/5

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.

  1. 21 tool updatesv1.3.0
    • Removedcapture_frames
    • Removedcompare_frames
    • Addeddiff_frames
    • Removedinspect_bank
    • Removedinspect_layout
    • Removedinspect_palette
    • Removedinspect_screen
    • Removedinspect_sprite
    • Removedinspect_state
    • Removedinspect_tilemap
    • Removedplay_and_capture
    • Changedpyxel_info13 fields changed
      • addedOutput schema / $defs
        Added 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"
        +  }
        +}
      • addedOutput schema / additionalProperties
        Added value: +false
      • addedOutput schema / properties / errors
        Added value: +{
        +  "items": {
        +    "$ref": "#/$defs/ToolErrorRecord"
        +  },
        +  "title": "Errors",
        +  "type": "array"
        +}
      • addedOutput schema / properties / examples
        Added value: +{
        +  "items": {
        +    "$ref": "#/$defs/ExampleInfo"
        +  },
        +  "title": "Examples",
        +  "type": "array"
        +}
      • addedOutput schema / properties / ok
        Added value: +{
        +  "title": "Ok",
        +  "type": "boolean"
        +}
      • addedOutput schema / properties / python_version
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Python Version"
        +}
      • addedOutput schema / properties / pyxel_mcp_version
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Pyxel Mcp Version"
        +}
      • addedOutput schema / properties / pyxel_version
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Pyxel Version"
        +}
      • addedOutput schema / properties / resources
        Added value: +{
        +  "additionalProperties": {
        +    "type": "string"
        +  },
        +  "title": "Resources",
        +  "type": "object"
        +}
      • removedOutput schema / properties / result
        Removed value: -{
        -  "title": "Result",
        -  "type": "string"
        -}
      • addedOutput schema / properties / stubs_path
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Stubs Path"
        +}
      • changedOutput schema / required
        Previous value: -[
        -  "result"
        -]New value: +[
        +  "ok",
        +  "errors"
        +]
      • changedOutput schema / title
        Previous value: -"pyxel_infoOutput"New value: +"PyxelInfoResult"
    • Addedread_audio
    • Addedread_image
    • Addedread_palette
    • Addedread_tilemap
    • Removedrender_audio
    • Addedrun
    • Removedrun_and_capture
    • Addedvalidate
    • Removedvalidate_script
  2. 14 tool updatesv0.8.0
    • First observedcapture_frames
    • First observedcompare_frames
    • First observedinspect_bank
    • First observedinspect_layout
    • First observedinspect_palette
    • First observedinspect_screen
    • First observedinspect_sprite
    • First observedinspect_state
    • First observedinspect_tilemap
    • First observedplay_and_capture
    • First observedpyxel_info
    • First observedrender_audio
    • First observedrun_and_capture
    • First observedvalidate_script

TDQS

A3.8/5.0

Scored across 8 tools

Disambiguation5/5

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.

Naming Consistency4/5

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.

Tool Count5/5

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.

Completeness5/5

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

ActivityMaintained
ResponsivenessUnresponsive

Related MCP Connectors

Related MCP Servers