mcp-retroarch
Provides tools for interacting with RetroArch through its Network Control Interface and Network RetroPad protocols, enabling memory read/write, save state management, screenshots, emulator control (pause, frame advance, reset), and gamepad input.
Click on "Install 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., "@mcp-retroarchSave the current state to slot 2"
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.
mcp-retroarch
MCP server for RetroArch — memory r/w, save states, screenshots, pause/frame-advance/reset via the Network Control Interface, plus gamepad input via the Network RetroPad protocol (UDP).
Inspired by dmang-dev/mcp-retroarch. Rewritten in Python to eliminate the npm git-install reliability issues that plagued the original TypeScript distribution (
npm install -g github:...produces a broken symlink on most systems due to a known npm bug).uv tool install git+...handles this correctly.
Requirements
Python 3.13
RetroArch with:
Network Commands enabled for NCI tools (memory, save states, screenshots, emulator control)
Network Gamepad enabled for input tools
Related MCP server: mcp-retroarch
Install
# Install as a persistent uv tool (recommended)
uv tool install git+https://github.com/pythoninthegrass/mcp-retroarch
# Or run ephemerally without installing
uvx --from git+https://github.com/pythoninthegrass/mcp-retroarch mcp-retroarchRetroArch configuration
Network Commands (NCI — required for most tools)
In retroarch.cfg or via Settings → Network → Network Commands:
network_cmd_enable = "true"
network_cmd_port = "55355"Network Gamepad (required for input tools)
In retroarch.cfg or via Settings → Input → Network Gamepad:
network_remote_enable = "true"
network_remote_base_port = "55400"
# Enable per player (p1 through p16)
network_remote_enable_user_p1 = "true"Client configuration
Claude Desktop
~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or
%APPDATA%\Claude\claude_desktop_config.json (Windows):
{
"mcpServers": {
"retroarch": {
"command": "uvx",
"args": [
"--from",
"git+https://github.com/pythoninthegrass/mcp-retroarch",
"mcp-retroarch"
]
}
}
}If installed via uv tool install:
{
"mcpServers": {
"retroarch": {
"command": "mcp-retroarch"
}
}
}Environment variables
Variable | Default | Description |
|
| RetroArch host for both NCI and RetroPad |
|
| NCI UDP port ( |
|
| Override host for Network Gamepad only |
|
| Base port for Network Gamepad ( |
Tools
Connectivity & introspection
Tool | Description |
| Verify NCI connectivity; returns RetroArch version |
| Report playing/paused state, loaded system, game, and CRC32 |
| Read a single RetroArch config parameter by name |
Memory
Tool | Description |
| Read bytes via the libretro system memory map (preferred) |
| Read bytes via the CHEEVOS address space (fallback) |
| Write bytes via the libretro system memory map |
| Write bytes via the CHEEVOS address space (no acknowledgement) |
Emulator control
Tool | Description |
| Toggle pause/unpause |
| Step one frame (paused only) |
| Soft-reset the loaded game |
| Save a screenshot to RetroArch's screenshot directory |
| Display an OSD notification on the RetroArch window |
Save states
Tool | Description |
| Save to currently-selected slot |
| Load from currently-selected slot |
| Load from an explicit slot number (does not change the current-slot pointer) |
| Increment current slot pointer |
| Decrement current slot pointer |
Gamepad input (Network RetroPad)
Tool | Description |
| Latch one or more buttons down |
| Release one or more buttons |
| Zero all buttons and analog sticks in one packet |
| Set an analog stick's X/Y position |
| Press, hold for a duration, then release (everyday input) |
Valid RetroPad button names: b, y, select, start, up, down, left, right, a, x, l, r, l2, r2, l3, r3.
On PlayStation cores: b=Cross, a=Circle, y=Square, x=Triangle.
See docs/RECIPES.md for usage patterns.
Development
# Install with dev dependencies
uv sync
# Run tests
uv run pytest
# Format and lint
uv run ruff format .
uv run ruff check .Docker
docker build -t mcp-retroarch .
docker run --rm -i \
-e RETROARCH_HOST=host.docker.internal \
mcp-retroarchLicense
MIT — see LICENSE.
Available Tools
22 toolsretroarch_frame_advanceA
PURPOSE: Step emulation forward by exactly one frame. USAGE: Use for frame-precise input automation, animation inspection, or letting the system initialize after a reset. ONLY effective while emulation is paused — RetroArch's FRAMEADVANCE is a no-op when running, so call retroarch_pause_toggle first (after checking retroarch_get_status to confirm you'll end up paused, not unpaused). For long jumps (thousands of frames) prefer retroarch_save_state_current / retroarch_load_state_current of a pre-prepared state — frame-by-frame stepping costs ~1 UDP round-trip per frame. BEHAVIOR: When paused, advances the emulator by exactly one frame and remains paused. When NOT paused, the command is silently ignored by RetroArch. FIRE-AND-FORGET: the NCI does NOT acknowledge this command — the call returns as soon as the UDP datagram is sent, with no confirmation that RetroArch received or applied it. To verify the effect, follow up with an observable tool (retroarch_get_status for run state, retroarch_read_memory / retroarch_read_ram for memory mutations, retroarch_screenshot for visual state). UDP packets to a not-listening RetroArch are silently dropped. The new frame count is not reported — to verify progress, take screenshots before/after with retroarch_screenshot or read a known-changing memory value. Transport: RetroArch's Network Control Interface (NCI) over UDP (default 127.0.0.1:55355, requires network_cmd_enable = true in retroarch.cfg). RETURNS: Single line 'Advanced one frame' (UDP-send confirmation only — does NOT confirm that RetroArch was paused or that the frame actually advanced).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does so thoroughly. It discloses that the command is silently ignored when not paused, is fire-and-forget with no acknowledgment, UDP packets are silently dropped if not listening, the frame count is not reported, and the return string is only a send confirmation. This fully reveals critical behavioral traits beyond basic functionality.
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?
Though lengthy, the description is structured with labeled sections (PURPOSE, USAGE, BEHAVIOR, FIRE-AND-FORGET, Transport, RETURNS). Each sentence conveys a necessary operational detail such as pause requirement, no-ack behavior, verification methods, and configuration. The length is justified by the tool's complexity, and it is front-loaded with the core purpose.
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 description covers purpose, usage, behavior, return value, transport, prerequisites, and verification strategies, even referencing sibling tools for confirmation. Given the fire-and-forget nature, no output schema, and no annotations, this description is fully complete for an agent to invoke the tool correctly and verify its effect.
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 there is no parameter meaning to clarify. The description instead provides useful invocation context (UDP transport, network_cmd_enable requirement), which adds value, but the parameter dimension is vacuously satisfied. Baseline 4 for no params is appropriate.
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 opens with a precise purpose: "Step emulation forward by exactly one frame." It clearly distinguishes itself from sibling tools by emphasizing frame-precise stepping and even contrasts with long jumps using save/load states. This is a specific verb+resource+outcome with strong sibling differentiation.
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?
Explicit usage contexts are given: "frame-precise input automation, animation inspection, or letting the system initialize after a reset." It states the condition "ONLY effective while emulation is paused," instructs to call retroarch_pause_toggle first after checking retroarch_get_status, and recommends alternatives for long jumps. This is exemplary when-to-use versus when-not-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
retroarch_get_configA
PURPOSE: Read a single RetroArch configuration parameter by name via the NCI GET_CONFIG_PARAM command. USAGE: Discover RetroArch's filesystem paths and selected settings without parsing retroarch.cfg yourself. For run-state (playing/paused, loaded ROM) use retroarch_get_status instead — this tool only reads static config. RetroArch whitelists which params are exposed; non-whitelisted names error even if they exist in retroarch.cfg. screenshot_directory is NOT exposed — see retroarch_screenshot. BEHAVIOR: No side effects — pure read. Transport: RetroArch's Network Control Interface (NCI) over UDP (default 127.0.0.1:55355, requires network_cmd_enable = true in retroarch.cfg). Errors if the param isn't in RetroArch's NCI whitelist, the value contains characters that break the line-based reply parser (rare — embedded newlines or null bytes), or the UDP query times out. RETURNS: 'NAME = VALUE' where VALUE is the raw string as stored in retroarch.cfg (paths unquoted, booleans as 'true'/'false', integers as decimal).
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Config key — same snake_case ASCII identifier RetroArch uses in retroarch.cfg, case-sensitive, no surrounding quotes. Path-class keys (return absolute paths on disk): `savefile_directory`, `savestate_directory`, `system_directory`, `cache_directory`, `log_dir`, `runtime_log_directory`, `core_assets_directory`. User-data keys: `netplay_nickname`. Toggle keys (return 'true' / 'false'): `video_fullscreen`, `video_vsync`, `audio_mute_enable`. The full whitelist varies per RetroArch build; if a key returns an error rather than a value, it's not exposed via the NCI on this build. Notable exclusions: `screenshot_directory` is intentionally NOT exposed by RetroArch (see retroarch_screenshot for the workaround). Also no key for the currently-selected savestate slot — track that client-side via retroarch_state_slot_plus/minus. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden and exceeds expectations. It discloses that this is a pure read with 'No side effects,' specifies the transport (UDP, default address/port), prerequisites (network_cmd_enable=true), and error conditions (non-whitelisted params, parser-breaking characters, timeouts). It also describes the exact return format, including unquoted paths and boolean/integer representations.
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 well-structured with labeled sections (PURPOSE, USAGE, BEHAVIOR, RETURNS) and front-loaded with the core purpose. It is verbose but every sentence adds value; however, there is some redundancy, such as repeating 'screenshot_directory is NOT exposed' and 'only reads static config' across sections. Slightly tighter wording would make it ideal.
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?
Despite having no output schema and only one parameter, the description is highly complete. It covers prerequisites, network details, error scenarios, and return format comprehensively. Given the tool's complexity (UDP transport, whitelist restrictions), the description leaves no critical gaps for an agent to correctly invoke and interpret results.
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 100%, and the schema itself already provides extensive parameter semantics, listing example keys, categories, and the screenshot_directory exclusion. The tool description adds minimal new parameter meaning beyond restating the exclusion and whitelist behavior, so the baseline of 3 is appropriate.
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+resource+scope: 'Read a single RetroArch configuration parameter by name via the NCI GET_CONFIG_PARAM command.' It clearly distinguishes from siblings by explicitly saying 'For run-state (playing/paused, loaded ROM) use retroarch_get_status instead — this tool only reads static config' and notes 'screenshot_directory is NOT exposed — see retroarch_screenshot.' This leaves no ambiguity about the tool's purpose.
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 explicit when-to-use guidance: 'Discover RetroArch's filesystem paths and selected settings without parsing retroarch.cfg yourself.' It also gives clear exclusions and alternatives, naming retroarch_get_status for run-state queries and retroarch_screenshot for the screenshot_directory workaround. The whitelist limitation is disclosed upfront, helping the agent decide when to attempt a call.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
retroarch_get_statusA
PURPOSE: Report whether RetroArch is currently playing or paused, plus the loaded system, game basename, and CRC32. USAGE: Call after retroarch_ping to learn what (if anything) is loaded; before retroarch_pause_toggle to decide whether the toggle will pause or unpause; before retroarch_frame_advance (which only steps when paused); whenever you need to confirm the previous fire-and-forget control command (pause/reset/load_state) actually took effect. For RetroArch settings (paths, flags) use retroarch_get_config instead — this tool only reports run-state and the loaded ROM identity. BEHAVIOR: No side effects — pure read of emulator status via the NCI's GET_STATUS command. Returns 'No content loaded' (state=contentless) when RetroArch is sitting at the menu with no ROM. Returns an error on UDP timeout (RetroArch not reachable). RETURNS: When content is loaded: four lines 'State: playing|paused', 'System: SYSTEM_ID', 'Game: BASENAME', 'CRC32: HEX or (none reported)'. When no content: literal 'No content loaded'.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description fully shoulders the transparency burden. It states 'No side effects — pure read of emulator status via the NCI's GET_STATUS command', explains the contentless case ('Returns 'No content loaded' (state=contentless) when RetroArch is sitting at the menu with no ROM'), and discloses error behavior on UDP timeout. This goes beyond what structured fields could convey.
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 organized with clear labels (PURPOSE, USAGE, BEHAVIOR, RETURNS) and every sentence contributes essential information. Despite its length, there is no redundancy or filler; it remains succinct while covering all necessary facets. The front-loaded purpose lets an agent quickly classify the tool.
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 that there is no output schema and no annotations, the description compensates by fully specifying the return format for both loaded and contentless states, including line-by-line details. It covers prerequisites (call after ping), side effects, and error cases, making it essentially self-contained for an agent to invoke confidently.
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 schema provides no semantics to enrich. The baseline for 0 params is 4. The description adds value by detailing the return payload, which is more relevant than parameter documentation for this no-arg tool.
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 opens with a clear, specific verb ('Report') and resource ('whether RetroArch is currently playing or paused, plus the loaded system, game basename, and CRC32'). It explicitly distinguishes itself from sibling tools like retroarch_get_config by stating what this tool does not do ('this tool only reports run-state and the loaded ROM identity'), making it easy for an agent to select it correctly.
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 explicit when-to-use guidance: 'Call after retroarch_ping to learn what (if anything) is loaded; before retroarch_pause_toggle to decide whether the toggle will pause or unpause; before retroarch_frame_advance (which only steps when paused); whenever you need to confirm the previous fire-and-forget control command...'. It also names an alternative for a different use case: 'For RetroArch settings (paths, flags) use retroarch_get_config instead'. This is exemplary usage guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
retroarch_input_pressA
PURPOSE: Press (latch down) one or more RetroPad buttons for a player via RetroArch's Network Gamepad channel. USAGE: The low-level press primitive. For a simple press-and-release use retroarch_input_tap instead. For frame-accurate scripting: pause first, call this for ONE button, then retroarch_frame_advance, repeating per change (see BEHAVIOR for why). Buttons follow libretro RetroPad naming — on PlayStation cores: b=Cross, a=Circle, y=Square, x=Triangle. BEHAVIOR: Two receiver behaviors govern all input tools: (1) LATCHING — a pressed button stays down until an explicit release; there is no auto-release or keepalive. Always pair presses with releases or use retroarch_input_release_all. (2) ONE DATAGRAM PER FRAME — RetroArch consumes at most one queued input message per emulated frame per player, so N changes sent back-to-back land over N consecutive frames. For frame-accurate scripting: pause, then alternate one input tool call with one retroarch_frame_advance per change. FIRE-AND-FORGET: the Network Gamepad channel does NOT acknowledge this command — the call returns as soon as the UDP datagram is sent, with no confirmation that RetroArch received or applied it. To verify the effect, follow up with an observable tool (retroarch_get_status for run state, retroarch_read_memory / retroarch_read_ram for memory mutations, retroarch_screenshot for visual state). UDP packets to a not-listening RetroArch are silently dropped. Transport: RetroArch's Network Gamepad receiver over UDP (default 127.0.0.1:55400 + player index; requires network_remote_enable = true AND network_remote_enable_user_p1 = true (per player) in retroarch.cfg, or Settings > Input > Network Gamepad). This is a SEPARATE channel from the NCI command port — enabling Network Commands alone is not enough. RETURNS: 'Pressed BUTTONS (player N)' — UDP-send confirmation only; verify effect via memory read or screenshot.
| Name | Required | Description | Default |
|---|---|---|---|
| player | No | Player index, 0-based. Player N's receiver listens at base port + N (default 55400 + N) and must be individually enabled in RetroArch (network_remote_enable_user_p<N+1>). Default 0 (Player 1). | |
| buttons | Yes | RetroPad button names (case-insensitive): b, y, select, start, up, down, left, right, a, x, l, r, l2, r2, l3, r3. One datagram is sent per button; RetroArch applies one per emulated frame, so multiple buttons land on consecutive frames (all remain latched once applied). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden of behavioral disclosure, and it excels. It explains latching behavior, one-datagram-per-frame limits, fire-and-forget semantics, lack of acknowledgment, silent UDP dropping, and the required RetroArch network settings—information critical for correct use.
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?
Although lengthy, the description is organized into labeled sections (PURPOSE, USAGE, BEHAVIOR, FIRE-AND-FORGET, Transport, RETURNS) and every sentence carries necessary information. It is front-loaded with the purpose, and the structure aids scanning without wasted 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?
This is a complex tool involving network communication, latched input, and frame-accurate scripting, with no output schema. The description covers the return format, verification strategies, configuration prerequisites, and behavioral caveats, leaving no critical gaps for an agent to misuse the 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 schema already documents both parameters comprehensively (100% coverage), so the baseline is 3. The description adds value by mapping libretro button names to PlayStation core conventions (b=Cross, a=Circle) and clarifying that multiple buttons each generate a datagram landing on consecutive frames, which goes beyond schema details.
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 opens with 'PURPOSE: Press (latch down) one or more RetroPad buttons for a player via RetroArch's Network Gamepad channel,' clearly identifying the verb, resource, and mechanism. It also distinguishes itself from retroarch_input_tap and retroarch_input_release, establishing its unique role as the low-level press primitive.
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 explicitly states when to use this tool versus alternatives: 'For a simple press-and-release use retroarch_input_tap instead.' It also gives detailed frame-accurate scripting guidance, including pausing first, calling for one button, and alternating with retroarch_frame_advance, which is comprehensive and actionable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
retroarch_input_releaseA
PURPOSE: Release (latch up) one or more previously pressed RetroPad buttons for a player. USAGE: Counterpart to retroarch_input_press — every press must eventually be paired with a release (or retroarch_input_release_all), because the receiver latches state indefinitely. Releasing a button that is not pressed is harmless. BEHAVIOR: Two receiver behaviors govern all input tools: (1) LATCHING — a pressed button stays down until an explicit release; there is no auto-release or keepalive. Always pair presses with releases or use retroarch_input_release_all. (2) ONE DATAGRAM PER FRAME — RetroArch consumes at most one queued input message per emulated frame per player, so N changes sent back-to-back land over N consecutive frames. For frame-accurate scripting: pause, then alternate one input tool call with one retroarch_frame_advance per change. Transport: RetroArch's Network Gamepad receiver over UDP (default 127.0.0.1:55400 + player index; requires network_remote_enable = true AND network_remote_enable_user_p1 = true (per player) in retroarch.cfg, or Settings > Input > Network Gamepad). This is a SEPARATE channel from the NCI command port — enabling Network Commands alone is not enough. Fire-and-forget UDP — no acknowledgement. RETURNS: 'Released BUTTONS (player N)' — UDP-send confirmation only.
| Name | Required | Description | Default |
|---|---|---|---|
| player | No | Player index, 0-based (see retroarch_input_press). Default 0. | |
| buttons | Yes | RetroPad button names (case-insensitive): b, y, select, start, up, down, left, right, a, x, l, r, l2, r2, l3, r3. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description fully discloses behavioral traits: latching (no auto-release), one datagram per frame, UDP transport with specific config requirements, fire-and-forget semantics, and no acknowledgment. This is comprehensive and goes far beyond the basic 'release button' expectation.
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 organized into labeled sections (PURPOSE, USAGE, BEHAVIOR, TRANSPORT, RETURNS), making it skimmable. It is detailed but each sentence adds necessary context for the complex UDP/latching behavior. Slightly verbose due to repetition of the latching rule, but the structure prevents confusion.
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 description covers prerequisites (RetroArch config settings), transport specifics (UDP address/port), behavioral caveats (latching, one datagram per frame), and return value explanation. For a tool with no output schema and no annotations, this is fully complete for an agent to understand and invoke it 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 input schema already describes both parameters (player and buttons) with details like case-insensitivity and range for player. The description adds a note that releasing unpressed buttons is harmless, but this is behavioral rather than parameter-level. Since schema coverage is 100%, the description contributes no critical parameter semantics beyond the schema.
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 purpose is explicitly stated: 'Release (latch up) one or more previously pressed RetroPad buttons for a player.' This clearly identifies the action and resource, and it distinguishes itself from siblings by naming retroarch_input_press and retroarch_input_release_all as related tools.
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 explicitly frames this tool as the counterpart to retroarch_input_press and instructs that every press must be paired with a release or release_all. It also notes that releasing an unpressed button is harmless, providing clear guidance on when to use this tool versus alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
retroarch_input_release_allA
PURPOSE: Zero every button and both analog sticks for a player in a single packet — the input panic button. USAGE: Use at the start and end of every scripted input session so no latched button leaks into or out of your script; also as recovery when you have lost track of which buttons are down. Unlike releasing 16 buttons individually (16 datagrams = 16 frames to drain), this clears everything in ONE datagram, applied on the next frame. BEHAVIOR: Implementation detail worth knowing: RetroArch's receiver zeroes all input state for a player whenever it reads a datagram whose size is not exactly sizeof(struct remote_message) — this tool sends a deliberately undersized datagram to trigger exactly that. Documented receiver behavior in input/input_driver.c, stable across RetroArch releases, but it is technically a protocol edge case rather than a designed command. Transport: RetroArch's Network Gamepad receiver over UDP (default 127.0.0.1:55400 + player index; requires network_remote_enable = true AND network_remote_enable_user_p1 = true (per player) in retroarch.cfg, or Settings > Input > Network Gamepad). This is a SEPARATE channel from the NCI command port — enabling Network Commands alone is not enough. Fire-and-forget UDP — no acknowledgement. RETURNS: 'Released all input (player N)' — UDP-send confirmation only.
| Name | Required | Description | Default |
|---|---|---|---|
| player | No | Player index, 0-based (see retroarch_input_press). Default 0. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden and does so excellently. It discloses the undersized-datagram mechanism, cites the source file, flags it as a protocol edge case, explains the fire-and-forget UDP nature with no acknowledgement, and clarifies transport prerequisites including the separate channel from the NCI port.
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 well-structured with labeled sections (PURPOSE, USAGE, BEHAVIOR, Transport, RETURNS), purpose is front-loaded, and every sentence provides either usage guidance or a critical implementation detail. Despite its length, it is dense and free of redundancy, making it appropriately sized for 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 no output schema and no annotations, the description covers the action, usage patterns, underlying behavior, transport prerequisites, and the return string. It also anticipates common questions (e.g., whether Network Commands alone are sufficient) and explicitly addresses them, making it effectively self-contained.
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 already covers the 'player' parameter with 100% coverage (0-based, default 0). The description adds meaningful value by explaining that the player index is used to form the destination address ('default 127.0.0.1:55400 + player index'), which is not present in the schema and helps the agent understand how the parameter affects the tool's behavior.
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 opens with a clear, specific verb phrase: 'Zero every button and both analog sticks for a player in a single packet' and labels it the 'input panic button.' It distinguishes itself from sibling tools like 'retroarch_input_release' by emphasizing the 'all' scope and the single-packet mechanism.
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?
Explicitly states when to use it: at the start and end of scripted sessions to prevent leaks, and as recovery when input state is unknown. It also contrasts with the alternative of releasing 16 buttons individually, noting the inefficiency (16 datagrams = 16 frames) and the tool's advantage, making the usage context unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
retroarch_input_set_analogA
PURPOSE: Set one analog stick's X/Y position for a player (values persist until changed). USAGE: For analog movement, camera control, or pressure-sensitive navigation on cores that read analog sticks. Values are int16: -32768 (full left/up) to 32767 (full right/down), 0,0 = centered. Like buttons, analog state LATCHES — recenter with (0, 0) or retroarch_input_release_all when done. Sends two datagrams (X then Y), which the receiver applies over two consecutive frames. BEHAVIOR: Two receiver behaviors govern all input tools: (1) LATCHING — a pressed button stays down until an explicit release; there is no auto-release or keepalive. Always pair presses with releases or use retroarch_input_release_all. (2) ONE DATAGRAM PER FRAME — RetroArch consumes at most one queued input message per emulated frame per player, so N changes sent back-to-back land over N consecutive frames. For frame-accurate scripting: pause, then alternate one input tool call with one retroarch_frame_advance per change. Transport: RetroArch's Network Gamepad receiver over UDP (default 127.0.0.1:55400 + player index; requires network_remote_enable = true AND network_remote_enable_user_p1 = true (per player) in retroarch.cfg, or Settings > Input > Network Gamepad). This is a SEPARATE channel from the NCI command port — enabling Network Commands alone is not enough. Fire-and-forget UDP — no acknowledgement. RETURNS: 'Analog STICK set to (X, Y) (player N)' — UDP-send confirmation only.
| Name | Required | Description | Default |
|---|---|---|---|
| x | Yes | Horizontal axis: -32768 = full left, 0 = centered, 32767 = full right. | |
| y | Yes | Vertical axis: -32768 = full up, 0 = centered, 32767 = full down. | |
| stick | Yes | Which analog stick to set. | |
| player | No | Player index, 0-based (see retroarch_input_press). Default 0. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description fully carries the behavioral burden. It discloses latching (no auto-release), one-datagram-per-frame sequencing, UDP transport without acknowledgment, the requirement for network_remote_enable settings, and that two datagrams are sent consecutively. This is exceptionally transparent for a tool with no structured behavioral hints.
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 organized into clear labeled sections (PURPOSE, USAGE, BEHAVIOR, Transport, RETURNS) and every sentence adds substantive information. Despite its length, there is no filler — each detail (latching, frame timing, configuration prerequisites) is necessary for correct usage.
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 involving network transport, latching state, and frame-level timing, the description is comprehensive. It covers the return value, network configuration, frame-accurate usage pattern, and the two-receiver behaviors. No output schema exists, but the description fully addresses expected return and side effects, making it contextually complete.
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 already provides 100% coverage with descriptions for each parameter. The description adds meaning beyond the schema by explaining the int16 range semantics, the importance of (0,0) for centering, the two-datagram send order, and the player index default reference. This complements the schema without redundancy.
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 opens with 'Set one analog stick's X/Y position for a player', clearly stating the verb (set), resource (analog stick), and scope (player, axes). It identifies this as distinct from button-press tools via 'Like buttons' and from other input tools by focusing on analog sticks, making sibling differentiation clear.
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?
It provides explicit use cases ('analog movement, camera control, or pressure-sensitive navigation'), latching behavior, and a frame-accurate scripting pattern. While it does not explicitly name alternative tools for when not to use this, it implicitly distinguishes from button inputs and references companion functions (retroarch_input_release_all). This is clear guidance, though a direct exclusion would elevate it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
retroarch_input_tapA
PURPOSE: Press buttons, hold them for a duration, then release them — the everyday building block for menu navigation and normal play. USAGE: Use while emulation is RUNNING (state 'playing' per retroarch_get_status). The default 100 ms hold spans ~6 frames at 60 fps, comfortably above the one-datagram-per-frame application delay and typical game input-polling windows. For frame-accurate work while PAUSED, do not use this tool — compose retroarch_input_press / retroarch_frame_advance / retroarch_input_release manually, because this tool's hold is wall-clock and a paused emulator never samples it. BEHAVIOR: Sends press datagrams, waits hold_ms of wall-clock time, sends release datagrams. Multiple buttons latch over consecutive frames (see below), so a two-button chord is fully held only from the second frame of the hold window onward. Two receiver behaviors govern all input tools: (1) LATCHING — a pressed button stays down until an explicit release; there is no auto-release or keepalive. Always pair presses with releases or use retroarch_input_release_all. (2) ONE DATAGRAM PER FRAME — RetroArch consumes at most one queued input message per emulated frame per player, so N changes sent back-to-back land over N consecutive frames. For frame-accurate scripting: pause, then alternate one input tool call with one retroarch_frame_advance per change. Transport: RetroArch's Network Gamepad receiver over UDP (default 127.0.0.1:55400 + player index; requires network_remote_enable = true AND network_remote_enable_user_p1 = true (per player) in retroarch.cfg, or Settings > Input > Network Gamepad). This is a SEPARATE channel from the NCI command port — enabling Network Commands alone is not enough. RETURNS: 'Tapped BUTTONS for HOLDms (player N)' after the release datagrams are sent.
| Name | Required | Description | Default |
|---|---|---|---|
| player | No | Player index, 0-based (see retroarch_input_press). Default 0. | |
| buttons | Yes | RetroPad button names (case-insensitive): b, y, select, start, up, down, left, right, a, x, l, r, l2, r2, l3, r3. | |
| hold_ms | No | Wall-clock hold duration in milliseconds. Default 100 (~6 frames at 60 fps). Minimum 16 (~1 frame); values under ~50 ms risk the game's input poll missing the press entirely on cores that debounce. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries a heavy disclosure burden and fully delivers: it explains wall-clock waits, latching with no auto-release, one-datagram-per-frame consumption, the exact transport channel (UDP Network Gamepad vs NCI), and required config flags. It also explains that multi-button chords are fully held only from the second frame, which is exactly the kind of subtle behavior an agent needs to know.
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 structured with clear labels (PURPOSE, USAGE, BEHAVIOR, RETURNS) and every sentence adds operational detail. It is longer than average but each sentence earns its place — there is no filler, tautology, or repetition. The RETURNS line even documents the exact success message.
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's non-trivial interaction model (network transport, latching, frame timing, two receiver behaviors), the description covers prerequisites, configuration, timing, multi-button semantics, and return value. There is no output schema, so the RETURNS section compensates. The only minor gap is what happens on failure, but the sibling list and tool purpose make that acceptable; overall this is complete.
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 coverage is 100% and already includes fine parameter descriptions, so this dimension is near baseline. However, the description adds context not in the schema: the default 100 ms hold maps to ~6 frames, minimum 16 ms risks input-poll misses, and player index is 0-based (referencing retroarch_input_press). This is meaningful additional meaning beyond the raw schema.
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 opens with 'Press buttons, hold them for a duration, then release them' — a specific verb+resource+behavior — and distinguishes itself from sibling tools by explaining that this is for normal play/menu navigation while paused frame-accurate work should use press/frame_advance/release manually. This clearly separates it from retroarch_input_press and retroarch_input_release.
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?
It explicitly states when to use (emulation running, state 'playing'), when NOT to use (paused frame-accurate work) and names the alternative composition (retroarch_input_press / retroarch_frame_advance / retroarch_input_release). It also warns about two receiver behaviors (latching and one-datagram-per-frame) and tells users to pair presses with releases or use release_all.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
retroarch_load_state_currentA
PURPOSE: Restore the emulator from RetroArch's currently-selected save slot (one of slots 0-9). USAGE: Counterpart to retroarch_save_state_current. Use to undo a sequence of writes/inputs (the snapshot/experiment/restore workflow) or to start each tool-call sequence from a known baseline. Loads from whichever slot is currently selected (the same slot save_state_current would target). To load from a specific slot WITHOUT changing the current-slot pointer, use retroarch_load_state_slot instead — that's important if you're alternating between bookmarks. To start fresh from boot, use retroarch_reset. BEHAVIOR: DESTRUCTIVE TO LIVE STATE: replaces ALL current emulator state (RAM, registers, mapper, audio, framecount) with the slot file's contents. Anything not previously snapshotted is lost. The state file MUST come from the same ROM and same core version that produced it — loading mismatched files typically fails or destabilizes the core. FIRE-AND-FORGET: the NCI does NOT acknowledge this command — the call returns as soon as the UDP datagram is sent, with no confirmation that RetroArch received or applied it. To verify the effect, follow up with an observable tool (retroarch_get_status for run state, retroarch_read_memory / retroarch_read_ram for memory mutations, retroarch_screenshot for visual state). UDP packets to a not-listening RetroArch are silently dropped. If the currently-selected slot has no saved state, RetroArch silently ignores the command — no error is raised. To verify the load happened, follow up with a memory-read or screenshot. Transport: RetroArch's Network Control Interface (NCI) over UDP (default 127.0.0.1:55355, requires network_cmd_enable = true in retroarch.cfg). RETURNS: Single line 'Loaded from current slot' (UDP-send confirmation only — does NOT verify the slot existed or the load succeeded).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries full responsibility and excels. It discloses destructive impact on live state, fire-and-forget UDP behavior with no acknowledgment, silent drops when not listening, silent ignore when no save exists, and the need for follow-up verification. This goes well beyond what annotations would have provided.
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 lengthy but well-structured with PURPOSE/USAGE/BEHAVIOR/RETURNS labels. Some redundancy exists (e.g., repeated emphasis on verifying after load), but most sentences convey essential safety and operational details. It is denser than necessary but earns most of its length.
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?
Despite having no output schema, the description explicitly states the return line and its limited meaning. It covers transport configuration, prerequisites (network_cmd_enable), failure modes, and verification strategies. For a complex, side-effect-heavy tool with zero parameters, this is exceptionally complete.
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 is 4. The description adds semantic context by explaining that the 'currently-selected slot' is the one save_state_current targets, and how to select a specific slot via sibling tools, effectively giving meaning to the implicit parameter state. This exceeds the baseline.
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 states the tool's function: restoring emulator state from RetroArch's currently-selected save slot. It distinguishes itself from siblings by explicitly contrasting with retroarch_load_state_slot and retroarch_reset, making the purpose unambiguous.
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 provides explicit when-to-use guidance: as a counterpart to save_state_current, for undoing writes/inputs, and for starting from a known baseline. It also gives clear alternative tools for different scenarios (load_state_slot for specific slots without changing pointer, reset for fresh boot), satisfying the when/not/alternatives criteria.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
retroarch_load_state_slotA
PURPOSE: Load state from an explicitly-named save slot number, without modifying RetroArch's currently-selected slot pointer. USAGE: Use to load from a specific slot when you don't want to disturb the current-slot pointer (e.g. you're alternating between two bookmarks while keeping the 'live' slot for ongoing saves). For loading from the currently-selected slot, use retroarch_load_state_current — semantically distinct: this tool ignores the current-slot pointer entirely and addresses by number. Slots are numbered 0-9 by RetroArch convention. There is no retroarch_save_state_slot counterpart in the NCI — saving to a specific slot still requires walking the pointer with state_slot_plus/minus and then calling save_state_current. BEHAVIOR: DESTRUCTIVE TO LIVE STATE: replaces ALL current emulator state with the named slot's contents. Anything not previously snapshotted is lost. The state file MUST come from the same ROM and core version that produced it. Transport: RetroArch's Network Control Interface (NCI) over UDP (default 127.0.0.1:55355, requires network_cmd_enable = true in retroarch.cfg). UNLIKE most NCI control commands, LOAD_STATE_SLOT does send a reply (this client awaits it), so a UDP timeout will surface as an error here even though sibling load/save calls are fire-and-forget. If the named slot has no saved state, RetroArch's reply still indicates the command was processed — verify with a memory-read or screenshot. The current-slot pointer is unchanged after this call. RETURNS: Single line 'Loaded from slot N' echoing the requested slot number.
| Name | Required | Description | Default |
|---|---|---|---|
| slot | Yes | Save state slot number to load from. RetroArch's standard slot range is 0-9 (ten slots), but the NCI does not enforce a hard upper bound — slot numbers outside the configured range will simply find no file and silently no-op. This call does NOT change the currently-selected slot pointer (use retroarch_state_slot_plus / retroarch_state_slot_minus for that). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description fully carries the burden. It explicitly warns 'DESTRUCTIVE TO LIVE STATE: replaces ALL current emulator state with the named slot's contents', notes ROM/core version requirements, explains that LOAD_STATE_SLOT sends a reply unlike siblings, and clarifies no-op behavior and pointer invariants. This is thorough and goes far beyond basic info.
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 longer than average, but its labeled sections (PURPOSE, USAGE, BEHAVIOR, RETURNS) make it scannable and every sentence carries meaningful information. The detail is justified by the destructive nature and the need to separate from siblings. It is concise relative to the 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?
Given no annotations, no output schema, and a high-risk destructive operation, the description covers all needed context: purpose, usage alternatives, behavioral side effects, transport details, timeout behavior, verification advice, and return format. Nothing material is missing for an AI agent to select and invoke this 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 schema description coverage is 100% and already provides rich detail: integer, min 0, slot range 0-9, no hard upper bound, no-op outside range, and no pointer change. The description adds one useful nuance—this tool addresses by number and ignores current-slot pointer entirely—but it mostly reinforces schema content. Baseline 3 is appropriate.
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 starts with a clear PURPOSE: 'Load state from an explicitly-named save slot number, without modifying RetroArch's currently-selected slot pointer.' It uses a specific verb and resource, and explicitly distinguishes itself from the sibling retroarch_load_state_current. The scope and uniqueness are fully clarified.
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 USAGE section explicitly states when to use this tool ('use to load from a specific slot when you don't want to disturb the current-slot pointer') and when not to ('For loading from the currently-selected slot, use retroarch_load_state_current'). It also notes the absence of a save counterpart and suggests the alternative state_slot_plus/minus walking approach. This is exemplary guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
retroarch_pause_toggleA
PURPOSE: Toggle RetroArch's pause state — pause if running, unpause if paused. USAGE: RetroArch's NCI exposes ONLY a toggle, not separate pause/unpause commands. To reach a known state, call retroarch_get_status first to check state: playing|paused, then toggle if and only if you need to flip it. Use before a sequence of memory-inspect / write / screenshot calls when you need a stable game state across calls; pair with retroarch_frame_advance to step single frames without leaving pause. BEHAVIOR: Modifies emulator run state by flipping it. FIRE-AND-FORGET: the NCI does NOT acknowledge this command — the call returns as soon as the UDP datagram is sent, with no confirmation that RetroArch received or applied it. To verify the effect, follow up with an observable tool (retroarch_get_status for run state, retroarch_read_memory / retroarch_read_ram for memory mutations, retroarch_screenshot for visual state). UDP packets to a not-listening RetroArch are silently dropped. Calling toggle when you don't know the current state will flip it to whichever state it ISN'T — confirm with retroarch_get_status before and after if it matters. Transport: RetroArch's Network Control Interface (NCI) over UDP (default 127.0.0.1:55355, requires network_cmd_enable = true in retroarch.cfg). RETURNS: Single line 'Pause toggled' (this is a confirmation that the UDP datagram was sent, NOT that RetroArch received or acted on it).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description fully discloses critical behavioral traits: it is fire-and-forget, receives no acknowledgment, silently drops UDP if not listening, and requires verification via other tools. It also states it modifies emulator run state, giving the agent a complete operational awareness.
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 well-structured with clear section headers and every section adds essential operational detail. It is longer than a minimal toggle description, but the additional length is justified by the lack of annotations and the need to explain the fire-and-forget behavior and verification steps.
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 no annotations, no output schema, and zero parameters, the description covers all essential aspects: what it does, when to use it, expected behavior, transport details, and how to verify results. It provides a complete mental model for an agent to invoke this 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 tool takes zero parameters, and the schema already shows no properties. The description adds no parameter-specific details because there are none to document. This aligns with the baseline for zero-parameter tools.
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 opens with a specific verb ('Toggle') and resource ('RetroArch's pause state'), explicitly stating it pauses if running and unpauses if paused. This clearly distinguishes it from siblings like retroarch_get_status or retroarch_frame_advance, which serve different purposes.
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 usage section explicitly directs when to use the tool (e.g., before memory/screenshot sequences for a stable state) and names companion tools like retroarch_get_status and retroarch_frame_advance. It also warns that the NCI exposes only a toggle, preventing incorrect use as separate pause/unpause commands.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
retroarch_pingA
PURPOSE: Verify connectivity to RetroArch's Network Control Interface and return the running RetroArch version string. USAGE: Call once at start-of-session before issuing other tool calls — if it succeeds, the UDP transport is up and other tools should reach RetroArch. Use retroarch_get_status afterwards to confirm a game is loaded (ping succeeds even when RetroArch is sitting at the menu with no content). BEHAVIOR: No side effects — pure liveness probe. Transport: RetroArch's Network Control Interface (NCI) over UDP (default 127.0.0.1:55355, requires network_cmd_enable = true in retroarch.cfg). Times out after ~5 seconds with a clear error if RetroArch isn't running, has Network Commands disabled, is bound to a different host/port, or a firewall is blocking UDP 55355. RETURNS: Single line 'OK — RetroArch VERSION', e.g. 'OK — RetroArch 1.20.0'.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does exceptionally well: it declares 'No side effects — pure liveness probe,' explains the UDP transport and prerequisite (network_cmd_enable = true), the default host/port, and the ~5-second timeout with an explicit list of error conditions (RetroArch not running, disabled commands, wrong host/port, firewall blocking).
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 organized into labeled sections (PURPOSE, USAGE, BEHAVIOR, RETURNS) and every sentence adds value—purpose, usage context, transport details, error behavior, and return format. No fluff or redundancy.
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 description is complete for a zero-parameter liveness probe: it covers prerequisites, default connection details, timeout and error conditions, and the exact return format with an example. Even without an output schema or annotations, the agent has everything needed to invoke and interpret the 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?
This tool has 0 parameters, so the schema coverage is 100% and the baseline is 4. The description does not need to discuss parameters and doesn't, which is appropriate. It adds no parameter information because none exists.
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 explicitly states 'Verify connectivity to RetroArch's Network Control Interface and return the running RetroArch version string,' which is a specific verb+resource. It clearly distinguishes this from sibling tools like retroarch_get_status, which confirms game loading rather than basic connectivity.
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 explicit when-to-use guidance: 'Call once at start-of-session before issuing other tool calls.' It also names the alternative for verifying a loaded game: 'Use retroarch_get_status afterwards to confirm a game is loaded.' This fully addresses when to use and when to choose another tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
retroarch_read_memoryA
PURPOSE: Read up to 4096 bytes from emulated memory via the libretro core's system memory map (READ_CORE_MEMORY) and return them as a hex dump. USAGE: Preferred memory-read tool when the loaded core advertises a memory map (most modern cores do). If it returns 'no memory map defined', fall back to retroarch_read_ram which uses the CHEEVOS address space. To poke a value back, pair with retroarch_write_memory at the same address. The classic two-snapshot RAM-hunt workflow uses this: snapshot before a known change, snapshot after, diff for matching deltas. Maximum 4096 bytes per call (NCI line-length limit); for larger reads, batch in 4 KiB chunks. BEHAVIOR: No side effects — pure read. Transport: RetroArch's Network Control Interface (NCI) over UDP (default 127.0.0.1:55355, requires network_cmd_enable = true in retroarch.cfg). Reads work whether emulation is paused or running. Returns an error if the loaded core doesn't expose a memory map ('no memory map defined'), the address is outside any core descriptor, length < 1, length > 4096, or the UDP query times out. RetroArch may return FEWER bytes than requested if the read crosses a memory-region boundary — the response reports the actual count.
RetroArch exposes TWO distinct memory APIs with different address spaces: • READ_CORE_MEMORY / WRITE_CORE_MEMORY (used by retroarch_read_memory / retroarch_write_memory): goes through the libretro core's system memory map. Preferred when the loaded core advertises a memory map (most modern cores do). Errors with 'no memory map defined' if the loaded core doesn't. • READ_CORE_RAM / WRITE_CORE_RAM (used by retroarch_read_ram / retroarch_write_ram): uses the achievement (CHEEVOS) address space. Works even when no core memory map is defined, but addresses follow CHEEVOS conventions, not the system bus. Use as a fallback when read_memory returns 'no memory map defined'. Both APIs depend on the loaded core's exposed mapping — addresses you used on a different core / system will NOT carry over.
RETURNS: Header line 'ADDR_HEX [N bytes]:' followed by space-separated 2-digit uppercase hex bytes.
| Name | Required | Description | Default |
|---|---|---|---|
| length | Yes | Number of consecutive bytes to read (1-4096). Hard cap is RetroArch's NCI single-datagram size; chunk larger reads yourself. RetroArch may return fewer bytes if the read crosses a memory-region boundary in the core's descriptor list. | |
| address | Yes | Starting address in the libretro core's system memory map (NOT the CHEEVOS address space — that's read_ram). Address layout depends on the loaded core: e.g. SNES WRAM is typically at 0x7E0000-0x7FFFFF, GBA EWRAM at 0x02000000-0x0203FFFF, Genesis 68K RAM at 0xFF0000-0xFFFFFF. Reads `length` consecutive bytes starting here. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden and does so thoroughly. It discloses 'No side effects — pure read', transport details over UDP, behavior while paused/running, specific error conditions (no memory map, address out of range, length out of bounds, timeout), and the important nuance that RetroArch may return fewer bytes than requested when crossing memory-region boundaries.
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 well-structured with clear labels (PURPOSE, USAGE, BEHAVIOR, RETURNS) and is front-loaded with the primary purpose. It is longer than strictly necessary, and the distinction between the two memory APIs is explained twice (once in USAGE and again in a dedicated comparison section), but the redundancy is mild and each section adds value.
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 no output schema and no annotations, the description is remarkably complete. It describes the return format, error conditions, fallback strategy, transport prerequisites, and core-specific address behavior. The only missing element might be example output, but the return format is clearly specified.
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?
Although schema coverage is 100%, the description adds substantial meaning beyond the schema: it provides concrete example address spaces (SNES WRAM at 0x7E0000, GBA EWRAM at 0x02000000, Genesis 68K RAM at 0xFF0000), clarifies that addresses are system-map not CHEEVOS, and explains the 4096-byte cap is due to NCI line-length limits. This goes well beyond the baseline 3.
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 opens with a specific verb+resource statement: 'Read up to 4096 bytes from emulated memory via the libretro core's system memory map (READ_CORE_MEMORY) and return them as a hex dump.' It clearly distinguishes this tool from retroarch_read_ram by naming the alternative and explaining when each should be used.
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 USAGE section explicitly states when to use this tool versus alternatives: 'Preferred memory-read tool when the loaded core advertises a memory map (most modern cores do). If it returns 'no memory map defined', fall back to retroarch_read_ram.' It also provides a pairing recommendation with retroarch_write_memory and describes the RAM-hunt workflow, giving concrete context for use.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
retroarch_read_ramA
PURPOSE: Read up to 4096 bytes from emulated memory via the achievement (CHEEVOS) address space (READ_CORE_RAM) and return them as a hex dump. USAGE: Fallback memory-read tool — use when retroarch_read_memory returns 'no memory map defined' (older cores or those without an exposed system memory map can still respond to the older CHEEVOS read API). To poke back, pair with retroarch_write_ram at the same CHEEVOS address. Maximum 4096 bytes per call (NCI line-length limit). BEHAVIOR: No side effects — pure read. Transport: RetroArch's Network Control Interface (NCI) over UDP (default 127.0.0.1:55355, requires network_cmd_enable = true in retroarch.cfg). Reads work whether emulation is paused or running. Returns an error if the address is invalid for the CHEEVOS space, length < 1, length > 4096, or the UDP query times out. Like read_memory, RetroArch may return fewer bytes than requested at memory-region boundaries.
RetroArch exposes TWO distinct memory APIs with different address spaces: • READ_CORE_MEMORY / WRITE_CORE_MEMORY (used by retroarch_read_memory / retroarch_write_memory): goes through the libretro core's system memory map. Preferred when the loaded core advertises a memory map (most modern cores do). Errors with 'no memory map defined' if the loaded core doesn't. • READ_CORE_RAM / WRITE_CORE_RAM (used by retroarch_read_ram / retroarch_write_ram): uses the achievement (CHEEVOS) address space. Works even when no core memory map is defined, but addresses follow CHEEVOS conventions, not the system bus. Use as a fallback when read_memory returns 'no memory map defined'. Both APIs depend on the loaded core's exposed mapping — addresses you used on a different core / system will NOT carry over.
RETURNS: Header line 'ADDR_HEX [N bytes, CHEEVOS]:' followed by space-separated 2-digit uppercase hex bytes.
| Name | Required | Description | Default |
|---|---|---|---|
| length | Yes | Number of consecutive bytes to read (1-4096). Hard cap is RetroArch's NCI single-datagram size. May return fewer bytes at region boundaries. | |
| address | Yes | Starting address in the CHEEVOS (achievements) address space — distinct from the libretro system memory map used by retroarch_read_memory. CHEEVOS addresses follow per-system conventions used by RetroAchievements (e.g. SNES CHEEVOS addresses for WRAM start at 0x000000, not the SNES system bus 0x7E0000). If unsure, retroarch_read_memory is usually the right starting point. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, so the description carries full burden. It discloses 'No side effects — pure read', behavior when paused/running, error conditions (invalid address, length bounds, timeout), and the caveat that fewer bytes may be returned at region boundaries. Transport and config requirements are also stated.
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 long but well-structured with PURPOSE, USAGE, BEHAVIOR, API comparison, and RETURNS sections. It front-loads the core purpose and usage, and every paragraph adds necessary context for correct invocation. No fluff.
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 no output schema and no annotations, the description fully covers return format, error handling, transport details, address space differences, and edge cases. It provides enough context for an agent to decide when to use this tool and interpret results 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?
Schema coverage is 100% and the schema already provides detailed parameter descriptions. The description adds extra semantic value by explaining the CHEEVOS address space distinction, cross-core non-portability of addresses, and the pairing with write_ram. This goes beyond the schema.
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 opens with a specific verb and resource: 'Read up to 4096 bytes from emulated memory via the achievement (CHEEVOS) address space (READ_CORE_RAM) and return them as a hex dump.' It clearly distinguishes from sibling retroarch_read_memory by explicitly naming the CHEEVOS space and framing this tool as a fallback.
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 explicit when-to-use guidance: 'use when retroarch_read_memory returns "no memory map defined"' and contrasts the two memory APIs, naming preferred vs fallback. Also suggests pairing with retroarch_write_ram for write-back, and warns that addresses don't carry over across cores.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
retroarch_resetA
PURPOSE: Soft-reset the running game — equivalent to pressing the console's reset button (NOT a power cycle). USAGE: Use to start fresh from the game's reset vector. To return to a specific known-good point instead of boot, use retroarch_load_state_current or retroarch_load_state_slot with a previously saved state. Note this is a SOFT reset (button reset): RAM contents and any cart-internal state may persist depending on the system, unlike a true power cycle. BEHAVIOR: DESTRUCTIVE: triggers the loaded core's reset routine, which on most systems clears registers, resets the PC to the reset vector, and starts the boot sequence over. Unsaved game progress is lost. The loaded ROM stays loaded — only volatile state is affected. FIRE-AND-FORGET: the NCI does NOT acknowledge this command — the call returns as soon as the UDP datagram is sent, with no confirmation that RetroArch received or applied it. To verify the effect, follow up with an observable tool (retroarch_get_status for run state, retroarch_read_memory / retroarch_read_ram for memory mutations, retroarch_screenshot for visual state). UDP packets to a not-listening RetroArch are silently dropped. To confirm the reset took, follow up with retroarch_get_status (state should still be 'playing') and/or a screenshot. Transport: RetroArch's Network Control Interface (NCI) over UDP (default 127.0.0.1:55355, requires network_cmd_enable = true in retroarch.cfg). RETURNS: Single line 'Game reset' (UDP-send confirmation only — does NOT verify the reset executed).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Without annotations, the description carries full burden. It discloses destructive nature ('triggers the loaded core's reset routine... Unsaved game progress is lost'), the soft-reset semantics versus power cycle, fire-and-forget behavior with no acknowledgement, and silent UDP drops. Also recommends verification via other tools.
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?
Structured in labeled sections (PURPOSE, USAGE, BEHAVIOR, TRANSPORT, RETURNS) with the core action first. Every sentence provides necessary operational details (reset semantics, destructive effects, verification steps, transport requirements) without redundancy.
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's complexity (missing annotations, no output schema, zero parameters), the description covers all essential aspects: transport protocol, prerequisites, return value, side effects, and verification strategy. It also cross-references sibling tools for follow-up, making it self-sufficient.
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 description cannot add parameter semantics beyond the schema. However, it clarifies the return value ('Single line 'Game reset'') and that it is only a send confirmation, which is useful context. Baseline for no params is 4.
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?
Clearly states the function: 'Soft-reset the running game — equivalent to pressing the console's reset button (NOT a power cycle).' Distinguishes from power cycle and mentions alternatives like load state, so it is unambiguous and differentiated from siblings.
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?
Explicitly explains when to use: 'Use to start fresh from the game's reset vector.' Also says 'To return to a specific known-good point instead of boot, use retroarch_load_state_current or retroarch_load_state_slot...' This provides clear usage guidance and names alternative tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
retroarch_save_state_currentA
PURPOSE: Save the entire emulator state to RetroArch's currently-selected save slot (one of slots 0-9). USAGE: Use as a rollback point before risky writes, to bookmark interesting game states, or to share repro states. RetroArch's NCI has NO 'save to slot N' command — to target a specific slot, you must first walk the slot pointer there with retroarch_state_slot_plus / retroarch_state_slot_minus, then call this. The current slot is RetroArch's internal state and is NOT reported back by the NCI, so if you don't track it yourself, observe the on-screen slot indicator after each plus/minus or use retroarch_show_message as a confirmation echo. The companion retroarch_load_state_current restores from the same slot. For path-based savestate I/O (no slots), there is no NCI equivalent — use the BizHawk or mGBA MCP servers instead. BEHAVIOR: DESTRUCTIVE TO TARGET SLOT FILE: overwrites whatever was previously in the currently-selected slot with no prompt or backup. The state file lands in RetroArch's configured savestate_directory (queryable via retroarch_get_config). State files are bound to the EXACT ROM and core version that produced them — loading on a different ROM or core typically fails. FIRE-AND-FORGET: the NCI does NOT acknowledge this command — the call returns as soon as the UDP datagram is sent, with no confirmation that RetroArch received or applied it. To verify the effect, follow up with an observable tool (retroarch_get_status for run state, retroarch_read_memory / retroarch_read_ram for memory mutations, retroarch_screenshot for visual state). UDP packets to a not-listening RetroArch are silently dropped. To verify the save happened, retroarch_load_state_current it back and observe via memory-read or screenshot. Transport: RetroArch's Network Control Interface (NCI) over UDP (default 127.0.0.1:55355, requires network_cmd_enable = true in retroarch.cfg). RETURNS: Single line 'Saved to current slot' (UDP-send confirmation only — does NOT verify the file was written, nor report which slot number it landed in).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and excels. It discloses that the tool is 'DESTRUCTIVE TO TARGET SLOT FILE', overwriting without prompt/backup, that it is fire-and-forget with no acknowledgment, that UDP packets can be silently dropped, and that state files are bound to ROM/core versions. Verification strategies are also provided.
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 long but exceptionally well-structured with labeled sections (PURPOSE, USAGE, BEHAVIOR, RETURNS). Every sentence adds critical operational detail—overwrite risk, fire-and-forget behavior, verification, transport config—making it dense but not wasteful.
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 no output schema, no annotations, and no parameters, so the description must fully compensate. It covers return value, failure modes, verification steps, transport prerequisites, and slot-selection mechanics. This is complete for a destructive, non-acknowledged UDP command.
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 is 4. The description adds essential meaning beyond the empty schema by explaining that the target is the 'currently-selected save slot' and how to select a specific slot using retroarch_state_slot_plus/minus. This is valuable semantic context absent from the schema.
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 opens with a specific verb and resource: 'Save the entire emulator state to RetroArch's currently-selected save slot (one of slots 0-9).' It clearly distinguishes the save action from sibling tools like retroarch_load_state_current and retroarch_state_slot_plus.
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?
Explicit usage guidance is provided: 'Use as a rollback point before risky writes, to bookmark interesting game states, or to share repro states.' It also explains when NOT to use it (for path-based I/O, use BizHawk/mGBA) and how to target a specific slot via sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
retroarch_screenshotA
PURPOSE: Capture a PNG screenshot of the current emulator display and save it to RetroArch's configured screenshot directory. USAGE: Use to capture visible game state for inspection, sequence documentation, or to verify that a fire-and-forget control command (pause / reset / load_state / write) had a visible effect. To capture a specific game state, pause / advance frames / load state first to get the frame you want, then call this. IMPORTANT: unlike most screenshot tools, this one DOES NOT take a path argument — RetroArch saves to its own configured screenshot_directory, which the NCI does not expose (it is NOT readable via retroarch_get_config). To find the file, check RetroArch's settings UI (Settings → Directory → Screenshots) or look at where screenshots normally land for your install. BEHAVIOR: Writes a new timestamped PNG to RetroArch's screenshot directory — no existing files are overwritten (RetroArch generates a fresh filename per shot). FIRE-AND-FORGET: the NCI does NOT acknowledge this command — the call returns as soon as the UDP datagram is sent, with no confirmation that RetroArch received or applied it. To verify the effect, follow up with an observable tool (retroarch_get_status for run state, retroarch_read_memory / retroarch_read_ram for memory mutations, retroarch_screenshot for visual state). UDP packets to a not-listening RetroArch are silently dropped. The returned message confirms only that the SCREENSHOT command was sent, not that the file was actually written (disk full, permission denied, etc. would fail silently from the tool's perspective). Transport: RetroArch's Network Control Interface (NCI) over UDP (default 127.0.0.1:55355, requires network_cmd_enable = true in retroarch.cfg). RETURNS: Single line 'Screenshot saved to RetroArch's configured screenshot directory' (UDP-send confirmation only).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It discloses fire-and-forget UDP behavior, no acknowledgement, silently dropped packets, lack of file-write confirmation, timestamped filenames, non-overwriting, and the inaccessible screenshot_directory. This is exceptionally thorough and leaves no critical ambiguity.
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?
Though long, the description is well-structured with clear labeled sections (PURPOSE, USAGE, BEHAVIOR, RETURNS) and every sentence delivers necessary operational detail. It is front-loaded with the purpose and uses formatting to enhance scannability, making the length justified.
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 absence of annotations and output schema, this description is remarkably complete. It covers transport prerequisites, failure modes, verification strategies, and return-value semantics, and even explains how to locate the output file. It leaves no meaningful gap for an AI agent to misinterpret or misuse the 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?
With zero parameters and a 100% coverage baseline, the description still adds significant value by explicitly explaining why there is no path argument: RetroArch uses its own configured directory, not exposed via the NCI. This prevents the agent from assuming a path parameter exists and clarifies the tool's role despite the empty schema.
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 opens with a clear, specific verb and resource: 'Capture a PNG screenshot of the current emulator display and save it to RetroArch's configured screenshot directory.' It also distinguishes itself from typical screenshot tools by explicitly stating it does NOT accept a path argument, which sets it apart from any sibling tools or generic expectations.
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 explicit when-to-use guidance: for inspection, sequence documentation, or verifying visible effects of fire-and-forget commands. It explains the workflow (pause/advance/load state first) and contrasts with observation alternatives like retroarch_get_status, retroarch_read_memory, and retroarch_read_ram, making the decision boundary clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
retroarch_show_messageA
PURPOSE: Display a single-line notification message overlaid on the RetroArch window (OSD). USAGE: For in-emulator debug output, progress markers during long scripts, or text to a human watching the RetroArch window. Purely cosmetic — no effect on game state. The ONLY way to push agent-generated text onto the RetroArch display; there is no read-the-screen counterpart. BEHAVIOR: Renders the message in RetroArch's notification area for ~3 seconds (RetroArch's default notification timeout, configurable via the input_overlay_show_inputs_port setting family). Messages are NOT queued — rapid calls replace the previous message before users can read it. FIRE-AND-FORGET: the NCI does NOT acknowledge this command — the call returns as soon as the UDP datagram is sent, with no confirmation that RetroArch received or applied it. To verify the effect, follow up with an observable tool (retroarch_get_status for run state, retroarch_read_memory / retroarch_read_ram for memory mutations, retroarch_screenshot for visual state). UDP packets to a not-listening RetroArch are silently dropped. Transport: RetroArch's Network Control Interface (NCI) over UDP (default 127.0.0.1:55355, requires network_cmd_enable = true in retroarch.cfg). RETURNS: 'Showed: MESSAGE' echoing what was sent (UDP-send confirmation only — does NOT verify the overlay rendered).
| Name | Required | Description | Default |
|---|---|---|---|
| message | Yes | UTF-8 message text. Spaces and most punctuation are preserved verbatim. NEWLINES (\n / \r) TRUNCATE the message — the NCI protocol is line-terminated, so anything after the first newline is silently dropped on the wire. Keep messages to ONE LINE; recommended ≤80 chars to fit RetroArch's notification overlay without horizontal clipping (the exact width depends on the user's video resolution and font size). Consecutive calls REPLACE rather than queue, so use one message per logical event rather than emitting a stream of status updates. Special characters: percent-signs are safe (RetroArch does NOT printf-interpret the string), quotes are safe (no shell interpolation), but ASCII control bytes other than space are likely rendered as boxes or stripped. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description bears the full burden. It thoroughly discloses behavior: ~3-second display duration, non-queuing of messages, fire-and-forget NCI with no acknowledgment, silent UDP drop when RetroArch is not listening, and the fact that the return value only confirms UDP send, not rendering. It also notes the requirement for 'network_cmd_enable = true'.
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 well-structured with labeled sections (PURPOSE, USAGE, BEHAVIOR, TRANSPORT, RETURNS) and every sentence contributes useful information. It is somewhat lengthy due to the many behavioral caveats, but the length is justified given 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?
Without an output schema, the description explains the return value ('Showed: MESSAGE' as UDP-send confirmation only) and the overall semantics. It covers transport, configuration prerequisites, failure modes, and verification strategies, making it complete for an agent to correctly invoke and interpret the 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 covers the 'message' parameter with 100% coverage, including detailed notes on newlines, length, and special characters. The tool description adds little beyond the schema regarding the parameter itself, but the schema already provides the necessary semantics, so a baseline of 3 is appropriate.
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 ('Display') and resource ('single-line notification message overlaid on the RetroArch window (OSD)'). It also distinguishes the tool from siblings by noting it is 'The ONLY way to push agent-generated text onto the RetroArch display; there is no read-the-screen counterpart.'
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?
Explicitly describes when to use the tool: 'For in-emulator debug output, progress markers during long scripts, or text to a human watching the RetroArch window.' It also clarifies it is cosmetic and provides guidance on verification ('To verify the effect, follow up with an observable tool...'), effectively explaining when alternative tools should be used.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
retroarch_state_slot_minusA
PURPOSE: Decrement RetroArch's currently-selected save slot pointer by 1 (e.g. slot 3 → slot 2). USAGE: Counterpart to retroarch_state_slot_plus. Combine with retroarch_save_state_current or retroarch_load_state_current to target a lower-numbered slot — these tools always operate on the current slot. RetroArch's NCI exposes NO way to set the slot directly to N or to query the current slot number, so track it client-side or walk from a known position. For loading a specific slot WITHOUT changing the pointer, use retroarch_load_state_slot. BEHAVIOR: Mutates RetroArch's internal current-slot pointer (-1). Wraps or clamps per RetroArch's slot-cycling configuration (typically wraps at 0 → 9). FIRE-AND-FORGET: the NCI does NOT acknowledge this command — the call returns as soon as the UDP datagram is sent, with no confirmation that RetroArch received or applied it. To verify the effect, follow up with an observable tool (retroarch_get_status for run state, retroarch_read_memory / retroarch_read_ram for memory mutations, retroarch_screenshot for visual state). UDP packets to a not-listening RetroArch are silently dropped. The new slot number is NOT reported back — track it client-side or watch the on-screen slot indicator. No effect on emulator memory / run state — only the slot pointer used by future save_state_current / load_state_current calls changes. Transport: RetroArch's Network Control Interface (NCI) over UDP (default 127.0.0.1:55355, requires network_cmd_enable = true in retroarch.cfg). RETURNS: Single line 'Decremented current slot' (UDP-send confirmation only — does NOT report the new slot number).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description fully discloses behavior: it mutates the pointer, wraps/clamps, is fire-and-forget with no acknowledgment, UDP packets are silently dropped, and no slot number is returned. It also notes no effect on emulator memory/run state. This is exemplary transparency for a network command tool.
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 well-structured with labeled sections (PURPOSE, USAGE, BEHAVIOR, FIRE-AND-FORGET, Transport, RETURNS) and front-loads the core purpose. However, it is somewhat verbose with minor redundancy, such as repeating that the new slot number is not reported back in both the BEHAVIOR and RETURNS sections.
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's complexity (mutating RetroArch state via UDP), the description covers all necessary context: prerequisites, exact behavior, consequences, verification methods, and return value. It also addresses the lack of an output schema by explaining what the return line means.
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 and an empty schema, so there is nothing to explain; baseline 4 applies. The description adds value by explaining the unspoken semantics of the operation itself, though no parameter-specific detail is needed.
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 begins with 'Decrement RetroArch's currently-selected save slot pointer by 1' which clearly states the verb, resource, and expected effect. It also distinguishes from siblings by naming retroarch_state_slot_plus and retroarch_load_state_slot, making the tool's unique role unambiguous.
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?
Explicit guidance is provided: 'Counterpart to retroarch_state_slot_plus' and 'For loading a specific slot WITHOUT changing the pointer, use retroarch_load_state_slot.' It also advises tracking the slot client-side because no direct set/query exists, giving clear context on when and how to use this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
retroarch_state_slot_plusA
PURPOSE: Increment RetroArch's currently-selected save slot pointer by 1 (e.g. slot 3 → slot 4). USAGE: Combine with retroarch_save_state_current or retroarch_load_state_current to target a specific slot — these tools always operate on the current slot, so to save TO slot 5 you must walk the pointer there first. Pair with retroarch_state_slot_minus to walk backwards. RetroArch's NCI exposes NO way to set the slot directly to N or to query the current slot number, so if you don't track it yourself you must walk from a known position (e.g. slot 0) or observe the on-screen indicator. For loading a specific slot WITHOUT changing the pointer, use retroarch_load_state_slot instead. BEHAVIOR: Mutates RetroArch's internal current-slot pointer (+1). Wraps or clamps per RetroArch's slot-cycling configuration (typically wraps at 9 → 0). FIRE-AND-FORGET: the NCI does NOT acknowledge this command — the call returns as soon as the UDP datagram is sent, with no confirmation that RetroArch received or applied it. To verify the effect, follow up with an observable tool (retroarch_get_status for run state, retroarch_read_memory / retroarch_read_ram for memory mutations, retroarch_screenshot for visual state). UDP packets to a not-listening RetroArch are silently dropped. The new slot number is NOT reported back — track it client-side or watch the on-screen slot indicator. No effect on emulator memory / run state — only the slot pointer used by future save_state_current / load_state_current calls changes. Transport: RetroArch's Network Control Interface (NCI) over UDP (default 127.0.0.1:55355, requires network_cmd_enable = true in retroarch.cfg). RETURNS: Single line 'Incremented current slot' (UDP-send confirmation only — does NOT report the new slot number).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It discloses mutation of the internal pointer, wrap/clamp behavior, fire-and-forget semantics with no acknowledgment, silent UDP drops, lack of slot-number reporting, and no effect on memory/run state. This is exemplary transparency.
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 front-loaded with PURPOSE, then USAGE, BEHAVIOR, and RETURNS. Though long, every sentence addresses a distinct operational need (e.g., NCI limitations, verification strategies, return behavior), and there is no fluff.
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 no annotations, no output schema, and zero parameters, the description must be self-sufficient. It covers purpose, usage, behavioral caveats, transport, verification, and return format — complete for the complexity of a fire-and-forget UDP command.
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?
This tool has zero parameters, so the schema coverage is 100% vacuously. The baseline for 0 params is 4; the description adds no parameter-specific details because none exist, but it explains the operational semantics fully without needing parameter documentation.
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 begins with a specific verb and resource: 'Increment RetroArch's currently-selected save slot pointer by 1 (e.g. slot 3 → slot 4).' This clearly distinguishes it from siblings like retroarch_state_slot_minus and retroarch_load_state_slot.
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?
Extremely explicit usage guidance: combine with save_state_current/load_state_current, pair with state_slot_minus, and explicitly states when to use retroarch_load_state_slot instead. It also warns about the inability to set the slot directly, which is critical for correct tool selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
retroarch_write_memoryA
PURPOSE: Write a byte sequence to emulated memory via the libretro core's system memory map (WRITE_CORE_MEMORY). USAGE: Preferred memory-write tool when the loaded core advertises a memory map. Use for cheats, debug pokes, and game-state mutations (give a player N lives, unlock a flag, install a cheat table). If it returns 'no memory map defined', fall back to retroarch_write_ram. Maximum 4096 bytes per call (NCI line-length limit); for larger writes, batch in 4 KiB chunks. To establish a rollback point first, use retroarch_save_state_current. BEHAVIOR: DESTRUCTIVE: overwrites N bytes starting at address with no undo (snapshot via retroarch_save_state_current first if you need rollback). Disables RetroArch's hardcore mode for the rest of the session (RetroArch silently flips this flag when any memory-write NCI command is used). UNLIKE most NCI commands, this one DOES return a count — RetroArch replies with the number of bytes actually written, which may be less than requested if a read-only descriptor is hit mid-write (writes still apply up to that boundary). Direct memory write — bypasses MBC/mapper/DMA semantics. Transport: RetroArch's Network Control Interface (NCI) over UDP (default 127.0.0.1:55355, requires network_cmd_enable = true in retroarch.cfg). Returns an error if the loaded core doesn't expose a memory map, the address is invalid, the byte array is empty or > 4096, or the UDP query times out.
RetroArch exposes TWO distinct memory APIs with different address spaces: • READ_CORE_MEMORY / WRITE_CORE_MEMORY (used by retroarch_read_memory / retroarch_write_memory): goes through the libretro core's system memory map. Preferred when the loaded core advertises a memory map (most modern cores do). Errors with 'no memory map defined' if the loaded core doesn't. • READ_CORE_RAM / WRITE_CORE_RAM (used by retroarch_read_ram / retroarch_write_ram): uses the achievement (CHEEVOS) address space. Works even when no core memory map is defined, but addresses follow CHEEVOS conventions, not the system bus. Use as a fallback when read_memory returns 'no memory map defined'. Both APIs depend on the loaded core's exposed mapping — addresses you used on a different core / system will NOT carry over.
RETURNS: Single line 'Wrote N bytes → ADDR_HEX' where N is RetroArch's reported actual byte count.
| Name | Required | Description | Default |
|---|---|---|---|
| bytes | Yes | Byte values to write, one per element (each 0-255). Length 1-4096 (hard cap from RetroArch's NCI single-datagram size). Written sequentially from `address`. If a read-only descriptor is encountered mid-array, the write stops at that boundary and the response reports how many bytes actually landed. | |
| address | Yes | Starting address in the libretro core's system memory map (NOT CHEEVOS space). Bytes are written sequentially address, address+1, ..., address+N-1. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, but the description fully discloses behavioral traits: it is DESTRUCTIVE with no undo, disables RetroArch's hardcore mode, may write fewer bytes than requested if a read-only descriptor is hit, and returns an actual byte count. This goes well beyond the basic 'writes memory' expectation and covers side effects and edge cases.
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 long but well-structured with clear PURPOSE, USAGE, BEHAVIOR, and RETURNS sections. Every section adds essential information—fallback logic, destructive side effects, return format, and error conditions—with no filler or redundancy. The structure makes it easy for an agent to parse and extract key facts 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?
With no output schema, the description explicitly states the return format ('Wrote N bytes → ADDR_HEX') and explains the meaning of the count. It also covers error cases, prerequisites (network_cmd_enable), the distinction between the two memory APIs, and the fact that addresses don't carry across cores. This makes the tool fully understandable without external documentation.
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 already provides highly detailed descriptions for both parameters, including the 0-255 range, 1-4096 length cap, sequential write behavior, and the distinction from CHEEVOS space (100% coverage). The description adds little new parameter-specific meaning beyond the schema, mostly repeating or rephrasing the same constraints, so the baseline 3 applies.
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 opens with a specific verb and resource: 'Write a byte sequence to emulated memory via the libretro core's system memory map (WRITE_CORE_MEMORY).' It clearly identifies the target memory space and distinguishes this tool from the sibling retroarch_write_ram by stating this is the 'preferred' tool when a memory map is advertised.
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 explicit usage context: 'Use for cheats, debug pokes, and game-state mutations.' It names an alternative tool (retroarch_write_ram) as a fallback and specifies a prerequisite (use retroarch_save_state_current for rollback). This makes the when-to-use vs. when-not-to-use very clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
retroarch_write_ramA
PURPOSE: Write a byte sequence to emulated memory via the achievement (CHEEVOS) address space (WRITE_CORE_RAM). USAGE: Fallback memory-write tool — use when retroarch_write_memory returns 'no memory map defined' or the core only supports the older CHEEVOS write API. Maximum 4096 bytes per call (NCI line-length limit). To verify the write landed (this command does NOT acknowledge — see BEHAVIOR), follow up with retroarch_read_ram at the same address. To establish a rollback point first, use retroarch_save_state_current. BEHAVIOR: DESTRUCTIVE: overwrites bytes starting at address with no undo (snapshot via retroarch_save_state_current first if you need rollback). Disables RetroArch's hardcore mode for the rest of the session. FIRE-AND-FORGET: the NCI does NOT acknowledge this command — the call returns as soon as the UDP datagram is sent, with no confirmation that RetroArch received or applied it. To verify the effect, follow up with an observable tool (retroarch_get_status for run state, retroarch_read_memory / retroarch_read_ram for memory mutations, retroarch_screenshot for visual state). UDP packets to a not-listening RetroArch are silently dropped. This is the key behavioral difference vs retroarch_write_memory, which DOES return a count: write_ram has no way to report a partial write or a rejected address — the only way to verify is a follow-up retroarch_read_ram. Direct memory write — bypasses MBC/mapper/DMA semantics. Transport: RetroArch's Network Control Interface (NCI) over UDP (default 127.0.0.1:55355, requires network_cmd_enable = true in retroarch.cfg). Local input validation rejects empty arrays, > 4096 bytes, or values outside 0-255 before the UDP send.
RetroArch exposes TWO distinct memory APIs with different address spaces: • READ_CORE_MEMORY / WRITE_CORE_MEMORY (used by retroarch_read_memory / retroarch_write_memory): goes through the libretro core's system memory map. Preferred when the loaded core advertises a memory map (most modern cores do). Errors with 'no memory map defined' if the loaded core doesn't. • READ_CORE_RAM / WRITE_CORE_RAM (used by retroarch_read_ram / retroarch_write_ram): uses the achievement (CHEEVOS) address space. Works even when no core memory map is defined, but addresses follow CHEEVOS conventions, not the system bus. Use as a fallback when read_memory returns 'no memory map defined'. Both APIs depend on the loaded core's exposed mapping — addresses you used on a different core / system will NOT carry over.
RETURNS: Single line 'Wrote N bytes → ADDR_HEX (CHEEVOS, no ack)' where N is the array length you sent. The 'no ack' in the message is a reminder that RetroArch did not confirm the write.
| Name | Required | Description | Default |
|---|---|---|---|
| bytes | Yes | Byte values to write, one per element (each 0-255). Length 1-4096 (hard cap from RetroArch's NCI single-datagram size). Written sequentially from `address`. Because RetroArch does not acknowledge this command, partial / rejected writes cannot be distinguished from successful ones at the protocol level. | |
| address | Yes | Starting address in the CHEEVOS (achievements) address space — distinct from the libretro system memory map used by retroarch_write_memory. See retroarch_read_ram for address-space caveats. Bytes are written sequentially address, address+1, ... |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden and excels. It discloses destructive overwrites with no undo, hardcore-mode disabling, fire-and-forget semantics with no acknowledgment, silent UDP drops, input validation limits, and bypassing of MBC/mapper/DMA semantics. This level of behavioral disclosure is exceptional.
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 long but well-structured with clear PURPOSE, USAGE, BEHAVIOR, and RETURNS sections, plus a bulleted comparison of the two memory APIs. It is appropriately detailed for a complex tool. Minor redundancy in repeating 'no ack' in multiple places costs a point, but overall it earns its length.
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's complexity, no output schema, and no annotations, the description is remarkably complete. It covers purpose, alternatives, behavioral caveats, transport requirements, input validation, return format, and verification strategies. It even notes the two distinct memory APIs and address-space non-portability across cores, leaving no critical 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?
Schema coverage is 100%, but the description adds substantial meaning beyond the schema: the 4096-byte NCI line-length cap, the distinct CHEEVOS address-space interpretation, sequential write ordering, and the implication of no acknowledgment for partial writes. It also clarifies that `bytes` length maps to the protocol limit and that `address` follows CHEEVOS conventions.
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 opens with a specific verb and resource: 'Write a byte sequence to emulated memory via the achievement (CHEEVOS) address space (WRITE_CORE_RAM).' It clearly distinguishes itself from the sibling retroarch_write_memory by naming the CHEEVOS address space and its role as a fallback, making the tool's purpose unambiguous.
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 explicitly states when to use this tool: 'use when retroarch_write_memory returns no memory map defined or the core only supports the older CHEEVOS write API.' It also contrasts the two memory APIs, advises using retroarch_save_state_current for a rollback point, and explains when to follow up with other tools. This is exemplary usage guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
TDQS
Every tool has a distinct purpose: input press/release/tap/analog, save/load state, memory read/write via two clearly documented APIs, status/config probes, and emulator controls. The only potential overlap between read_memory and read_ram is thoroughly disambiguated by explicit descriptions of the two address spaces and fallback guidance.
All tools follow the 'retroarch_' prefix with a consistent verb-noun or noun-verb structure (e.g., input_press, load_state_current, read_memory, get_status). Even compound names like state_slot_plus and input_release_all follow a logical pattern. No mixing of camelCase or inconsistent verb styles.
22 tools is on the higher side but appropriate for RetroArch's broad feature set, covering input, memory, save states, status, config, and screenshots. Each tool serves a distinct function with no obvious redundancy, justifying the count as slightly over the ideal range but reasonable for the domain.
The tool surface covers the core workflows of emulator control: connectivity, status, input, memory manipulation, save/load states, and screenshots. Minor gaps exist such as no direct ROM loading or slot-number query, but these can be worked around given the NCI protocol's limitations and the server's assumptions of a loaded game.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
An MCP server that provides read access to your cloud storage providers, bank accounts and more.
The official MCP Server for the Mux API
Related MCP Servers
- AlicenseAqualityCmaintenanceMCP server for PCSX2 and other emulators that speak the PINE protocol. Read and write 8/16/32/64-bit emulator memory and control save states for PlayStation-family emulation.14262MIT
- AlicenseAqualityCmaintenanceMCP server for RetroArch via its Network Control Interface. Drive any libretro core — read/write memory, save/load state, screenshot, pause/frame-advance/reset — across NES, SNES, Genesis, N64, GBA, PS1 and more.17243MIT
- AlicenseAqualityBmaintenanceMCP server for the mGBA Game Boy Advance emulator. Read and write GBA memory, inject button presses, take screenshots, save/load state, and step the emulator through a Lua bridge.18361MIT
- AlicenseAqualityCmaintenanceMCP server for BizHawk, the multi-system emulator. Drive NES, SNES, GB/GBC/GBA, Genesis, N64, PSX, Saturn and more through one Lua bridge — memory r/w across named domains, joypad input, frame-advance, screenshot, save/load state.20264MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/pythoninthegrass/mcp-retroarch'
If you have feedback or need assistance with the MCP directory API, please join our Discord server