Skip to main content
Glama

mcp-bizhawk

npm version npm downloads CI License: MIT Snyk Socket Bundlephobia npmgraph

An MCP server that exposes BizHawk — the multi-system emulator the TAS community lives in — to any MCP-compatible client (Claude Desktop, Claude Code, etc.).

One bridge, many systems: NES, SNES, Game Boy / GBC / GBA, Sega Master System / Genesis / 32X / Saturn, N64, PlayStation 1, Atari 2600/5200/7800, Lynx, ColecoVision, Intellivision, and more — all through the same MCP tools, with per-system memory domains exposed cleanly.

How it works

+------------------+    stdio     +------------------+   TCP :8766   +------------------+
|   MCP client     |   JSON-RPC   |    mcp-bizhawk   |  newline JSON |     BizHawk      |
| (Claude / etc.)  | ===========> |     (Node.js)    | <============ |    bridge.lua    |
+------------------+              +------------------+               +------------------+

The transport is inverted compared to most other emulator-MCP bridges: BizHawk's Lua doesn't have native server sockets, only an outbound comm.socketServer* client. So mcp-bizhawk runs the TCP listener, and BizHawk's Lua bridge dials in once per frame to ferry commands and replies.

Two pieces:

  • lua/bridge.lua — runs inside BizHawk's Lua Console, polls our TCP server once per frame

  • dist/index.js — the Node.js MCP server, listens on 127.0.0.1:8766 by default, exposes tools over stdio

Trade-off: this design adds ~one frame of latency per call (≈16ms at 60Hz). Fine for interactive memory hunting, save-state experimentation, and frame-by-frame inspection. Less ideal for high-rate-of-fire scripting.

Related MCP server: mcp-retroarch

Requirements

  • BizHawk 2.6.2 or newer (earlier builds use an older socket-server wire format)

  • Node.js 22+ (for the MCP server)

Tested on BizHawk 2.11.1 across SNES (Super Metroid). Should work on any system BizHawk supports.

Install

npm install -g mcp-bizhawk

Option B — npx (no install)

npx -y mcp-bizhawk

Option C — clone and develop

git clone https://github.com/dmang-dev/mcp-bizhawk
cd mcp-bizhawk
npm install        # also runs the build via the `prepare` hook

Set up the BizHawk bridge

There are two pieces to configure: telling BizHawk where to connect, and loading the bridge script.

1. Point BizHawk at the MCP server

Easiest: launch BizHawk with the socket flags directly.

EmuHawk.exe --socket_ip=127.0.0.1 --socket_port=8766 <path/to/rom>

(Adjust port if you're overriding BIZHAWK_PORT.)

Alternative: configure persistently via Settings → Customize → External Tools in BizHawk's UI.

2. Load the bridge script

In BizHawk: Tools → Lua Console → Open Script → select lua/bridge.lua from this repo.

You should see in the Lua Console:

[mcp-bizhawk] bridge starting
[mcp-bizhawk] socket server target: 127.0.0.1:8766
[mcp-bizhawk] socket receive timeout set to 50ms
[mcp-bizhawk] frame loop active — bridge is polling once per frame

And in the mcp-bizhawk process's stderr:

[mcp-bizhawk] BizHawk client connected (waiting for bridge.lua to start polling)
[mcp-bizhawk] bridge.lua is polling — bridge ready

Register with your MCP client

Claude Code (CLI)

claude mcp add bizhawk --scope user mcp-bizhawk

Verify:

claude mcp list
# bizhawk: mcp-bizhawk - ✓ Connected

Claude Desktop

Edit claude_desktop_config.json:

Platform

Path

macOS

~/Library/Application Support/Claude/claude_desktop_config.json

Windows

%APPDATA%\Claude\claude_desktop_config.json

Linux

~/.config/Claude/claude_desktop_config.json

{
  "mcpServers": {
    "bizhawk": {
      "command": "mcp-bizhawk"
    }
  }
}

Restart Claude Desktop after editing.

Other MCP clients

The server speaks standard MCP over stdio. Run mcp-bizhawk and connect any MCP client to its stdio.

Configuration

Env var

Default

Purpose

BIZHAWK_HOST

127.0.0.1

TCP host to listen on for BizHawk

BIZHAWK_PORT

8766

TCP port to listen on for BizHawk

Tools

Tool

Description

bizhawk_ping

Verify bridge connectivity (returns pong)

bizhawk_get_info

ROM name, ROM hash, framecount, memory domains, capabilities

bizhawk_list_memory_domains

List available memory domains for the loaded core

bizhawk_read8 / bizhawk_read16 / bizhawk_read32

Read u8 / u16-LE / u32-LE from memory

bizhawk_write8 / bizhawk_write16 / bizhawk_write32

Write to memory

bizhawk_read_range

Read up to 4096 bytes as a byte array

bizhawk_write_range

Write up to 4096 bytes from a byte array

bizhawk_press_buttons

Set joypad state for one player; keys are button names, values booleans

bizhawk_frame_advance

Step the emulator by N frames

bizhawk_pause / bizhawk_unpause

Pause / resume emulation

bizhawk_reset

Reset the loaded core

bizhawk_screenshot

Save a PNG of the current display to a path

bizhawk_save_state / bizhawk_load_state

Save / load emulator state to a file path

All memory r/w tools take an optional domain parameter — if omitted, the active "current" memory domain is used. Use bizhawk_list_memory_domains to discover the names available on the loaded core.

See docs/RECIPES.md for end-to-end examples (RAM hunting on SNES/NES/N64, frame-precise input, snapshot-experiment-restore, cross-system regression testing) and CHANGELOG.md for release history.

Memory domains by system (cheat sheet)

Names come straight from BizHawk's core implementation. Use bizhawk_list_memory_domains to see the exact set for the loaded ROM.

System

Main RAM domain

Other common domains

NES

RAM

PPU, OAM, PRG ROM, CHR

SNES

WRAM

VRAM, CARTROM, CARTRAM

GB/GBC

WRAM

VRAM, HRAM, OAM, ROM

GBA

EWRAM, IWRAM

VRAM, PALRAM, OAM, ROM

Genesis

68K RAM

VRAM, Z80 RAM, CARTRAM

N64

RDRAM

SP DMEM, SP IMEM, PI Reg

PSX

MainRAM

VRAM, Scratchpad, BIOS

Buttons by system

BizHawk's joypad.set takes a {ButtonName=true, ...} table where button names depend on the core. Common ones:

System

Names

NES

A, B, Up, Down, Left, Right, Start, Select

SNES

A, B, X, Y, L, R, Up, Down, Left, Right, Start, Select

GB/GBC

A, B, Up, Down, Left, Right, Start, Select

GBA

A, B, L, R, Up, Down, Left, Right, Start, Select

N64

A, B, Z, L, R, Start, Up, Down, Left, Right, C-Up, C-Down, C-Left, C-Right

Genesis

A, B, C, X, Y, Z, Up, Down, Left, Right, Start, Mode

If you're unsure, run a probe: bizhawk_press_buttons {"A": true} and watch the active core's input display in BizHawk.

Troubleshooting

Symptom

Cause / Fix

MCP tool calls hang for 10 seconds, then time out with "is the bridge.lua script still polling?"

bridge.lua isn't loaded. In BizHawk: Tools → Lua Console → Open Script → bridge.lua. Check the console for frame loop active.

BizHawk connects to the server but tool calls still time out

You're on BizHawk older than 2.6.2 — the socket wire format changed then. Upgrade BizHawk.

[mcp-bizhawk] FATAL: comm.socketServer* not available in the Lua Console

BizHawk wasn't launched with --socket_ip / --socket_port flags, and no socket server is configured in Settings → Customize → External Tools.

Tools missing in Claude after install

Restart your MCP client; Claude only enumerates servers on startup.

Memory reads return zeros for the first few seconds after boot

The emulator hasn't initialized RAM yet. Either advance some frames (bizhawk_frame_advance) or check bizhawk_get_info to confirm framecount > 0 before relying on game state.

unknown memory domain: <name>

The domain name didn't match anything for the loaded core. Call bizhawk_list_memory_domains to see the actual list — names are case-sensitive.

client.screenshot not available or savestate.* not available

Some BizHawk cores expose a slightly different surface. Check bizhawk_get_info — the capabilities map shows which optional functions are present on your current build/core combo.

Development

npm install
npm run dev      # tsc --watch — autobuilds on src/ changes

End-to-end smoke test (launches BizHawk, loads ROM + bridge, runs ping/get_info/list_memory_domains/read_range):

node .scratch/test-all.cjs "I:\path\to\your\rom.smc"

Set DEBUG=1 to dump every RX/TX line.

Debugging with the MCP Inspector

Browse and call this server's tools interactively with the MCP Inspector:

npm run inspector

Build first if you've edited src/ since your last npm install (npm run build, or keep npm run dev running). Override the listener with BIZHAWK_HOST / BIZHAWK_PORT (default 127.0.0.1:8766). tools/list works even without BizHawk connected; calling a tool needs EmuHawk running with the socket flags and lua/bridge.lua loaded.

License

MIT

Available Tools

20 tools
bizhawk_frame_advanceA

PURPOSE: Step emulation by exactly N frames (default 1) and return the new framecount. USAGE: Use for frame-precise input automation (combine with bizhawk_press_buttons), animation inspection, or letting the system initialize after a hard reset (RAM is mostly zero in the first ~30 frames after bizhawk_reset). For long jumps (thousands of frames) prefer bizhawk_save_state / bizhawk_load_state of a pre-prepared state — frame_advance scales linearly. Works whether emulation is currently paused or running and does NOT change the pause state. BEHAVIOR: Advances the game-logic clock by N frames. Each step costs roughly one real frame (~16ms at 60Hz) plus one bridge round-trip — so advancing 600 frames takes ~10 seconds wall-clock. Returns an error if the loaded core doesn't expose emu.frameadvance. RETURNS: Single line 'Advanced N frame(s). Framecount: NEW_COUNT'.

ParametersJSON Schema
NameRequiredDescriptionDefault
countNoNumber of frames to advance (≥1, default 1). Latency scales linearly: ~16ms per frame at 60Hz. New framecount = previous framecount + count.

TDQS

A5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations provided, so description carries full burden. It explains behavior: does not change pause state, works whether paused or running, scales linearly (~16ms per frame plus round-trip), and returns error if core doesn't support frameadvance. Also notes RAM behavior after reset.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Well-structured with labelled sections (PURPOSE, USAGE, BEHAVIOR, RETURNS). Every sentence is informative with zero wasted words. Highly efficient and scannable.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given a single parameter with full schema coverage and no output schema, the description covers purpose, usage, edge cases (error if core unsupported), performance characteristics, and return format. Nothing missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Only one parameter 'count' with 100% schema coverage. Description adds latency scaling and new framecount formula beyond schema's min and default. Provides practical context: 'New framecount = previous framecount + count.'

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states 'Step emulation by exactly N frames' and returns framecount. It distinguishes from siblings like pause/unpause, reset, and save/load state by focusing on frame-precise stepping.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly tells when to use (frame-precise automation, animation inspection, after reset) and when not to (prefer save/load state for long jumps). Also suggests combining with press_buttons and notes initialization after hard reset.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

bizhawk_get_infoA

PURPOSE: Get the loaded ROM's name and hash, current frame count, the list of available memory domains, the active default domain (the one used when 'domain' is omitted on read/write tool calls), and the bridge's capability map (which optional emu/client/savestate/joypad/memory methods this BizHawk build exposes). USAGE: Call after bizhawk_ping to learn what system is loaded and which optional features are available; before any memory tool call to confirm the active domain and avoid silent reads from the wrong address space; before pause / unpause / reset / screenshot / save_state to check the corresponding capabilities.* flag. BEHAVIOR: No side effects — pure read of emulator metadata. Returns 'unavailable' for fields the loaded core doesn't expose (rom_name when no ROM is loaded, framecount on cores without emu.framecount, etc.). RETURNS: Multi-line text with ROM, ROM hash, framecount, memory_domains list, active domain, and a list of any missing capabilities for this build.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description states 'No side effects — pure read of emulator metadata' and notes that fields return 'unavailable' when not applicable. With no annotations, this fully discloses behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with PURPOSE, USAGE, BEHAVIOR, RETURNS sections. Each sentence adds value without redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no output schema, the description explains the return format and contents in detail. It covers all necessary context for a zero-parameter info tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Input schema has no parameters, so schema coverage is 100%. The description adds no parameter info, but baseline for 0 params is 4. Adequate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool retrieves ROM name, hash, frame count, memory domains, active domain, and capability map. It distinguishes from sibling tools by being pure info, not a control or write action.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The USAGE section explicitly says to call after bizhawk_ping, before memory tool calls to confirm domain, and before control actions to check capabilities. It provides clear when-to-use guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

bizhawk_list_memory_domainsA

PURPOSE: List the memory domains available on the loaded core (e.g. 'WRAM', 'CARTRAM', 'VRAM', 'System Bus' on SNES; 'RAM', 'PPU', 'OAM' on NES). USAGE: Call before any memory r/w tool when you don't know the domain layout for the loaded system. The returned names are exactly what to pass as the domain parameter on bizhawk_read*/write* tools (case-sensitive). BEHAVIOR: No side effects — pure read. Returns an error if the loaded BizHawk core doesn't implement memory.getmemorydomainlist (extremely rare). RETURNS: Newline-formatted list of domain names, one per line.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Despite having no annotations, the description fully discloses behavior: no side effects (pure read), and mentions the rare error case when the core doesn't implement memory.getmemorydomainlist. This provides complete transparency for a read-only query.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise and well-structured with labeled sections (PURPOSE, USAGE, BEHAVIOR, RETURNS). Every sentence adds value, and the information is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

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 tool with no output schema. It explains the return format (newline-formatted list) and error conditions, leaving no gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has 0 parameters, so according to guidelines the baseline is 4. The description doesn't need to add parameter meaning; it confirms no parameters are required.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description explicitly states the tool's purpose: listing memory domains available on the loaded core. It provides concrete examples for SNES and NES, making it clear what the tool does and how it relates to sibling memory read/write tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear guidance on when to use the tool: 'Call before any memory r/w tool when you don't know the domain layout.' It also specifies that the returned names are exactly what to pass as the `domain` parameter (case-sensitive), eliminating ambiguity.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

bizhawk_load_stateA

PURPOSE: Restore the emulator from a previously saved .State file at the given path. USAGE: Counterpart to bizhawk_save_state. Use to undo a sequence of writes/inputs (the snapshot/experiment/restore workflow), to jump to a bookmarked game state, or to start each tool-call sequence from a known baseline. To start fresh from console boot instead, use bizhawk_reset. BEHAVIOR: DESTRUCTIVE TO LIVE STATE: replaces ALL current emulator state (RAM, registers, mapper, audio, framecount) with the file's contents. Anything not previously snapshotted is lost. The state file MUST come from the same ROM and same BizHawk core version that produced it — loading an incompatible state typically crashes the core. Returns an error if the file doesn't exist, isn't a valid BizHawk state, or the core doesn't expose savestate.load. RETURNS: Single line 'Loaded state from PATH'.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathYesAbsolute filesystem path to an existing .State file produced by bizhawk_save_state on this same ROM and BizHawk core version. Loading mismatched files typically crashes the core.

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Even without annotations, the description clearly labels the tool as destructive ('replaces ALL current emulator state') and warns of crashes from mismatched state files. No contradictions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Perfectly organized with PURPOSE, USAGE, BEHAVIOR, RETURNS labels. Every sentence is necessary and informative. No fluff.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Covers purpose, usage, behavior, return value, and error conditions. Given that annotations are absent, the description compensates fully.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and already includes the path meaning and crash warning. The tool description adds minimal new information beyond reinforcing the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb 'Restore' and the resource '.State file', and distinguishes from the sibling tools bizhawk_save_state and bizhawk_reset.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly mentions counterpoint bizhawk_save_state, provides use cases (undo, bookmark, baseline), and specifies alternative bizhawk_reset for fresh boot.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

bizhawk_pauseA

PURPOSE: Pause emulation — freeze game-logic clocks and hold the current frame on screen. USAGE: Use before a sequence of memory-inspect / write / screenshot calls when you need a stable game state across calls (so the game doesn't advance between your reads). Use bizhawk_unpause to resume; use bizhawk_frame_advance to step single frames without leaving pause. BEHAVIOR: Modifies emulator run state. The Lua bridge keeps polling the socket while paused, so all other tool calls (memory r/w, screenshot, save_state, etc.) still work. Returns an error if the loaded core doesn't expose emu.pause — check capabilities.pause in bizhawk_get_info first to handle that case gracefully. Calling pause when already paused is a no-op. RETURNS: Single line 'Emulation paused'.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations provided, so description carries full burden. It discloses: modifies emulator run state, Lua bridge keeps polling, other calls still work, returns error if core doesn't expose pause, and no-op if already paused. This is comprehensive.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with labeled sections (PURPOSE, USAGE, BEHAVIOR, RETURNS). Every sentence adds value; no fluff. It is both concise and informative.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no parameters, no output schema, and the tool's simplicity, the description is complete. It covers purpose, usage, behavior, error handling, and return value, and references sibling tools and capabilities check.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has no parameters (0 params, 100% coverage). Baseline for 0 params is 4. The description adds no parameter info because none needed, but it does add context about behavior and usage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the purpose: 'Pause emulation — freeze game-logic clocks and hold the current frame on screen.' It uses a specific verb and resource, and distinguishes itself from siblings like bizhawk_unpause and bizhawk_frame_advance.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly says when to use: 'Use before a sequence of memory-inspect / write / screenshot calls when you need a stable game state across calls.' It also provides alternatives: 'Use bizhawk_unpause to resume; use bizhawk_frame_advance to step single frames without leaving pause.'

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

bizhawk_pingA

PURPOSE: Verify that the BizHawk Lua bridge is connected and responding to RPC over the TCP socket. USAGE: Call this once at start-of-session before issuing other tool calls; if it succeeds, every other tool will work. BEHAVIOR: No side effects — pure liveness probe. Times out after ~10 seconds with a clear error if BizHawk isn't running, isn't pointed at the right host:port, or hasn't loaded lua/bridge.lua via Tools → Lua Console. RETURNS: The literal string 'pong' on success.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description fully covers behavior: no side effects, pure liveness probe, timeout of ~10 seconds, and clear error conditions. No contradictions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Structured with clear sections (PURPOSE, USAGE, BEHAVIOR, RETURNS), front-loaded, each sentence adds value, no waste.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no output schema and no parameters, the description is complete: explains purpose, usage, behavior, return value, and error conditions.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

No parameters; baseline is 4. Description adds no param info but provides comprehensive tool context beyond the empty schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description explicitly states the purpose: verifying BizHawk Lua bridge connectivity. It uses specific verb 'Verify' and distinguishes from sibling tools by being a liveness probe.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly recommends calling at start-of-session before other tools, and specifies success condition. Provides clear context for when to use.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

bizhawk_play_input_sequenceA

PURPOSE: Play a pre-built sequence of per-frame joypad inputs back-to-back, advancing one frame per element, ENTIRELY SERVER-SIDE in a single bridge round-trip. Optionally captures screenshots AND labeled memory reads at fixed frame intervals during the play, and optionally aborts play early when a specified memory address changes. All observations come back inline so the agent sees the full trajectory + game state in one tool response. USAGE: Use whenever you have ≥10 frames of inputs to play in order — TAS movie playback, scripted multi-frame sequences, AI-search of input patterns, agent-driven gameplay. ONE bridge round-trip ships N frames instead of the 2N round-trips you'd pay looping bizhawk_press_buttons + bizhawk_frame_advance(1). For sequences over ~200 frames, CHUNK. FOR AGENT-DRIVEN PLAY: combine screenshot_every, observe_memory, and stop_on_memory_change for the killer pattern — 'walk right for up to 200 frames, observing screenshot+x+y+hp every second, but STOP the moment the room ID changes'. The agent sees: where Samus was at each second, AND whether the goal (room transition) was reached, AND screenshots for visual confirmation — all in one tool response. BEHAVIOR: For each frames element, calls joypad.set with that frame's buttons then emu.frameadvance. The bridge's main poll loop is BLOCKED for the duration of the call (no other RPCs, no heartbeat) until the sequence finishes or fails. With screenshot_every, each captured screenshot adds ~1 frame of wall-clock. With observe_memory, each observation also reads the listed memory addresses at the same frame the screenshot was taken — values come back labeled by name in each observation's memory field. With stop_on_memory_change, the bridge records the listed address's value before the first frame, re-reads it after each frame, and aborts the sequence the moment it changes (a final observation is captured at the stop frame regardless of cadence). Returns an error if joypad.set / emu.frameadvance / client.screenshot is missing when needed, if any observe_memory entry references an unknown domain, if any width isn't 'u8' / 'u16' / 'u32', or if any address is out of range. RETURNS: A text summary ('Played N frames. Final framecount: M. Stopped early: yes/no [reason]. Captured K observations with their memory values') followed by K inline image content blocks (one per observation, in frame order). Each observation in the text summary includes its frame_offset and labeled memory values so the agent can correlate the visible screenshot with the game state at that exact frame.

ParametersJSON Schema
NameRequiredDescriptionDefault
framesYesArray of per-frame input objects. Each element describes ONE emulated frame: `{"buttons": {"Right": true, ...}, "player": 1}`. Empty `buttons` (or empty object) = no input on that frame. `player` defaults to 1 if omitted. Array order = frame playback order. Chunk longer sequences across multiple calls (≤200 frames each is a reasonable upper bound) to keep the bridge responsive.
screenshot_everyNoOptional. If set, capture a PNG screenshot every N frames during playback (and one extra at the final frame regardless of remainder). Each screenshot costs ~1 wall-clock frame for client.screenshot, so 60 (≈1 sec of game time) is a good default — captures meaningful state changes without doubling batch latency. Omit to skip screenshots. If `observe_memory` is also set, screenshots and memory reads happen at the same observation points.
screenshot_dirNoOptional. Directory to write screenshot PNGs into when `screenshot_every` is set. Default: C:/temp. Must exist and be writable. Files are named `<prefix>-NNNN.png` where NNNN is the frame offset within the batch (zero-padded to 4 digits).
screenshot_prefixNoOptional. Filename prefix for screenshots when `screenshot_every` is set. Default: 'obs'.
observe_memoryNoOptional. List of memory reads to perform at each observation point (alongside screenshots if `screenshot_every` is also set). Each result lands in the observation's `memory` field keyed by `name`. Use this to track game-state values per observation — e.g. on Super Metroid, track HP/X/Y/room-ID at each screenshot so you see how state changes across the play batch.
stop_on_memory_changeNoOptional. If set, the bridge reads the specified memory value before the first frame, re-reads it after every frame, and ABORTS the play sequence the moment it changes. The result will have `stopped_early: true` and `stop_reason: 'memory_changed'`. A final observation is captured at the stop frame even if it's not on the normal cadence. Killer use case: watch the room ID — Samus walks through a door, room ID changes, play stops at the exact frame of the transition.

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries full burden of behavioral disclosure. It clearly states that the bridge's main poll loop is BLOCKED during the call, that each screenshot adds ~1 frame of wall-clock, and how the stop_on_memory_change works (records initial value, checks after each frame, aborts on change). Error conditions are listed (missing methods, unknown domain, invalid width, out-of-range address). The description is transparent about all key behaviors.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured into sections (PURPOSE, USAGE, BEHAVIOR, RETURNS), and the most critical information is front-loaded. However, it is verbose; some details (like the killer pattern) are repeated in both USAGE and BEHAVIOR sections. While every sentence adds value, compactness could be improved without losing clarity. Still, it remains relatively easy to parse.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (6 parameters, nested objects, no output schema, no annotations), the description is fully complete. It covers purpose, usage, behavior, error conditions, and return format (text summary plus inline images). It explains optional features and their interactions (e.g., screenshot and memory read cadence). No gaps are apparent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% (all parameters have descriptions). The description adds substantial value beyond the schema. For example, the `screenshot_every` parameter explains that each screenshot costs ~1 frame and recommends 60 as a good default. The `observe_memory` parameter gives a concrete example for Super Metroid. The `stop_on_memory_change` parameter describes the killer use case. The `frames` parameter includes chunking advice. The descriptions provide meaningful semantics for effective tool use.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description begins with a clear statement of purpose: 'Play a pre-built sequence of per-frame joypad inputs back-to-back, advancing one frame per element, ENTIRELY SERVER-SIDE in a single bridge round-trip.' It distinguishes itself from siblings (bizhawk_press_buttons and bizhawk_frame_advance) by noting that this tool batches many frames into one call, reducing round-trips. The optional features (screenshots, memory reads, early stop) are also described, making the tool's capabilities very clear.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The USAGE section explicitly advises when to use this tool ('whenever you have ≥10 frames of inputs to play in order') and contrasts with looping the two sibling tools, which would cost 2N round-trips. It also recommends chunking for sequences over ~200 frames. However, it does not explicitly state when NOT to use it (e.g., for very short sequences it might be overkill), though the recommendation for ≥10 frames implies exclusion for shorter sequences. The guidance is clear and actionable.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

bizhawk_press_buttonsA

PURPOSE: Set the joypad button state for one player for EXACTLY the next emulated frame. USAGE: Drive games with input. Each call sets joypad state for ONE frame only — the very next frame BizHawk processes. After that frame, BizHawk's input goes back to whatever the human user is holding (typically nothing). To HOLD a button across N consecutive frames, INTERLEAVE: call bizhawk_press_buttons + bizhawk_frame_advance(count=1) N times in a loop. DO NOT call bizhawk_press_buttons once and then bizhawk_frame_advance(count=N) — only the first of those N frames sees the button; the rest are no-input. Verified empirically against SNES Super Metroid in May 2026: a 60-frame advance after a single press_buttons(Right) moved Samus the same +1 pixel as a 10-frame advance, because frames 2-60 had no input. To release a button mid-hold, just stop calling press_buttons for it; the next frame_advance will see it released. BEHAVIOR: Modifies emulator input state for the next frame poll only — no other side effects. Returns an error if the loaded core doesn't expose joypad.set. Button names that aren't valid for the active core are silently ignored by BizHawk (no error). RETURNS: Single line 'Set joypad N: BUTTON+BUTTON+...' or '... (all released)' if nothing was pressed.

Button names vary per system. Common names across cores: A, B, X, Y, Up, Down, Left, Right, Start, Select, L, R, L1, R1, L2, R2, L3, R3, C, Z, C-Up, C-Down, C-Left, C-Right, Mode. Use whatever names the active core understands — if unsure, try a name and check BizHawk's input display, or use bizhawk_get_info to confirm joypad_set is available.

ParametersJSON Schema
NameRequiredDescriptionDefault
buttonsYesMap of button name (string, case-sensitive per the active core) → pressed (boolean: true=pressed, false=released). Example: {"A": true, "Up": true} presses A and Up while leaving everything else released. Names not recognized by the active core are silently ignored.
playerNoPlayer number (1-based). Default 1. For multi-controller cores (e.g. N64 with 4 controllers) pass 2/3/4 to address other players.

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations provided; description fully covers behavior: sets input for exactly one frame, then reverts to human input, silently ignores invalid button names, returns a status line, and describes error conditions. No contradictions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Well-structured with clear sections (PURPOSE, USAGE, BEHAVIOR, RETURNS). Front-loaded with purpose. Slightly verbose due to empirical example, but each part serves a purpose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no annotations and no output schema, the description is remarkably complete: covers purpose, usage patterns, behavioral details, return format, error handling, and button name guidance. No gaps for effective use.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema covers both parameters with 100% description coverage. The description adds minimal extra meaning but includes an example for buttons and clarifies the player default. Could be slightly more detailed about button name variability.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states 'set joypad button state for one player for exactly the next emulated frame.' It provides a specific verb-resource-scope and distinguishes from siblings like bizhawk_frame_advance by clarifying frame-level granularity.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly tells when to use (drive games) and when not to (avoid single press+multiple frame_advance). Provides the correct interleaving pattern and explains how to release buttons. Includes empirical verification.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

bizhawk_read16A

PURPOSE: Read an unsigned 16-bit little-endian value from emulator memory at the given address. USAGE: Use for 16-bit fields (most game-state values: HP, score, coordinates). For single bytes use bizhawk_read8; for 32-bit values use bizhawk_read32; for non-aligned spans or big-endian fields use bizhawk_read_range and decode the bytes yourself (this tool always interprets bytes as little-endian regardless of the target system's native endianness). BEHAVIOR: No side effects — pure read. Reads two consecutive bytes (low byte at address, high byte at address+1) and combines them as little-endian. Returns an error if the named domain doesn't exist, address+2 exceeds domain size, or the core doesn't expose memory.read_u16_le. RETURNS: Single line 'ADDR_HEX: VAL_DEC (0xVAL_HEX)'.

ParametersJSON Schema
NameRequiredDescriptionDefault
addressYesByte offset within the chosen memory domain. Per-domain offsets are 0-based and INDEPENDENT of system bus addresses (e.g. SNES WRAM uses 0x09C6, NOT 0x7E09C6). Reads 2 consecutive bytes starting here. Returns an error if address < 0 or address + 2 exceeds the domain's size.
domainNoOptional case-sensitive memory domain name. Omit to use BizHawk's currently selected domain (see bizhawk_get_info → current_memory_domain). Discover available names with bizhawk_list_memory_domains; they vary per system (WRAM on SNES, RAM on NES, RDRAM on N64, 68K RAM on Genesis, MainRAM on PSX, EWRAM/IWRAM on GBA). Returns an error if the name doesn't match any domain on the loaded core.

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Despite no annotations, the description fully discloses behavioral traits: no side effects (pure read), byte ordering details (reads low byte at address, high byte at address+1, little-endian combination), and error conditions for missing domain, out-of-bounds, or missing core capability. This provides complete transparency for an agent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Structured with bold headings for clear skimming. Every sentence is relevant, though slightly wordy. Could be shortened by removing redundant examples, but remains efficient for the information conveyed.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema, but description specifies exact return format. Covers all essential aspects: purpose, usage, behavior, errors, and integration with sibling tools. Complete for a simple read tool with two parameters.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Input schema has 100% coverage with detailed descriptions. The description adds value by explicitly stating the little-endian interpretation (not in schema) and the independence of bus addresses (already in schema but reinforced). A small but meaningful addition beyond schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description clearly states verb ('Read'), resource ('unsigned 16-bit little-endian value'), and context ('from emulator memory at the given address'). Distinguishes from siblings by explicitly naming alternatives (bizhawk_read8, bizhawk_read32, bizhawk_read_range) with specific use-cases, making the tool's purpose unmistakable.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states when to use ('for 16-bit fields') and when not to use, listing exact sibling tools for other bit widths and endianness. Includes error conditions and domain selection guidance, leaving no ambiguity about appropriate invocation.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

bizhawk_read32A

PURPOSE: Read an unsigned 32-bit little-endian value from emulator memory at the given address. USAGE: Use for 32-bit fields (timestamps, large counters, pointers on 32-bit systems, RGBA colors). For 8/16-bit reads use bizhawk_read8/read16; for big-endian or unaligned multi-word reads use bizhawk_read_range and decode yourself. BEHAVIOR: No side effects — pure read. Reads four consecutive bytes starting at address and combines them as little-endian (LSB at address, MSB at address+3). Returns an error if the domain doesn't exist, address+4 exceeds the domain, or the core lacks memory.read_u32_le. RETURNS: Single line 'ADDR_HEX: VAL_DEC (0xVAL_HEX)'.

ParametersJSON Schema
NameRequiredDescriptionDefault
addressYesByte offset within the chosen memory domain. Per-domain offsets are 0-based and INDEPENDENT of system bus addresses (e.g. SNES WRAM uses 0x09C6, NOT 0x7E09C6). Reads 4 consecutive bytes starting here. Returns an error if address < 0 or address + 4 exceeds the domain's size.
domainNoOptional case-sensitive memory domain name. Omit to use BizHawk's currently selected domain (see bizhawk_get_info → current_memory_domain). Discover available names with bizhawk_list_memory_domains; they vary per system (WRAM on SNES, RAM on NES, RDRAM on N64, 68K RAM on Genesis, MainRAM on PSX, EWRAM/IWRAM on GBA). Returns an error if the name doesn't match any domain on the loaded core.

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description fully covers behavioral traits: it declares 'No side effects — pure read', explains endianness handling (LSB at address, MSB at address+3), and lists error conditions (domain missing, address out of bounds, core lacking capability). No contradictions with absent annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is structured into clear sections (PURPOSE, USAGE, BEHAVIOR, RETURNS) with no redundant sentences. Every sentence provides unique, useful information, earning its place. It is appropriately sized for a tool of this complexity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the absence of an output schema, the description fully explains the return value format and error conditions. It covers all relevant aspects for a read tool: side effects, endianness, address semantics, domain usage, and alternatives. No gaps identified.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and already describes parameters well. The description adds value by explaining that offsets are per-domain and independent of system bus addresses, and gives examples of domain names per system. It also clarifies the return format, which the schema does not cover.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states it reads a 32-bit little-endian value from emulator memory. It distinguishes itself from siblings by explicitly referencing read8/read16 and read_range for other use cases, providing a clear, specific verb+resource.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

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 (32-bit fields) and when not to (8/16-bit reads, big-endian, unaligned multi-word), naming alternative tools (bizhawk_read8/16, bizhawk_read_range). This provides clear guidance for tool selection.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

bizhawk_read8A

PURPOSE: Read an unsigned 8-bit byte from emulator memory at the given address. USAGE: Use for single-byte status flags, counters, and 8-bit fields. For 16- or 32-bit values use bizhawk_read16/read32 (one call instead of multi-byte assembly); for spans of more than ~4 bytes use bizhawk_read_range (one round-trip instead of N frame-latency hops). BEHAVIOR: No side effects — pure read. Reads work the same way whether emulation is paused or running. Returns an error if the named domain doesn't exist, the address is out of range for the domain, or the loaded core doesn't expose memory.read_u8. RETURNS: Single line 'ADDR_HEX: VAL_DEC (0xVAL_HEX)', e.g. '0x09C6: 99 (0x63)'.

ParametersJSON Schema
NameRequiredDescriptionDefault
addressYesByte offset within the chosen memory domain. Per-domain offsets are 0-based and INDEPENDENT of system bus addresses (e.g. SNES WRAM uses 0x09C6, NOT 0x7E09C6). Reads 1 consecutive byte starting here. Returns an error if address < 0 or address + 1 exceeds the domain's size.
domainNoOptional case-sensitive memory domain name. Omit to use BizHawk's currently selected domain (see bizhawk_get_info → current_memory_domain). Discover available names with bizhawk_list_memory_domains; they vary per system (WRAM on SNES, RAM on NES, RDRAM on N64, 68K RAM on Genesis, MainRAM on PSX, EWRAM/IWRAM on GBA). Returns an error if the name doesn't match any domain on the loaded core.

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description fully covers behavior: 'No side effects — pure read. Reads work the same way whether emulation is paused or running.' It also lists error conditions for missing domain, out-of-range address, or missing core functionality.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with labeled sections (PURPOSE, USAGE, BEHAVIOR, RETURNS) and every sentence adds value. It is concise without being terse.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no output schema, the description includes a RETURNS section with an example format and explains error conditions. It is complete for a simple read tool, covering all necessary context.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and the description does not add new information beyond the schema's thorough parameter descriptions. Baseline 3 is appropriate as it doesn't compensate further.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description starts with 'PURPOSE: Read an unsigned 8-bit byte from emulator memory at the given address.' This is a specific verb and resource, clearly distinguishing from sibling tools like bizhawk_read16, bizhawk_read32, and bizhawk_read_range.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The USAGE section explicitly states 'Use for single-byte status flags, counters, and 8-bit fields' and advises using bizhawk_read16/read32 for larger values or bizhawk_read_range for spans, providing clear when-to-use and 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.

bizhawk_read_rangeA

PURPOSE: Read a contiguous range of bytes from emulator memory as a hex dump. USAGE: Use for >4 bytes (one round-trip vs N frame-latency hops). Max 4096 bytes/call (BizHawk serialization limit); chunk larger reads in 4 KiB. Powers the two-snapshot RAM-hunt workflow (snapshot before/after a known change, diff for matching deltas). BEHAVIOR: No side effects — pure read. Returns an error if domain is unknown, length is out of 1-4096, or address+length exceeds the domain. RETURNS: 'ADDR_HEX [N bytes, DOMAIN]:' header + space-separated 2-digit uppercase hex bytes.

ParametersJSON Schema
NameRequiredDescriptionDefault
addressYesStarting byte offset within the chosen memory domain (0-based per-domain, NOT a system-bus address). Reads [address, address+length).
lengthYesNumber of bytes to read (1-4096; hard cap is BizHawk's per-call serialization limit).
domainNoOptional case-sensitive memory domain name. Omit to use BizHawk's currently selected domain (see bizhawk_get_info → current_memory_domain). Discover available names with bizhawk_list_memory_domains; they vary per system (WRAM on SNES, RAM on NES, RDRAM on N64, 68K RAM on Genesis, MainRAM on PSX, EWRAM/IWRAM on GBA). Returns an error if the name doesn't match any domain on the loaded core.

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

States 'No side effects — pure read' and lists three error conditions (unknown domain, length out of range, address+length exceeds domain). With no annotations, this provides good behavioral transparency, though it omits potential rate limits or other 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.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Description is structured with clear labels (PURPOSE, USAGE, BEHAVIOR, RETURNS) and every sentence adds value. It is concise, front-loading key information, and avoids redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no output schema, the description explains the return format (header + hex bytes) and error conditions. It also mentions the workflow context. However, it lacks an explicit example of the return string, which would aid completeness.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Input schema has 100% coverage with descriptions for address (0-based per-domain), length (1-4096 with hard cap), and domain (optional with examples and error condition). Description adds context beyond schema, such as the per-domain offset meaning and the chunking limit.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description clearly states 'Read a contiguous range of bytes from emulator memory' with specific verb and resource. Distinguishes from siblings by noting usage for >4 bytes and references the two-snapshot workflow, making purpose unmistakable.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states when to use: for >4 bytes to avoid multiple round-trips and max 4096 bytes per call with chunking advice. Implies when not to use by contrasting with single-byte reads, but does not explicitly name sibling tools like bizhawk_read8/16/32 as alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

bizhawk_resetA

PURPOSE: Reset the loaded core — equivalent to a hard reset (power cycle) of the emulated console. USAGE: Use to start fresh from boot. To return to a specific known-good point instead of boot, use bizhawk_load_state with a previously saved state file. BEHAVIOR: DESTRUCTIVE: RAM contents become indeterminate (typically zeroed), CPU returns to the reset vector, framecount resets to 0, joypad state clears, and any in-progress audio/video state is discarded. The loaded ROM stays loaded — only volatile state is cleared. Unsaved game progress is lost. Returns an error if the loaded core doesn't expose client.reboot_core — check capabilities.reboot_core in bizhawk_get_info first. RETURNS: Single line 'Core reset'.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Since no annotations are provided, the description fully discloses the destructive behavior, detailing exactly what changes: RAM contents become indeterminate, CPU resets, framecount resets, joypad clears, audio/video state discarded. It also notes that the ROM stays loaded and unsaved progress is lost, and mentions error conditions if the core lacks reboot_core.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with labeled sections (PURPOSE, USAGE, BEHAVIOR, RETURNS) and is concise, with each sentence adding value. No extraneous text.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity and lack of output schema, the description covers all necessary aspects: purpose, usage, behavioral details, return value, and error handling. It is complete for an agent to understand and use the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has no parameters (100% coverage), so the description does not need to add parameter information. The baseline of 3 is appropriate as it does not contribute additional parameter semantics beyond what the schema already provides.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: 'Reset the loaded core — equivalent to a hard reset (power cycle) of the emulated console.' It distinguishes itself from the sibling tool bizhawk_load_state, which is used for returning to a saved state.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit usage guidelines: 'Use to start fresh from boot.' It also tells when not to use it and suggests an alternative: 'To return to a specific known-good point instead of boot, use bizhawk_load_state with a previously saved state file.'

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

bizhawk_save_stateA

PURPOSE: Save the entire emulator state (RAM, CPU/PPU/APU registers, mapper state, sound chip state, timing) to a file at the given path. USAGE: Use as a rollback point before risky writes, to bookmark interesting game states, or to share repro states. The companion bizhawk_load_state can perfectly restore from this file. BizHawk's savestate API is path-based (NOT slot-based like mGBA's). BEHAVIOR: DESTRUCTIVE TO TARGET FILE: overwrites the file at path if it exists, with no prompt or backup. The state file is bound to the EXACT ROM and BizHawk core version that produced it — loading it on a different ROM or core version usually crashes the core. Returns an error if the parent directory doesn't exist, the path isn't writable, or the core doesn't expose savestate.save. RETURNS: Single line 'Saved state to PATH'.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathYesAbsolute filesystem path to write the .State file to (extension is convention, not required). Parent directory must exist. File is overwritten without prompt if present.

TDQS

A5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Despite no annotations, the description fully discloses destructive behavior (overwrites without prompt), compatibility constraints (bound to exact ROM and core version), and error conditions (parent directory missing, unwritable path, core not supporting save).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with clear sections (PURPOSE, USAGE, BEHAVIOR, RETURNS). Every sentence is informative and necessary, none wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter tool without output schema, the description is complete. It covers output format, error conditions, and critical behavioral details like version binding, leaving no gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, but the description adds significant value: clarifies that extension is convention not required, parent directory must exist, and file is overwritten without prompt. This context goes beyond the schema's property description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb 'save', the resource 'entire emulator state', and the target 'file at given path'. It distinguishes itself from the sibling 'bizhawk_load_state' by explicitly mentioning the companion tool for restoration.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit usage scenarios: 'rollback point before risky writes', 'bookmark interesting game states', 'share repro states'. It also differentiates from slot-based systems by noting BizHawk's path-based API.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

bizhawk_screenshotA

PURPOSE: Save a PNG screenshot of the current emulator display to the given file path. USAGE: Use to capture visible game state for inspection, comparison across savestates, or sequence documentation. The image captures whatever the emulator is currently rendering — to capture a specific game state, pause / advance frames / load state first to get the frame you want, then call this. BizHawk's underlying client.screenshot requires an explicit path (no temp-file fallback). BEHAVIOR: DESTRUCTIVE TO TARGET FILE: overwrites the file at path if it exists, with no prompt or backup. Returns an error if the parent directory doesn't exist, the path isn't writable, or the loaded core doesn't expose client.screenshot — check capabilities.screenshot in bizhawk_get_info first. RETURNS: Single line 'Screenshot saved: PATH'.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathYesAbsolute filesystem path to write the PNG to (e.g. C:/temp/snap.png on Windows, /tmp/snap.png on Linux/macOS). Parent directory must exist. File is overwritten without prompt if present.

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Thoroughly discloses destructive behavior (overwrites file without prompt), error conditions (missing parent dir, unwritable, unsupported core), and suggests checking capabilities first. With no annotations, the description fully informs the agent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Well-structured with labeled sections (PURPOSE, USAGE, BEHAVIOR, RETURNS). Every sentence adds value, no redundancy. Concise yet comprehensive.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple 1-parameter tool with no output schema, the description covers purpose, usage, behavior, and return format completely. No gaps remain.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, but the description adds significant value: absolute path requirement, examples, parent dir must exist, overwrite behavior. This fully compensates and enriches the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool saves a PNG screenshot to a given file path. It is the only screenshot tool among siblings, so differentiation is not needed but the purpose is explicit.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides clear usage context: capturing game state, and advises to pause/advance/load state first. Mentions explicit path requirement. Lacks explicit when-not-to-use, but the guidance is sufficient and context-rich.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

bizhawk_unpauseA

PURPOSE: Resume emulation after a pause, returning to normal real-time playback. USAGE: Counterpart to bizhawk_pause. Use after a paused inspection sequence is complete. To advance only a few frames without resuming full speed, use bizhawk_frame_advance instead. BEHAVIOR: Modifies emulator run state. Returns an error if the loaded core doesn't expose emu.unpause — check capabilities.unpause in bizhawk_get_info first. Calling unpause when not paused is a no-op. RETURNS: Single line 'Emulation resumed'.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations provided, so description must disclose behavior. It states it modifies run state, may error if core lacks feature (with actionable check), is no-op when not paused. Sufficient for a state-modifying tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four clearly labeled sections (PURPOSE, USAGE, BEHAVIOR, RETURNS) with minimal yet complete information. No filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no parameters, no output schema, and no annotations, description covers purpose, usage, behavior, return value, error conditions, and prerequisites. Complete for this tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Input schema has 0 parameters with 100% coverage; baseline 3. Description adds no parameter details, but that's acceptable as there are none to describe.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Clear verb+resource: 'Resume emulation after a pause'. Distinguishes from sibling bizhawk_frame_advance by stating its specific use case. No ambiguity.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states when to use ('after a paused inspection sequence') and when not to ('use bizhawk_frame_advance for frame advance'). Names alternative sibling tool directly.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

bizhawk_write16A

PURPOSE: Write an unsigned 16-bit little-endian value to emulator memory at the given address. USAGE: Use for 16-bit cheats and pokes (HP, score, coordinates). For single bytes use bizhawk_write8; for 32-bit use bizhawk_write32; for big-endian fields, byteswap and use bizhawk_write_range; for cart save RAM seeding, use bizhawk_load_state. BEHAVIOR: DESTRUCTIVE: overwrites two bytes (low byte at address, high byte at address+1) with no undo. Direct memory write — no MBC/mapper/DMA mediation, see bizhawk_write8 notes. Returns an error if the domain is unknown, address+2 exceeds the domain, value < 0 or > 65535, or the core lacks memory.write_u16_le. RETURNS: Single line 'Wrote VAL_DEC (0xVAL_HEX) → ADDR_HEX (DOMAIN)'.

ParametersJSON Schema
NameRequiredDescriptionDefault
addressYesByte offset within the chosen memory domain. Per-domain offsets are 0-based and INDEPENDENT of system bus addresses (e.g. SNES WRAM uses 0x09C6, NOT 0x7E09C6). Reads 2 consecutive bytes starting here. Returns an error if address < 0 or address + 2 exceeds the domain's size.
valueYes16-bit value to write. Must be 0-65535 (0x0000-0xFFFF). LSB is written to `address`, MSB to `address+1`. Values outside this range return an error.
domainNoOptional case-sensitive memory domain name. Omit to use BizHawk's currently selected domain (see bizhawk_get_info → current_memory_domain). Discover available names with bizhawk_list_memory_domains; they vary per system (WRAM on SNES, RAM on NES, RDRAM on N64, 68K RAM on Genesis, MainRAM on PSX, EWRAM/IWRAM on GBA). Returns an error if the name doesn't match any domain on the loaded core.

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description thoroughly discloses behavior: it is destructive ('overwrites two bytes... with no undo'), notes no mediation, lists all error conditions, and explains byte ordering. Since no annotations are provided, this fully compensates.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with labeled sections (PURPOSE, USAGE, BEHAVIOR, RETURNS). Every sentence adds value, no redundancy, and it is appropriately concise for the complexity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

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 includes a RETURNS section specifying exact output format. Schema coverage is 100%, no annotations, but the description covers all necessary behavioral and error information. The tool fits clearly among siblings.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already covers all three parameters with clear descriptions (100% coverage). The description adds context about little-endian ordering and byte placement, but does not significantly extend beyond the schema. Baseline 3, slightly elevated due to integrated behavioral notes.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description explicitly states the purpose: 'Write an unsigned 16-bit little-endian value to emulator memory at the given address.' It clearly distinguishes from sibling tools by referencing bizhawk_write8, bizhawk_write32, and others.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit usage guidance: 'Use for 16-bit cheats and pokes (HP, score, coordinates).' It also specifies alternatives for related tasks, such as using bizhawk_write8 for single bytes, bizhawk_write32 for 32-bit, etc.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

bizhawk_write32A

PURPOSE: Write an unsigned 32-bit little-endian value to emulator memory at the given address. USAGE: Use for 32-bit cheats and pokes (timestamps, large counters, pointers on 32-bit systems). For 8/16-bit values use bizhawk_write8/write16; for big-endian layouts byteswap and use bizhawk_write_range. BEHAVIOR: DESTRUCTIVE: overwrites four bytes starting at address with no undo (snapshot via bizhawk_save_state first if you need rollback). Direct memory write — bypasses MBC/mapper/DMA, see bizhawk_write8 notes. Returns an error if the domain is unknown, address+4 exceeds the domain, value < 0 or > 4294967295, or the core lacks memory.write_u32_le. RETURNS: Single line 'Wrote VAL_DEC (0xVAL_HEX) → ADDR_HEX (DOMAIN)'.

ParametersJSON Schema
NameRequiredDescriptionDefault
addressYesByte offset within the chosen memory domain. Per-domain offsets are 0-based and INDEPENDENT of system bus addresses (e.g. SNES WRAM uses 0x09C6, NOT 0x7E09C6). Reads 4 consecutive bytes starting here. Returns an error if address < 0 or address + 4 exceeds the domain's size.
valueYes32-bit value to write. Must be 0-4294967295 (0x00000000-0xFFFFFFFF). LSB lands at `address`, MSB at `address+3`. Values outside this range return an error.
domainNoOptional case-sensitive memory domain name. Omit to use BizHawk's currently selected domain (see bizhawk_get_info → current_memory_domain). Discover available names with bizhawk_list_memory_domains; they vary per system (WRAM on SNES, RAM on NES, RDRAM on N64, 68K RAM on Genesis, MainRAM on PSX, EWRAM/IWRAM on GBA). Returns an error if the name doesn't match any domain on the loaded core.

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description fully discloses destructive behavior (overwrites four bytes, no undo), error conditions, and that it bypasses MBC/mapper/DMA. Provides actionable guidance (save state first).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Well-structured with clear headings (PURPOSE, USAGE, BEHAVIOR, RETURNS). Every sentence is informative and front-loaded with purpose. No wasted words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Comprehensive coverage of purpose, usage, behavior, error conditions, and return format. Schema handles parameter details, leaving description to address agent decision-making needs fully.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% with detailed descriptions. The tool description adds practical usage examples (timestamps, large counters) and reinforces error conditions, but does not add significant new semantic detail beyond what schema already provides.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool writes a 32-bit little-endian value to emulator memory. It distinguishes from siblings like bizhawk_write8 and bizhawk_write16 by specifying bit width and endianness.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly recommends use for 32-bit cheats and pokes, and advises using alternative tools for 8/16-bit values or big-endian layouts. Includes when to avoid (e.g., need for rollback) and suggests snapshotting.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

bizhawk_write8A

PURPOSE: Write a single unsigned byte (0-255) to emulator memory at the given address. USAGE: Use for single-byte cheats, debug pokes, and game-state mutations (give a player N lives, unlock a flag, set a counter). For 16/32-bit values prefer bizhawk_write16/write32 (single call instead of byte-at-a-time); for spans use bizhawk_write_range. To seed cart save RAM realistically (with proper MBC behavior), prefer bizhawk_load_state with a pre-prepared .State file rather than poking SRAM bytes here. BEHAVIOR: DESTRUCTIVE: overwrites whatever was at address with no undo (snapshot via bizhawk_save_state first if you need rollback). The write is direct memory access — bypasses MBC bank switches, cartridge mapper side-effects, and DMA semantics — so it cannot be used to emulate cartridge hardware. Returns an error if the domain is unknown, address is out of range, value < 0 or > 255, or the core lacks memory.write_u8. Works whether emulation is paused or running. RETURNS: Single line 'Wrote VAL_DEC (0xVAL_HEX) → ADDR_HEX (DOMAIN)'.

ParametersJSON Schema
NameRequiredDescriptionDefault
addressYesByte offset within the chosen memory domain. Per-domain offsets are 0-based and INDEPENDENT of system bus addresses (e.g. SNES WRAM uses 0x09C6, NOT 0x7E09C6). Reads 1 consecutive byte starting here. Returns an error if address < 0 or address + 1 exceeds the domain's size.
valueYesByte value to write. Must be 0-255 (0x00-0xFF). Values outside this range return an error.
domainNoOptional case-sensitive memory domain name. Omit to use BizHawk's currently selected domain (see bizhawk_get_info → current_memory_domain). Discover available names with bizhawk_list_memory_domains; they vary per system (WRAM on SNES, RAM on NES, RDRAM on N64, 68K RAM on Genesis, MainRAM on PSX, EWRAM/IWRAM on GBA). Returns an error if the name doesn't match any domain on the loaded core.

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations provided, so description carries full burden. Clearly states the tool is destructive with no undo, bypasses MBC bank switches and cartridge mapper side-effects, returns error conditions (unknown domain, out of range, invalid value), and works regardless of emulation state.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Description is well-structured with clear sections (PURPOSE, USAGE, BEHAVIOR, RETURNS) and front-loaded. Each sentence adds value, though it could be slightly more compact without losing information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

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 purpose, usage guidelines, behavioral traits, error conditions, and return format. It is sufficiently complete for an 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.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Input schema covers all 3 parameters with full descriptions (100% coverage). Description adds some context (e.g., address is per-domain, independent of system bus addresses) but mostly echoes schema. Baseline 3 is appropriate since schema already does heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description explicitly states it writes a single unsigned byte to emulator memory at a given address, with concrete examples like 'give a player N lives, unlock a flag, set a counter'. It clearly distinguishes from sibling tools like bizhawk_write16, bizhawk_write32, bizhawk_write_range, and bizhawk_load_state.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit when-to-use (single-byte cheats, debug pokes, game-state mutations) and when-not-to-use (prefer bizhawk_write16/write32 for larger values, bizhawk_write_range for spans, bizhawk_load_state for cart save RAM). Names alternative tools directly.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

bizhawk_write_rangeA

PURPOSE: Write a contiguous byte sequence to emulator memory starting at the given address. USAGE: Use whenever you're seeding more than ~4 bytes — one round-trip vs N frame-latency hops compared to looping bizhawk_write8. Maximum 4096 bytes per call (BizHawk serialization limit); for larger writes, batch in 4 KiB chunks. Useful for installing cheat tables, patching code blocks, restoring a captured byte window after experiments, and writing big-endian multi-byte values (byteswap them yourself first). For cart save RAM seeding with proper MBC semantics, use bizhawk_load_state instead. BEHAVIOR: DESTRUCTIVE: overwrites N bytes starting at address with no undo. Direct memory write — bypasses MBC/mapper/DMA, see bizhawk_write8 notes. Bytes are written sequentially address, address+1, ..., address+N-1. Returns an error if the domain is unknown, address+N exceeds the domain, the array contains a value outside 0-255, or the array length is < 1 or > 4096. RETURNS: Single line 'Wrote N bytes → ADDR_HEX (DOMAIN)'.

ParametersJSON Schema
NameRequiredDescriptionDefault
addressYesStarting byte offset within the chosen memory domain. The N bytes [address, address+len) are written.
bytesYesByte values to write, one per element (each 0-255). Length 1-4096 (hard caps from BizHawk's serialization limit). Written sequentially from `address`.
domainNoOptional case-sensitive memory domain name. Omit to use BizHawk's currently selected domain (see bizhawk_get_info → current_memory_domain). Discover available names with bizhawk_list_memory_domains; they vary per system (WRAM on SNES, RAM on NES, RDRAM on N64, 68K RAM on Genesis, MainRAM on PSX, EWRAM/IWRAM on GBA). Returns an error if the name doesn't match any domain on the loaded core.

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Despite no annotations, the description discloses destructive nature ('overwrites N bytes with no undo'), bypassing of MBC/mapper/DMA, sequential writing, and specific error conditions. This fully informs the agent of behavioral traits.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with labeled sections (PURPOSE, USAGE, BEHAVIOR, RETURNS), front-loaded with key information. Every sentence is informative and concise without redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

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 purpose, usage scenarios, behavioral details, error conditions, return format, and constraints. It leaves no critical gaps for an AI agent to correctly invoke the tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Input schema already provides 100% coverage with detailed descriptions for all 3 parameters. The description adds value by explaining the 4096-byte limit, batching strategy, and domain optionality usage, though it doesn't introduce meaning beyond schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states 'Write a contiguous byte sequence to emulator memory starting at the given address', which is a specific verb+resource pairing. It distinguishes itself from siblings by referencing 'looping bizhawk_write8' and the ~4 byte threshold, making its purpose unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly says 'Use whenever you're seeding more than ~4 bytes' and contrasts with 'bizhawk_write8' and 'bizhawk_load_state' for alternative scenarios. Also provides batching guidance for writes exceeding 4096 bytes.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 1 tool updatev0.1.5
    • Changedbizhawk_play_input_sequence5 fields changed
      • addedInput schema / properties / observe_memory
        Added value: +{
        +  "description": "Optional. List of memory reads to perform at each observation point (alongside screenshots if `screenshot_every` is also set). Each result lands in the observation's `memory` field keyed by `name`. Use this to track game-state values per observation — e.g. on Super Metroid, track HP/X/Y/room-ID at each screenshot so you see how state changes across the play batch.",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "address": {
        +        "description": "Byte offset within the chosen memory domain (0-based per-domain).",
        +        "minimum": 0,
        +        "type": "integer"
        +      },
        +      "domain": {
        +        "description": "Optional case-sensitive memory domain. Omit to use BizHawk's currently selected domain. Same semantics as the standalone read tools.",
        +        "type": "string"
        +      },
        +      "name": {
        +        "description": "Label for this reading in the output observation. Choose something semantic (e.g. 'hp', 'samus_x', 'room').",
        +        "type": "string"
        +      },
        +      "width": {
        +        "description": "Read width. 'u16'/'u32' are little-endian (BizHawk's default). For big-endian reads, use width 'u8' multiple times and reassemble client-side (rare).",
        +        "enum": [
        +          "u8",
        +          "u16",
        +          "u32"
        +        ],
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "name",
        +      "address",
        +      "width"
        +    ],
        +    "type": "object"
        +  },
        +  "type": "array"
        +}
      • addedInput schema / properties / screenshot_dir
        Added value: +{
        +  "description": "Optional. Directory to write screenshot PNGs into when `screenshot_every` is set. Default: C:/temp. Must exist and be writable. Files are named `<prefix>-NNNN.png` where NNNN is the frame offset within the batch (zero-padded to 4 digits).",
        +  "type": "string"
        +}
      • addedInput schema / properties / screenshot_every
        Added value: +{
        +  "description": "Optional. If set, capture a PNG screenshot every N frames during playback (and one extra at the final frame regardless of remainder). Each screenshot costs ~1 wall-clock frame for client.screenshot, so 60 (≈1 sec of game time) is a good default — captures meaningful state changes without doubling batch latency. Omit to skip screenshots. If `observe_memory` is also set, screenshots and memory reads happen at the same observation points.",
        +  "minimum": 1,
        +  "type": "integer"
        +}
      • addedInput schema / properties / screenshot_prefix
        Added value: +{
        +  "description": "Optional. Filename prefix for screenshots when `screenshot_every` is set. Default: 'obs'.",
        +  "type": "string"
        +}
      • addedInput schema / properties / stop_on_memory_change
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "Optional. If set, the bridge reads the specified memory value before the first frame, re-reads it after every frame, and ABORTS the play sequence the moment it changes. The result will have `stopped_early: true` and `stop_reason: 'memory_changed'`. A final observation is captured at the stop frame even if it's not on the normal cadence. Killer use case: watch the room ID — Samus walks through a door, room ID changes, play stops at the exact frame of the transition.",
        +  "properties": {
        +    "address": {
        +      "description": "Byte offset within the chosen memory domain to monitor.",
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "domain": {
        +      "description": "Optional case-sensitive memory domain. Same semantics as observe_memory[].domain.",
        +      "type": "string"
        +    },
        +    "width": {
        +      "description": "Read width for the monitored value. Must match the underlying field's actual width (a u8 watch on a u16 field will only trigger on low-byte changes).",
        +      "enum": [
        +        "u8",
        +        "u16",
        +        "u32"
        +      ],
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "address",
        +    "width"
        +  ],
        +  "type": "object"
        +}
  2. 1 tool updatev0.1.3
    • Addedbizhawk_play_input_sequence
  3. 1 tool updatev0.1.2
    • Changedbizhawk_read_range2 fields changed
      • changedInput schema / properties / address / description
        Previous value: -"Starting byte offset within the chosen memory domain. 0-based per-domain offset (NOT a system-bus address). The N bytes [address, address+length) are read."New value: +"Starting byte offset within the chosen memory domain (0-based per-domain, NOT a system-bus address). Reads [address, address+length)."
      • changedInput schema / properties / length / description
        Previous value: -"Number of consecutive bytes to read (1-4096). Hard cap is BizHawk's serialization limit; chunk larger reads yourself."New value: +"Number of bytes to read (1-4096; hard cap is BizHawk's per-call serialization limit)."
  4. 13 tool updatesv0.1.1
    • Changedbizhawk_frame_advance2 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • changedInput schema / properties / count / description
        Previous value: -"Number of frames to advance (≥1, default 1). Returned framecount = previous framecount + count."New value: +"Number of frames to advance (≥1, default 1). Latency scales linearly: ~16ms per frame at 60Hz. New framecount = previous framecount + count."
    • Changedbizhawk_load_state2 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • changedInput schema / properties / path / description
        Previous value: -"Absolute filesystem path to an existing .State file produced by bizhawk_save_state on this same ROM and BizHawk core version."New value: +"Absolute filesystem path to an existing .State file produced by bizhawk_save_state on this same ROM and BizHawk core version. Loading mismatched files typically crashes the core."
    • Changedbizhawk_press_buttons3 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • changedInput schema / properties / buttons / description
        Previous value: -"Map of button name → pressed (boolean). Example: {\"A\": true, \"Up\": true}"New value: +"Map of button name (string, case-sensitive per the active core) → pressed (boolean: true=pressed, false=released). Example: {\"A\": true, \"Up\": true} presses A and Up while leaving everything else released. Names not recognized by the active core are silently ignored."
      • changedInput schema / properties / player / description
        Previous value: -"Player number (1-based). Default 1."New value: +"Player number (1-based). Default 1. For multi-controller cores (e.g. N64 with 4 controllers) pass 2/3/4 to address other players."
    • Changedbizhawk_read_range4 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • changedInput schema / properties / address / description
        Previous value: -"Starting byte offset within the chosen memory domain."New value: +"Starting byte offset within the chosen memory domain. 0-based per-domain offset (NOT a system-bus address). The N bytes [address, address+length) are read."
      • changedInput schema / properties / domain / description
        Previous value: -"Optional memory domain name (case-sensitive). Omit to use BizHawk's currently selected domain."New value: +"Optional case-sensitive memory domain name. Omit to use BizHawk's currently selected domain (see bizhawk_get_info → current_memory_domain). Discover available names with bizhawk_list_memory_domains; they vary per system (WRAM on SNES, RAM on NES, RDRAM on N64, 68K RAM on Genesis, MainRAM on PSX, EWRAM/IWRAM on GBA). Returns an error if the name doesn't match any domain on the loaded core."
      • changedInput schema / properties / length / description
        Previous value: -"Number of consecutive bytes to read (1-4096)."New value: +"Number of consecutive bytes to read (1-4096). Hard cap is BizHawk's serialization limit; chunk larger reads yourself."
    • Changedbizhawk_read163 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • changedInput schema / properties / address / description
        Previous value: -"Byte offset within the chosen memory domain. Reads two consecutive bytes starting here."New value: +"Byte offset within the chosen memory domain. Per-domain offsets are 0-based and INDEPENDENT of system bus addresses (e.g. SNES WRAM uses 0x09C6, NOT 0x7E09C6). Reads 2 consecutive bytes starting here. Returns an error if address < 0 or address + 2 exceeds the domain's size."
      • changedInput schema / properties / domain / description
        Previous value: -"Optional memory domain name (case-sensitive). Omit to use BizHawk's currently selected domain. Discover with bizhawk_list_memory_domains."New value: +"Optional case-sensitive memory domain name. Omit to use BizHawk's currently selected domain (see bizhawk_get_info → current_memory_domain). Discover available names with bizhawk_list_memory_domains; they vary per system (WRAM on SNES, RAM on NES, RDRAM on N64, 68K RAM on Genesis, MainRAM on PSX, EWRAM/IWRAM on GBA). Returns an error if the name doesn't match any domain on the loaded core."
    • Changedbizhawk_read323 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • changedInput schema / properties / address / description
        Previous value: -"Byte offset within the chosen memory domain. Reads four consecutive bytes starting here."New value: +"Byte offset within the chosen memory domain. Per-domain offsets are 0-based and INDEPENDENT of system bus addresses (e.g. SNES WRAM uses 0x09C6, NOT 0x7E09C6). Reads 4 consecutive bytes starting here. Returns an error if address < 0 or address + 4 exceeds the domain's size."
      • changedInput schema / properties / domain / description
        Previous value: -"Optional memory domain name (case-sensitive). Omit to use BizHawk's currently selected domain. Discover with bizhawk_list_memory_domains."New value: +"Optional case-sensitive memory domain name. Omit to use BizHawk's currently selected domain (see bizhawk_get_info → current_memory_domain). Discover available names with bizhawk_list_memory_domains; they vary per system (WRAM on SNES, RAM on NES, RDRAM on N64, 68K RAM on Genesis, MainRAM on PSX, EWRAM/IWRAM on GBA). Returns an error if the name doesn't match any domain on the loaded core."
    • Changedbizhawk_read83 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • changedInput schema / properties / address / description
        Previous value: -"Byte offset within the chosen memory domain. Domain offsets are 0-based and per-domain (NOT system bus addresses) — e.g. SNES WRAM 0x09C6 not 0x7E09C6."New value: +"Byte offset within the chosen memory domain. Per-domain offsets are 0-based and INDEPENDENT of system bus addresses (e.g. SNES WRAM uses 0x09C6, NOT 0x7E09C6). Reads 1 consecutive byte starting here. Returns an error if address < 0 or address + 1 exceeds the domain's size."
      • changedInput schema / properties / domain / description
        Previous value: -"Optional memory domain name (case-sensitive). Omit to use BizHawk's currently selected domain. Discover names with bizhawk_list_memory_domains."New value: +"Optional case-sensitive memory domain name. Omit to use BizHawk's currently selected domain (see bizhawk_get_info → current_memory_domain). Discover available names with bizhawk_list_memory_domains; they vary per system (WRAM on SNES, RAM on NES, RDRAM on N64, 68K RAM on Genesis, MainRAM on PSX, EWRAM/IWRAM on GBA). Returns an error if the name doesn't match any domain on the loaded core."
    • Changedbizhawk_save_state2 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • changedInput schema / properties / path / description
        Previous value: -"Absolute filesystem path to write the .State file to (extension is convention, not required). Parent directory must exist. File is overwritten if present."New value: +"Absolute filesystem path to write the .State file to (extension is convention, not required). Parent directory must exist. File is overwritten without prompt if present."
    • Changedbizhawk_screenshot2 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • changedInput schema / properties / path / description
        Previous value: -"Absolute filesystem path to write the PNG to (e.g. C:/temp/snap.png on Windows, /tmp/snap.png on Linux/macOS). Parent directory must exist. File is overwritten if present."New value: +"Absolute filesystem path to write the PNG to (e.g. C:/temp/snap.png on Windows, /tmp/snap.png on Linux/macOS). Parent directory must exist. File is overwritten without prompt if present."
    • Changedbizhawk_write_range4 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • changedInput schema / properties / address / description
        Previous value: -"Starting byte offset within the chosen memory domain. Bytes are written sequentially from here."New value: +"Starting byte offset within the chosen memory domain. The N bytes [address, address+len) are written."
      • changedInput schema / properties / bytes / description
        Previous value: -"Byte values to write, one per element (each 0-255). Length 1-4096."New value: +"Byte values to write, one per element (each 0-255). Length 1-4096 (hard caps from BizHawk's serialization limit). Written sequentially from `address`."
      • changedInput schema / properties / domain / description
        Previous value: -"Optional memory domain name (case-sensitive). Omit to use BizHawk's currently selected domain."New value: +"Optional case-sensitive memory domain name. Omit to use BizHawk's currently selected domain (see bizhawk_get_info → current_memory_domain). Discover available names with bizhawk_list_memory_domains; they vary per system (WRAM on SNES, RAM on NES, RDRAM on N64, 68K RAM on Genesis, MainRAM on PSX, EWRAM/IWRAM on GBA). Returns an error if the name doesn't match any domain on the loaded core."
    • Changedbizhawk_write164 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • changedInput schema / properties / address / description
        Previous value: -"Byte offset within the chosen memory domain. The low byte lands here, high byte at address+1."New value: +"Byte offset within the chosen memory domain. Per-domain offsets are 0-based and INDEPENDENT of system bus addresses (e.g. SNES WRAM uses 0x09C6, NOT 0x7E09C6). Reads 2 consecutive bytes starting here. Returns an error if address < 0 or address + 2 exceeds the domain's size."
      • changedInput schema / properties / domain / description
        Previous value: -"Optional memory domain name (case-sensitive). Omit to use BizHawk's currently selected domain."New value: +"Optional case-sensitive memory domain name. Omit to use BizHawk's currently selected domain (see bizhawk_get_info → current_memory_domain). Discover available names with bizhawk_list_memory_domains; they vary per system (WRAM on SNES, RAM on NES, RDRAM on N64, 68K RAM on Genesis, MainRAM on PSX, EWRAM/IWRAM on GBA). Returns an error if the name doesn't match any domain on the loaded core."
      • changedInput schema / properties / value / description
        Previous value: -"16-bit value to write (0-65535 / 0x0000-0xFFFF)."New value: +"16-bit value to write. Must be 0-65535 (0x0000-0xFFFF). LSB is written to `address`, MSB to `address+1`. Values outside this range return an error."
    • Changedbizhawk_write324 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • changedInput schema / properties / address / description
        Previous value: -"Byte offset within the chosen memory domain. LSB lands here, MSB at address+3."New value: +"Byte offset within the chosen memory domain. Per-domain offsets are 0-based and INDEPENDENT of system bus addresses (e.g. SNES WRAM uses 0x09C6, NOT 0x7E09C6). Reads 4 consecutive bytes starting here. Returns an error if address < 0 or address + 4 exceeds the domain's size."
      • changedInput schema / properties / domain / description
        Previous value: -"Optional memory domain name (case-sensitive). Omit to use BizHawk's currently selected domain."New value: +"Optional case-sensitive memory domain name. Omit to use BizHawk's currently selected domain (see bizhawk_get_info → current_memory_domain). Discover available names with bizhawk_list_memory_domains; they vary per system (WRAM on SNES, RAM on NES, RDRAM on N64, 68K RAM on Genesis, MainRAM on PSX, EWRAM/IWRAM on GBA). Returns an error if the name doesn't match any domain on the loaded core."
      • changedInput schema / properties / value / description
        Previous value: -"32-bit value to write (0-4294967295 / 0x00000000-0xFFFFFFFF)."New value: +"32-bit value to write. Must be 0-4294967295 (0x00000000-0xFFFFFFFF). LSB lands at `address`, MSB at `address+3`. Values outside this range return an error."
    • Changedbizhawk_write84 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • changedInput schema / properties / address / description
        Previous value: -"Byte offset within the chosen memory domain to write to."New value: +"Byte offset within the chosen memory domain. Per-domain offsets are 0-based and INDEPENDENT of system bus addresses (e.g. SNES WRAM uses 0x09C6, NOT 0x7E09C6). Reads 1 consecutive byte starting here. Returns an error if address < 0 or address + 1 exceeds the domain's size."
      • changedInput schema / properties / domain / description
        Previous value: -"Optional memory domain name (case-sensitive). Omit to use BizHawk's currently selected domain. Discover with bizhawk_list_memory_domains."New value: +"Optional case-sensitive memory domain name. Omit to use BizHawk's currently selected domain (see bizhawk_get_info → current_memory_domain). Discover available names with bizhawk_list_memory_domains; they vary per system (WRAM on SNES, RAM on NES, RDRAM on N64, 68K RAM on Genesis, MainRAM on PSX, EWRAM/IWRAM on GBA). Returns an error if the name doesn't match any domain on the loaded core."
      • changedInput schema / properties / value / description
        Previous value: -"Byte value to write (0-255 / 0x00-0xFF)."New value: +"Byte value to write. Must be 0-255 (0x00-0xFF). Values outside this range return an error."
  5. 12 tool updates
    • Changedbizhawk_frame_advance1 field changed
      • addedInput schema / properties / count / description
        Added value: +"Number of frames to advance (≥1, default 1). Returned framecount = previous framecount + count."
    • Changedbizhawk_load_state1 field changed
      • changedInput schema / properties / path / description
        Previous value: -"Absolute path to a .State file"New value: +"Absolute filesystem path to an existing .State file produced by bizhawk_save_state on this same ROM and BizHawk core version."
    • Changedbizhawk_read_range4 fields changed
      • addedInput schema / properties / address / description
        Added value: +"Starting byte offset within the chosen memory domain."
      • addedInput schema / properties / address / minimum
        Added value: +0
      • addedInput schema / properties / domain / description
        Added value: +"Optional memory domain name (case-sensitive). Omit to use BizHawk's currently selected domain."
      • addedInput schema / properties / length / description
        Added value: +"Number of consecutive bytes to read (1-4096)."
    • Changedbizhawk_read163 fields changed
      • addedInput schema / properties / address / description
        Added value: +"Byte offset within the chosen memory domain. Reads two consecutive bytes starting here."
      • addedInput schema / properties / address / minimum
        Added value: +0
      • addedInput schema / properties / domain / description
        Added value: +"Optional memory domain name (case-sensitive). Omit to use BizHawk's currently selected domain. Discover with bizhawk_list_memory_domains."
    • Changedbizhawk_read323 fields changed
      • addedInput schema / properties / address / description
        Added value: +"Byte offset within the chosen memory domain. Reads four consecutive bytes starting here."
      • addedInput schema / properties / address / minimum
        Added value: +0
      • addedInput schema / properties / domain / description
        Added value: +"Optional memory domain name (case-sensitive). Omit to use BizHawk's currently selected domain. Discover with bizhawk_list_memory_domains."
    • Changedbizhawk_read83 fields changed
      • addedInput schema / properties / address / description
        Added value: +"Byte offset within the chosen memory domain. Domain offsets are 0-based and per-domain (NOT system bus addresses) — e.g. SNES WRAM 0x09C6 not 0x7E09C6."
      • addedInput schema / properties / address / minimum
        Added value: +0
      • changedInput schema / properties / domain / description
        Previous value: -"Optional memory domain name (default: main memory)"New value: +"Optional memory domain name (case-sensitive). Omit to use BizHawk's currently selected domain. Discover names with bizhawk_list_memory_domains."
    • Changedbizhawk_save_state1 field changed
      • changedInput schema / properties / path / description
        Previous value: -"Absolute path to save the .State file"New value: +"Absolute filesystem path to write the .State file to (extension is convention, not required). Parent directory must exist. File is overwritten if present."
    • Changedbizhawk_screenshot1 field changed
      • changedInput schema / properties / path / description
        Previous value: -"Absolute path to save the PNG"New value: +"Absolute filesystem path to write the PNG to (e.g. C:/temp/snap.png on Windows, /tmp/snap.png on Linux/macOS). Parent directory must exist. File is overwritten if present."
    • Changedbizhawk_write_range4 fields changed
      • addedInput schema / properties / address / description
        Added value: +"Starting byte offset within the chosen memory domain. Bytes are written sequentially from here."
      • addedInput schema / properties / address / minimum
        Added value: +0
      • addedInput schema / properties / bytes / description
        Added value: +"Byte values to write, one per element (each 0-255). Length 1-4096."
      • addedInput schema / properties / domain / description
        Added value: +"Optional memory domain name (case-sensitive). Omit to use BizHawk's currently selected domain."
    • Changedbizhawk_write164 fields changed
      • addedInput schema / properties / address / description
        Added value: +"Byte offset within the chosen memory domain. The low byte lands here, high byte at address+1."
      • addedInput schema / properties / address / minimum
        Added value: +0
      • addedInput schema / properties / domain / description
        Added value: +"Optional memory domain name (case-sensitive). Omit to use BizHawk's currently selected domain."
      • addedInput schema / properties / value / description
        Added value: +"16-bit value to write (0-65535 / 0x0000-0xFFFF)."
    • Changedbizhawk_write325 fields changed
      • addedInput schema / properties / address / description
        Added value: +"Byte offset within the chosen memory domain. LSB lands here, MSB at address+3."
      • addedInput schema / properties / address / minimum
        Added value: +0
      • addedInput schema / properties / domain / description
        Added value: +"Optional memory domain name (case-sensitive). Omit to use BizHawk's currently selected domain."
      • addedInput schema / properties / value / description
        Added value: +"32-bit value to write (0-4294967295 / 0x00000000-0xFFFFFFFF)."
      • addedInput schema / properties / value / maximum
        Added value: +4294967295
    • Changedbizhawk_write84 fields changed
      • addedInput schema / properties / address / description
        Added value: +"Byte offset within the chosen memory domain to write to."
      • addedInput schema / properties / address / minimum
        Added value: +0
      • addedInput schema / properties / domain / description
        Added value: +"Optional memory domain name (case-sensitive). Omit to use BizHawk's currently selected domain. Discover with bizhawk_list_memory_domains."
      • addedInput schema / properties / value / description
        Added value: +"Byte value to write (0-255 / 0x00-0xFF)."
  6. 19 tool updatesv0.1.0
    • First observedbizhawk_frame_advance
    • First observedbizhawk_get_info
    • First observedbizhawk_list_memory_domains
    • First observedbizhawk_load_state
    • First observedbizhawk_pause
    • First observedbizhawk_ping
    • First observedbizhawk_press_buttons
    • First observedbizhawk_read_range
    • First observedbizhawk_read16
    • First observedbizhawk_read32
    • First observedbizhawk_read8
    • First observedbizhawk_reset
    • First observedbizhawk_save_state
    • First observedbizhawk_screenshot
    • First observedbizhawk_unpause
    • First observedbizhawk_write_range
    • First observedbizhawk_write16
    • First observedbizhawk_write32
    • First observedbizhawk_write8

TDQS

A4.5/5.0

Scored across 20 tools

Disambiguation5/5

Each tool targets a distinct resource and action: memory reads are separated by width/range, writes similarly, input has one-frame vs sequence tools, and control/state operations are clearly delineated. No two tools overlap in purpose, even the read16/read32/read_range tools are unambiguous due to their explicit size and usage guidance.

Naming Consistency5/5

All tools share the consistent `bizhawk_` prefix and follow a verb_noun pattern (get_info, list_memory_domains, press_buttons, save_state). The few bare-verb names (pause, unpause, reset) are still predictable and stylistically consistent, maintaining a clear convention throughout.

Tool Count3/5

With 20 tools, the set sits in the 16-25 range which the rubric categorizes as borderline heavy. While each tool serves a distinct purpose, the eight memory read/write variants could potentially be consolidated into parameterized tools, making the count slightly bloated even though it's justified by the comprehensive emulator-control scope.

Completeness4/5

Core workflows—memory inspection/modification, input automation, pause/frame/reset control, savestate save/load, and screenshots—are all covered with no dead ends. The only notable gap is the lack of a tool to programmatically query valid button names for the loaded core, which agents must work around via experience or external documentation.

Maintenance

ActivityActive
ResponsivenessResponsive

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    C
    maintenance
    MCP 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.
    14
    19 npm
    2
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    MCP 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.
    17
    23 npm
    3
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    MCP 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.
    18
    24 npm
    2
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    An MCP server that exposes PPSSPP — the PlayStation Portable emulator — to any MCP-compatible client (Claude Desktop, Claude Code, etc.) via PPSSPP's built-in WebSocket debugger interface. Read and write PSP memory, drive games with button input, capture screenshots, set CPU breakpoints, inspect MIPS Allegrex registers — all through a clean tool interface. No bridge plugin needed; PPSSPP's debugg
    23
    20 npm
    8
    MIT