mcp-pine
mcp-pine lets you inspect and manipulate emulated game memory, query game metadata, and control savestates on PlayStation 2 (PCSX2) and PlayStation 3 (RPCS3) emulators via the PINE protocol. It is well-suited for memory inspection, cheat/RAM hunting, savestate automation, and reverse engineering.
Connection & Status
pine_ping— Verify the emulator is reachable and get its version stringpine_get_status— Check if the emulator is running, paused, or shutdownpine_get_info— Retrieve full game metadata: title, serial code, disc CRC, game version, and run state
Memory Reading
pine_read8/16/32/64— Read unsigned 8/16/32/64-bit values from the emulated address spacepine_read_range— Bulk-read up to 4096 consecutive bytes as a hex dump
Memory Writing
pine_write8/16/32/64— Write unsigned 8/16/32/64-bit values to the emulated address space (RAM only; ROM writes are silently dropped)
Savestate Control
pine_save_state— Save the complete emulator state to a numbered slot (0–255)pine_load_state— Restore a previously saved state from a numbered slot (0–255)
Primary use cases: RAM/memory inspection, cheat hunting, game state mutation (e.g., editing HP, score, flags), snapshot/experiment/restore workflows, reverse engineering, and savestate automation.
Provides tools for reading and writing emulated memory (8/16/32/64-bit), triggering save/load states, and querying game metadata on PlayStation 2 emulators via the PINE protocol.
Provides tools for memory read/write and savestate control on PlayStation 3 emulators via the PINE protocol (tested with RPCS3).
mcp-pine
An MCP server for emulators that speak PINE (Protocol for Instrumentation of Network Emulators) — first-class support for PCSX2 (PS2) and RPCS3 (PS3), with target-aware tool descriptions so the agent sees the right memory map for whichever emulator it's pointed at. Exposes memory read/write and savestate control. Driven from MCP-compatible clients (Claude Desktop, Claude Code, etc.).
What you can do with it
Read & write emulated memory — 8/16/32/64-bit, anywhere in the emulator's address space (PS2 EE for PCSX2, PPU main memory for RPCS3)
Trigger save / load state to numbered slots
Query game metadata — title, serial, disc CRC, version
Inspect emulator state — running / paused / shutdown
Tool descriptions, memory-map context, and setup help are rendered per-target at startup — set PINE_TARGET=rpcs3 and every memory-tool description shows PS3 PPU addresses instead of PS2 EE addresses.
What you can't do (because PINE itself doesn't expose these):
Send controller input
Take screenshots
Step / pause / reset the emulator
This makes mcp-pine well-suited for memory inspection, cheat / RAM hunting, savestate automation, and reverse engineering, but not for "play games via Claude." For input + screenshot capability on Game Boy Advance, see the sister project mcp-mgba.
Related MCP server: mcp-mgba
How it works
+----------------+ stdio +----------------+ PINE socket +-----------------+
| MCP client | JSON-RPC | mcp-pine | (TCP or Unix) | Emulator |
| (Claude etc.) | -----------> | (Node.js) | ---------------> | (PINE server) |
+----------------+ +----------------+ +-----------------+mcp-pine opens a loopback connection to the emulator's PINE server (TCP on Windows, Unix domain socket on Linux/macOS) and translates each MCP tool call into a binary PINE message.
Compatible emulators
Emulator | Platform | PINE built in? | Default slot |
|
PCSX2 ≥ 1.7 (setup) | PlayStation 2 | ✅ Yes (toggle in settings) | 28011 |
|
RPCS3 (setup) | PlayStation 3 | ⚠️ Has IPC with PINE-compatible opcodes — verify before relying on it | 28012 |
|
Other emulators implementing the PINE spec should work out of the box once you point mcp-pine at the right slot — open an issue if you've tested one and it works.
Note on DuckStation (PS1): DuckStation had PINE support from May–September 2024 but dropped it in commit 19698559. Current builds have no PINE server. If upstream brings it back, PINE_TARGET=duckstation is reserved.
Setting PINE_TARGET does two things: (1) selects the right Unix socket filename on Linux/macOS, and (2) renders all tool descriptions, memory maps, and setup help for that emulator's address space. Default is pcsx2 for back-compat.
Requirements
An emulator with PINE enabled (see setup below)
Node.js 22+
Install
Option A — install from npm (recommended)
npm install -g mcp-pineVerify with mcp-pine (it prints a startup line and waits for stdio — Ctrl+C to exit).
Option B — npx (no install)
npx -y mcp-pineOption C — clone and develop
git clone https://github.com/dmang-dev/mcp-pine
cd mcp-pine
npm install # also runs the build via the `prepare` hookEmulator setup
PCSX2
Launch PCSX2 (1.7.x Qt or newer).
Settings → Advanced → Enable PINE Server (the option may live under a different submenu in some builds — search the settings for "PINE").
Default slot is 28011. If you change it, set
PINE_SLOTformcp-pine.Load any game.
That's it — no scripts, no console commands. PINE is always-on once the toggle is set.
RPCS3
RPCS3 has its own IPC implementation that mirrors PINE's opcode set, but the wire-level compatibility hasn't been thoroughly tested with this client. To try it:
Configuration → Advanced → Enable IPC server (or similar — check current RPCS3 docs).
Note the configured port.
Run with
PINE_TARGET=rpcs3 PINE_SLOT=<port> mcp-pine.
If something doesn't work, please file an issue with details.
Register with your MCP client
Claude Code (CLI)
claude mcp add pine --scope user mcp-pineVerify:
claude mcp list
# pine: mcp-pine - ✓ ConnectedClaude Desktop
Edit claude_desktop_config.json:
Platform | Path |
macOS |
|
Windows |
|
Linux |
|
{
"mcpServers": {
"pine": {
"command": "mcp-pine"
}
}
}Restart Claude Desktop after editing.
Other MCP clients
mcp-pine speaks standard MCP over stdio. Run it and connect any compatible client.
Configuration
Env var | Default | Purpose |
|
| Emulator name. Known values: |
| target default | PINE slot — also the TCP port on Windows. Defaults: |
|
| Override the host (TCP only) |
| (auto) | Override the full Unix socket path on Linux/macOS, bypassing automatic resolution |
Tools
Tool | Description |
| Verify the connection by querying the emulator version |
| Title, serial (e.g. |
| Just the running/paused/shutdown state |
| Read memory |
| Bulk read up to 4096 bytes (client-side pipelined PINE calls) |
| Write memory (RAM only — ROM writes are silently dropped) |
| Trigger save state to a numbered slot (0-255) |
| Trigger load state from a numbered slot (0-255) |
See docs/RECIPES.md for end-to-end examples (RAM hunting, struct decoding, snapshot-experiment-restore).
PlayStation 2 address space (PCSX2, default target)
Range | Region |
| EE main RAM (32 MiB) — start here for game data |
| Hardware registers (DMA, GIF, VIF) |
| VU0 / VU1 memory |
| GS privileged registers |
| IOP RAM (2 MiB) |
| IOP scratchpad |
| EE scratchpad (16 KiB) |
Troubleshooting
Symptom | Cause / Fix |
| Emulator isn't running, PINE isn't enabled in its settings, or the slot/port doesn't match. Check |
| The emulator rejected the request — most often because no game is loaded, or the address is unmapped. |
Reads return zeros | Address is in an unallocated region. Try |
Tool calls work but values look corrupted | Check endianness expectations — PINE returns little-endian; if you're interpreting strings, use |
| PCSX2's PINE server can wedge. Its request queue is fragile — if a third-party tool pipelines too aggressively (more than ~6 in-flight requests) it silently drops requests, and from then on every reply is mis-aligned with the wrong waiting client. Symptom: even a fresh |
| Expected. PINE has no native bulk read, so we issue calls serially (pipelining can wedge PCSX2 — see above). Loopback TCP is fast enough that this isn't usually a problem: measured ~52 ms for a full 4096-byte read on PCSX2 v2.6.3. For workloads that need lower latency and can tolerate occasional emulator restarts, set |
Development
npm install
npm run dev # tsc --watchQuick smoke test against a running PCSX2:
node .scratch/smoke.cjsDebugging with the MCP Inspector
Browse and call this server's tools interactively with the MCP Inspector:
PINE_TARGET=pcsx2 npm run inspectorBuild first if you've edited src/ since your last npm install (npm run build, or keep npm run dev running). Set PINE_TARGET (pcsx2 default, or rpcs3) and PINE_SLOT to match your emulator — e.g. PINE_TARGET=rpcs3 PINE_SLOT=28012 npm run inspector. tools/list works even without an emulator connected; calling a tool needs PCSX2 (or RPCS3) running with PINE/IPC enabled.
License
Related
mcp-mgba — sister MCP server for the mGBA Game Boy Advance emulator (also includes button input + screenshot, which PINE doesn't expose)
PINE protocol spec — the underlying IPC standard
Available Tools
14 toolspine_get_infoA
PURPOSE: Get the loaded game's metadata — title, serial code, disc CRC, in-game version string — plus the current emulator run state in one call. USAGE: Call after pine_ping to confirm what game is loaded (don't poke memory blindly — the same address means different things across games). For just the run state without the metadata round-trips use pine_get_status (1 PINE call vs 5 here). The serial (e.g. 'SLUS-21274' for PS2, 'SLUS-00067' for PS1) uniquely identifies the disc release region; combine with disc CRC to identify a specific revision. BEHAVIOR: No side effects — pure read of emulator metadata. Issues five PINE opcodes in parallel (Title, ID, UUID, GameVersion, Status). Any individual field that the emulator doesn't expose or that fails is replaced with the literal string '(unavailable)' and the rest still come back. If the entire connection fails the call propagates an error. RETURNS: Multi-line text with Title, Serial, Disc CRC, Game version, and Status — one field per line.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Describes behavior in detail: no side effects, pure read, issues five opcodes in parallel, returns '(unavailable)' for failed fields, propagates error on connection failure. Annotations absent so description carries full burden.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with PURPOSE, USAGE, BEHAVIOR, RETURNS sections. Every sentence adds value, no fluff. Efficient despite length.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Complete for a no-parameter tool without output schema. Explains return format (multi-line text with fields), parallel opcode behavior, error handling, and field failure behavior.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Input schema has zero parameters, baseline is 4. Description adds meaning about returned fields but no parameter details needed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states the tool gets loaded game metadata and run state, with specific fields listed: title, serial code, disc CRC, game version. It distinguishes from siblings like pine_get_status which only gets run state.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly instructs to call after pine_ping, warns against blind memory poking, and directs to pine_get_status for just run state. Provides contextual usage: serial identifies region, CRC identifies revision.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pine_get_statusA
PURPOSE: Get the emulator run state — 'running', 'paused', 'shutdown', or 'unknown'. USAGE: Cheap (1 PINE round-trip) check before timing-sensitive sequences — writes work while paused but only take visible effect after unpause. For game metadata (title, serial, CRC) use pine_get_info (batches Status with Title/ID/UUID/GameVersion). PINE has no pause/resume opcode; this tool only reports state. BEHAVIOR: No side effects. Issues PINE Status opcode (0x0F), decodes the 32-bit response (0=running, 1=paused, 2=shutdown). Errors on connection failure or PINE FAIL. RETURNS: 'Status: STATE' where STATE ∈ {running, paused, shutdown, unknown}.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so the description carries full burden. It states 'No side effects', details the underlying opcode (0x0F) and decoding of the 32-bit response, and mentions error conditions ('Errors on connection failure or PINE FAIL'). 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise with clear section headers (PURPOSE, USAGE, BEHAVIOR, RETURNS). Every sentence earns its place; no fluff. It is well-structured and front-loaded with the most important information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple status-check tool with no parameters and no output schema, the description is complete. It covers purpose, usage guidance, behavioral details, error handling, and return format. No gaps remain for the agent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so the description does not need to add parameter meaning beyond the empty schema. It adds value by explaining the return states and how they map to numeric values, which is useful context. Baseline for 0 params is 4.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: 'Get the emulator run state — 'running', 'paused', 'shutdown', or 'unknown''. It also distinguishes from sibling pine_get_info which batches Status with metadata, so the agent knows exactly what this tool does uniquely.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit usage guidance: 'Cheap (1 PINE round-trip) check before timing-sensitive sequences — writes work while paused but only take visible effect after unpause.' It also specifies when to use an alternative: 'For game metadata (title, serial, CRC) use pine_get_info.' This helps the agent choose correctly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pine_load_stateA
PURPOSE: Trigger the emulator to load a previously-saved state from the given numbered savestate slot, replacing all live state. USAGE: Counterpart to pine_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. There is no PINE 'reset' opcode — to start fresh from boot you must use the emulator's GUI or pre-prepare a slot containing a freshly booted state. BEHAVIOR: DESTRUCTIVE TO LIVE STATE: replaces ALL current emulator state (RAM, registers, GPU, audio, etc.) with the contents of the slot's file. Anything not previously snapshotted is lost permanently. The state file MUST come from the same game disc and same PCSX2 version that produced it; loading an incompatible state typically crashes the core (no recovery without restarting PCSX2). The PINE call returns immediately after PCSX2 schedules the load, NOT after the load is fully visible — there can be a brief window where state is partially loaded. Returns an error if the slot file doesn't exist, the file is corrupt or for the wrong game, or PINE returns FAIL.
RETURNS: Single line 'Load state triggered for slot N'.
| Name | Required | Description | Default |
|---|---|---|---|
| slot | Yes | Save state slot number (0-255). The PINE protocol accepts the full 0-255 range. PCSX2 slot files live in PCSX2's per-game savestate folder (typically %USERPROFILE%/Documents/PCSX2/sstates on Windows, ~/.config/PCSX2/sstates on Linux) with filenames like '<serial> (<crc>).<slot>.p2s'. Slot numbers are independent of any path. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries full burden. It extensively discloses destructive behavior, what gets replaced, crash risks from incompatible states, asynchronous nature, and return value. This is comprehensive and honest.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with labeled sections (PURPOSE, USAGE, BEHAVIOR, RETURNS) and every sentence adds value. It is appropriately sized for the complexity of the tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given a single required parameter, no output schema, and no annotations, the description is fully complete. It covers purpose, usage, behavior, return value, errors, and caveats, leaving no ambiguity for the agent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the description does not add significant new semantic meaning beyond what the schema already provides. The file naming detail is marginal extra context, but not enough to raise the score above baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: 'Trigger the emulator to load a previously-saved state from the given numbered savestate slot, replacing all live state.' It uses a specific verb and resource, and distinguishes from siblings like pine_save_state.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit usage scenarios: 'undo a sequence of writes/inputs..., jump to a bookmarked game state, or start each tool-call sequence from a known baseline.' It also notes when not to use (no reset opcode) and mentions alternatives like GUI.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pine_pingA
PURPOSE: Verify the PINE server (PCSX2) is reachable and responding. USAGE: Call once at session start before other tool calls. Issues PINE Version opcode (0x08) — doubles as liveness probe and emulator-version sniff. BEHAVIOR: No side effects. Bridge connects on demand — Unix socket at $XDG_RUNTIME_DIR/pcsx2.sock. (Linux/macOS, with $TMPDIR/$/tmp fallback) or TCP to 127.0.0.1: (Windows, default slot 28011). 10-second timeout if the emulator isn't running, PINE isn't enabled (For PCSX2: Settings > Advanced > Enable PINE Server (default port 28011).), or slot/port mismatches. RETURNS: 'OK — emulator: VERSION_STRING', e.g. 'OK — emulator: PCSX2 '.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description fully discloses behavior: no side effects, connection details (Unix socket or TCP with fallback), timeout (10 seconds), and return format. This meets the burden of transparency completely.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with clear sections (PURPOSE, USAGE, BEHAVIOR, RETURNS). Every sentence serves a purpose without redundancy, making it concise yet informative.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no parameters and no output schema, the description covers all necessary aspects: purpose, usage timing, behavioral details, and return value. It is fully self-contained and complete for an agent to use.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There are no parameters (input schema is empty with 100% coverage). The description adds no parameter info, but for a parameterless tool, it provides sufficient context about what the tool does, exceeding expectations.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Verify the PINE server (PCSX2) is reachable and responding,' providing a specific verb and resource. It distinguishes itself from sibling tools like pine_read16 or pine_write16, which are for data access, by being the liveness probe.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly advises 'Call once at session start before other tool calls,' giving clear usage context. It also notes that it doubles as an emulator-version sniffer. While it doesn't specify when not to use it, the tool is narrow in scope, so this is adequate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pine_read16A
PURPOSE: Read an unsigned 16-bit little-endian value from the emulator's EE main address space at the given absolute address. USAGE: Use for 16-bit fields (HP, score, coordinates on many PlayStation 2 titles). For single bytes use pine_read8; for 32/64-bit use pine_read32/read64; for unaligned reads or big-endian fields, use pine_read_range and decode the bytes yourself (this tool always interprets bytes as little-endian, which matches MIPS byte order on PS1/PS2). 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. Address MUST be 2-byte aligned. PINE on PCSX2 does NOT enforce alignment — unaligned access typically returns whatever bytes are at the aligned address below, silently corrupting the value. If you need an unaligned multi-byte read, use pine_read_range and assemble the bytes yourself. Returns a PINE FAIL response on unmapped addresses; times out after ~10s if the reply is dropped.
PlayStation 2 main address space landmarks (PCSX2): 0x00100000-0x01FFFFFF EE main RAM (32 MiB) — game code & data; the most common target 0x10000000 Hardware registers (DMA, GIF, VIF, etc.) 0x11000000 VU0 / VU1 memory 0x12000000 GS privileged registers 0x1C000000-0x1C1FFFFF IOP RAM (2 MiB) 0x1F800000 IOP scratchpad 0x70000000 EE scratchpad (16 KiB) PINE memory operations target the EE address space.
RETURNS: Single line 'ADDR_HEX: VAL_DEC (0xVAL_HEX)'.
| Name | Required | Description | Default |
|---|---|---|---|
| address | Yes | Absolute byte address in the EE main address space (NOT a per-domain offset). Pass as a number; hex literals like 0x00200000 are fine. Reads 2 consecutive bytes starting here. MUST be 2-byte aligned (address % 2 === 0). PINE on PCSX2 does NOT enforce alignment — unaligned access typically returns whatever bytes are at the aligned address below, silently corrupting the value. If you need an unaligned multi-byte read, use pine_read_range and assemble the bytes yourself. Useful range: 0x00100000-0x01FFFFFF for EE main RAM (where 99% of game state lives). An unmapped or invalid address returns a PINE FAIL response. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Without annotations, the description fully covers behavior: 'No side effects — pure read,' explains byte order and alignment constraints, warns about silent corruption on unaligned access, describes the PINE FAIL response for unmapped addresses, and mentions a ~10s timeout. It 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with clear sections (PURPOSE, USAGE, BEHAVIOR, memory map, RETURNS). It is front-loaded with essential information, and every sentence adds value. Despite length, it earns its place given the complexity of emulator memory access.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple 16-bit read tool, the description covers alignment, byte order, error handling, and provides a memory map reference. It references sibling tools for alternative scenarios. The return format is described, and no output schema is needed. It is fully complete for the tool's purpose.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with a description for 'address', but the description adds significant value: it explains why alignment is required, the consequence of misalignment, the useful address range, and the return format. While the schema provides basics, this enrichment justifies a score above baseline (3).
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description begins with 'PURPOSE: Read an unsigned 16-bit little-endian value from the emulator's EE main address space at the given absolute address,' clearly specifying verb, resource, and scope. It also distinguishes from sibling tools like pine_read8, pine_read32, and pine_read_range.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when to use this tool ('Use for 16-bit fields...') and when not, providing alternatives such as pine_read8 for single bytes, pine_read32/64 for larger sizes, and pine_read_range for unaligned or big-endian fields. This gives clear decision guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pine_read32A
PURPOSE: Read an unsigned 32-bit little-endian value from the emulator's EE main address space at the given absolute address. USAGE: Use for 32-bit fields — timestamps, large counters, RGBA colors, and the lower half of 64-bit pointers. For single byte / 16-bit / 64-bit values use pine_read8/read16/read64; for big-endian or unaligned multi-word reads use pine_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). Address MUST be 4-byte aligned. PINE on PCSX2 does NOT enforce alignment — unaligned access typically returns whatever bytes are at the aligned address below, silently corrupting the value. If you need an unaligned multi-byte read, use pine_read_range and assemble the bytes yourself. Returns a PINE FAIL response on unmapped addresses; times out after ~10s if the reply is dropped.
PlayStation 2 main address space landmarks (PCSX2): 0x00100000-0x01FFFFFF EE main RAM (32 MiB) — game code & data; the most common target 0x10000000 Hardware registers (DMA, GIF, VIF, etc.) 0x11000000 VU0 / VU1 memory 0x12000000 GS privileged registers 0x1C000000-0x1C1FFFFF IOP RAM (2 MiB) 0x1F800000 IOP scratchpad 0x70000000 EE scratchpad (16 KiB) PINE memory operations target the EE address space.
RETURNS: Single line 'ADDR_HEX: VAL_DEC (0xVAL_HEX)'.
| Name | Required | Description | Default |
|---|---|---|---|
| address | Yes | Absolute byte address in the EE main address space (NOT a per-domain offset). Pass as a number; hex literals like 0x00200000 are fine. Reads 4 consecutive bytes starting here. MUST be 4-byte aligned (address % 4 === 0). PINE on PCSX2 does NOT enforce alignment — unaligned access typically returns whatever bytes are at the aligned address below, silently corrupting the value. If you need an unaligned multi-byte read, use pine_read_range and assemble the bytes yourself. Useful range: 0x00100000-0x01FFFFFF for EE main RAM (where 99% of game state lives). An unmapped or invalid address returns a PINE FAIL response. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations, so description carries full burden. Discloses no side effects, alignment requirement, unaligned behavior, return format, timeout, and error response. 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose and usage, but includes a large address landmarks block that may be too detailed for a single tool. Still well-organized and earns its length.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema, yet description explains return format. Covers behavior, error handling, and usage context. Complete for a read tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, but description adds significant meaning: alignment requirement, address range hint, return format. Goes well beyond schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clear verb ('Read'), specific data type (unsigned 32-bit little-endian), and resource (EE main address space). Distinguishes from siblings by size and endianness.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use (32-bit fields) and when not to (different sizes, big-endian, unaligned). Provides alternative tool names (read8/16/64, read_range).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pine_read64A
PURPOSE: Read an unsigned 64-bit little-endian value from the emulator's EE main address space at the given absolute address. USAGE: Use for true 64-bit fields — full pointers, large IDs, packed double-word state. The PS2 EE is a 128-bit MIPS where 64-bit slots are common; PS1 and PS3 use 64-bit less heavily but the opcode still works. Reach for this rather than chaining two pine_read32 calls when you want atomicity. For 8/16/32-bit values use the corresponding sibling; for byte spans use pine_read_range. BEHAVIOR: No side effects — pure read. Reads eight consecutive bytes starting at address and combines them as little-endian. Address MUST be 8-byte aligned. PINE on PCSX2 does NOT enforce alignment — unaligned access typically returns whatever bytes are at the aligned address below, silently corrupting the value. If you need an unaligned multi-byte read, use pine_read_range and assemble the bytes yourself. The result is returned as a decimal STRING (not a JSON number) to preserve precision past 2^53 (JavaScript number limit) — parse with BigInt if you need to do arithmetic. Returns a PINE FAIL response on unmapped addresses; times out after ~10s if the reply is dropped.
PlayStation 2 main address space landmarks (PCSX2): 0x00100000-0x01FFFFFF EE main RAM (32 MiB) — game code & data; the most common target 0x10000000 Hardware registers (DMA, GIF, VIF, etc.) 0x11000000 VU0 / VU1 memory 0x12000000 GS privileged registers 0x1C000000-0x1C1FFFFF IOP RAM (2 MiB) 0x1F800000 IOP scratchpad 0x70000000 EE scratchpad (16 KiB) PINE memory operations target the EE address space.
RETURNS: Single line 'ADDR_HEX: VAL_DEC (0xVAL_HEX)' — VAL_DEC is a decimal string that may exceed 2^53.
| Name | Required | Description | Default |
|---|---|---|---|
| address | Yes | Absolute byte address in the EE main address space (NOT a per-domain offset). Pass as a number; hex literals like 0x00200000 are fine. Reads 8 consecutive bytes starting here. MUST be 8-byte aligned (address % 8 === 0). PINE on PCSX2 does NOT enforce alignment — unaligned access typically returns whatever bytes are at the aligned address below, silently corrupting the value. If you need an unaligned multi-byte read, use pine_read_range and assemble the bytes yourself. Useful range: 0x00100000-0x01FFFFFF for EE main RAM (where 99% of game state lives). An unmapped or invalid address returns a PINE FAIL response. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description fully covers behavioral traits: no side effects (pure read), alignment requirement (8-byte), unaligned corruption behavior, timeout (~10s), error on unmapped addresses, and return format (decimal string with hex).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with clear sections (PURPOSE, USAGE, BEHAVIOR, memory map, RETURNS). It is slightly verbose but every sentence adds value, covering alignment, siblings, and return format. Could be trimmed marginally but is effective.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, the description thoroughly explains the return format (single line with hex address, decimal value, hex value) and precision note (decimal string to avoid JavaScript number limits). It also includes a memory map for context. The tool has only one parameter and is well-covered.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the description adds significant context beyond the schema: it explains alignment requirement (must be 8-byte aligned and what happens if not), provides useful address range landmarks, and clarifies that unmapped addresses return a PINE FAIL response. The schema already describes the parameter, so 4 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description explicitly states the tool reads an unsigned 64-bit little-endian value from the EE main address space, with a clear verb ('Read') and resource ('unsigned 64-bit little-endian value'). It distinguishes from siblings like pine_read8/16/32 and pine_read_range by specifying bit-width and atomicity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit guidance: use for true 64-bit fields (full pointers, large IDs) and when atomicity is needed (rather than chaining two pine_read32). It also advises against unaligned reads, directing to pine_read_range instead. Alternatives (siblings) are named for 8/16/32-bit reads.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pine_read8A
PURPOSE: Read an unsigned 8-bit byte from the emulator's EE main address space at the given absolute address. USAGE: Use for single-byte fields — status flags, counters, 8-bit enums, character bytes. For 16/32/64-bit values use pine_read16/read32/read64 (one call instead of multi-byte assembly); for spans of more than ~4 bytes use pine_read_range (one batched call instead of N round-trips). BEHAVIOR: No side effects — pure read. Reads work whether the emulator is running or paused. No alignment requirement (byte access is naturally aligned). Returns an error if the address is unmapped, the connection drops, or PINE returns its FAIL response (0xFF). The 10-second per-call timeout fires if the emulator drops the reply (PCSX2 has been observed to do this under heavy pipeline load — see pine_read_range for the wider context).
PlayStation 2 main address space landmarks (PCSX2): 0x00100000-0x01FFFFFF EE main RAM (32 MiB) — game code & data; the most common target 0x10000000 Hardware registers (DMA, GIF, VIF, etc.) 0x11000000 VU0 / VU1 memory 0x12000000 GS privileged registers 0x1C000000-0x1C1FFFFF IOP RAM (2 MiB) 0x1F800000 IOP scratchpad 0x70000000 EE scratchpad (16 KiB) PINE memory operations target the EE address space.
RETURNS: Single line 'ADDR_HEX: VAL_DEC (0xVAL_HEX)', e.g. '0x00200000: 99 (0x63)'.
| Name | Required | Description | Default |
|---|---|---|---|
| address | Yes | Absolute byte address in the EE main address space (NOT a per-domain offset). Pass as a number; hex literals like 0x00200000 are fine. Reads 1 consecutive byte starting here. No alignment requirement for byte access. Useful range: 0x00100000-0x01FFFFFF for EE main RAM (where 99% of game state lives). An unmapped or invalid address returns a PINE FAIL response. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description fully discloses behavior: 'No side effects — pure read', 'Reads work whether the emulator is running or paused', 'No alignment requirement', and error conditions (unmapped address, connection drop, FAIL response, timeout). This exceeds the minimal expectation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with labeled sections (PURPOSE, USAGE, BEHAVIOR, RETURNS) and a reference list of address landmarks. It is front-loaded with critical information. While the address list is verbose, it is contextually useful and does not detract from conciseness overall.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite the lack of output schema and annotations, the description covers all necessary aspects: purpose, usage, behavior, parameter details, return format, error handling, and timeout. It provides a complete mental model for the agent to use the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with a good parameter description. The tool description adds value beyond the schema by indicating the typical useful range (0x00100000-0x01FFFFFF for EE RAM) and clarifying that hex literals are accepted and that invalid addresses return FAIL. This enriches the parameter semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description explicitly states the purpose: 'Read an unsigned 8-bit byte from the emulator's EE main address space at the given absolute address.' It clearly indicates the resource (EE main address space) and action (read byte). It also distinguishes from siblings by specifying 8-bit vs 16/32/64 and range tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The 'USAGE' section provides explicit guidance on when to use this tool (single-byte fields) and when to use alternatives (pine_read16/32/64 for larger types, pine_read_range for spans >4 bytes). This directly addresses tool selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pine_read_rangeA
PURPOSE: Read a contiguous range of bytes from EE main address space memory as a hex dump. USAGE: For >4 bytes — far cheaper than looping pine_read8. Max 4096 bytes/call; chunk larger reads in 4 KiB. Powers snapshot-diff RAM hunts (snapshot before/after a known change, diff for matching deltas), unknown-struct inspection, and region capture/restore. BEHAVIOR: No side effects. PINE has no native bulk-read opcode; the tool synthesizes the range from read64/32/16/8 calls (largest aligned load at each step) and assembles client-side. Issued FULLY SERIALLY by default because PCSX2's PINE queue silently drops replies past ~7 in-flight requests, desyncing the bridge until emulator restart. Loopback serial is fast enough (~52 ms for 4096 bytes on PCSX2 v2.6.3); other targets are typically similar or faster. Override via PINE_PIPELINE_BATCH env var at your own risk. Errors on length out of 1-4096, any underlying FAIL, or reply timeout.
PlayStation 2 main address space landmarks (PCSX2): 0x00100000-0x01FFFFFF EE main RAM (32 MiB) — game code & data; the most common target 0x10000000 Hardware registers (DMA, GIF, VIF, etc.) 0x11000000 VU0 / VU1 memory 0x12000000 GS privileged registers 0x1C000000-0x1C1FFFFF IOP RAM (2 MiB) 0x1F800000 IOP scratchpad 0x70000000 EE scratchpad (16 KiB) PINE memory operations target the EE address space.
RETURNS: 'ADDR_HEX [N bytes]:' header + space-separated 2-digit uppercase hex bytes.
| Name | Required | Description | Default |
|---|---|---|---|
| address | Yes | Starting absolute byte address in the EE main address space. Bytes [address, address+length) are read. No alignment requirement — the tool picks the largest aligned load it can at each step (e.g. an unaligned start, an aligned middle, and an unaligned tail are handled in three different load widths). | |
| length | Yes | Number of consecutive bytes to read (1-4096). Hard cap is the tool's max; chunk larger reads yourself. Latency is roughly proportional to length / 8 in serial mode (the default) — a 4096-byte read is ~512 PINE round-trips on a typical 8-byte-aligned region, around 50 ms over loopback. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses no side effects, explains internal synthesis from individual read calls, describes default serial execution due to PCSX2 queue limits, and lists error conditions. Since no annotations are provided, the description carries full burden and does so thoroughly.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Description is well-structured with clear sections (PURPOSE, USAGE, BEHAVIOR, memory map, RETURNS). While verbose, each section adds necessary context and no content is redundant. Could be slightly more concise but retains readability.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (synthesized reads, serial behavior, PS2 memory), the description is exceptionally complete. It includes memory map landmarks, return format, error conditions, and best practices. Without an output schema, it fully describes the output.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Input schema covers both parameters with descriptions; the tool description adds significant value: for 'address' explains alignment strategy, for 'length' gives latency proportionality and chunking advice. Both parameters are well documented beyond schema basics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool reads a contiguous byte range from EE memory as a hex dump, distinguishing it from sibling tools (pine_read8/16/32/64) by emphasizing bulk reads cheaper for >4 bytes.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit usage guidance: 'For >4 bytes — far cheaper than looping pine_read8,' and advises chunking reads larger than 4096 bytes. Includes context for snapshot-diff RAM hunts and mentions overriding pipeline batching at own risk. Implicitly suggests limiting to reads ≤4 bytes suggests alternatives, but does not explicitly list sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pine_save_stateA
PURPOSE: Trigger the emulator to save complete state (RAM, registers, GPU, audio, timing) to a numbered slot. USAGE: Rollback point before risky writes, bookmarks, repro sharing. Companion pine_load_state restores from the same slot. PINE savestates are SLOT-BASED (0-255), not file-path-based — PCSX2 picks the disk location. BEHAVIOR: DESTRUCTIVE TO TARGET SLOT: silently overwrites prior contents — no prompt, no backup, no recovery. Bound to the exact game disc and PCSX2 version; loading mismatched usually crashes the core. The call returns when PCSX2 schedules the save, NOT when the file is on disk — brief half-written window possible. Errors on no game loaded, unwritable folder, or PINE FAIL.
RETURNS: 'Save state triggered for slot N'.
| Name | Required | Description | Default |
|---|---|---|---|
| slot | Yes | Save state slot number (0-255). The PINE protocol accepts the full 0-255 range. PCSX2 slot files live in PCSX2's per-game savestate folder (typically %USERPROFILE%/Documents/PCSX2/sstates on Windows, ~/.config/PCSX2/sstates on Linux) with filenames like '<serial> (<crc>).<slot>.p2s'. Slot numbers are independent of any path. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full burden. It discloses destructive behavior (silently overwrites target slot), environment constraints (bound to game disc and PCSX2 version), timing behavior (returns when save scheduled, not when on disk), and error conditions. This is comprehensive but could mention performance implications.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description uses clear headings (PURPOSE, USAGE, BEHAVIOR, RETURNS) and is well-structured. However, it is somewhat verbose for a simple tool, with some redundancy and unnecessary detail about paths that could be streamlined.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, the description includes return value format and error conditions. It covers the half-written window and dependencies. For a state-saving tool, it is sufficiently complete, though it lacks details about async execution or cancellation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema covers 100% of the parameter (slot) with a detailed description including range, protocol, and path info. The description adds minimal additional semantic value beyond restating the slot-based nature. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Trigger the emulator to save complete state (RAM, registers, GPU, audio, timing) to a numbered slot.' It specifies the verb, resource, and distinguishes the tool from siblings like pine_load_state. The slot-based nature is explicitly highlighted.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit usage guidance: 'Rollback point before risky writes, bookmarks, repro sharing' and mentions the companion tool pine_load_state. It gives clear context but does not fully list when not to use it beyond implying alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pine_write16A
PURPOSE: Write an unsigned 16-bit little-endian value to EE main address space. USAGE: For 16-bit cheats/pokes (HP, score, coordinates). For single bytes use pine_write8; for 32/64-bit use pine_write32/write64; for big-endian fields byteswap first (this tool always writes little-endian). Snapshot via pine_save_state for rollback. BEHAVIOR: DESTRUCTIVE: overwrites two bytes (low at address, high at address+1) with no undo. Direct write — bypasses TLB; writes to read-only regions (BIOS) are silently dropped. Address MUST be 2-byte aligned. PINE on PCSX2 does NOT enforce alignment — unaligned access typically returns whatever bytes are at the aligned address below, silently corrupting the value. If you need an unaligned multi-byte read, use pine_read_range and assemble the bytes yourself. Errors on connection drop or PINE FAIL.
PlayStation 2 main address space landmarks (PCSX2): 0x00100000-0x01FFFFFF EE main RAM (32 MiB) — game code & data; the most common target 0x10000000 Hardware registers (DMA, GIF, VIF, etc.) 0x11000000 VU0 / VU1 memory 0x12000000 GS privileged registers 0x1C000000-0x1C1FFFFF IOP RAM (2 MiB) 0x1F800000 IOP scratchpad 0x70000000 EE scratchpad (16 KiB) PINE memory operations target the EE address space.
RETURNS: 'Wrote VAL_DEC (0xVAL_HEX) → ADDR_HEX'.
| Name | Required | Description | Default |
|---|---|---|---|
| address | Yes | Absolute byte address in the EE main address space (NOT a per-domain offset). Pass as a number; hex literals like 0x00200000 are fine. Reads 2 consecutive bytes starting here. MUST be 2-byte aligned (address % 2 === 0). PINE on PCSX2 does NOT enforce alignment — unaligned access typically returns whatever bytes are at the aligned address below, silently corrupting the value. If you need an unaligned multi-byte read, use pine_read_range and assemble the bytes yourself. Useful range: 0x00100000-0x01FFFFFF for EE main RAM (where 99% of game state lives). An unmapped or invalid address returns a PINE FAIL response. | |
| value | Yes | 16-bit value to write. Must be 0-65535 (0x0000-0xFFFF). LSB lands at `address`, MSB at `address+1`. For signed 16-bit values, encode as two's complement (e.g. -1 → 0xFFFF). Values outside the range are rejected by the schema. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, so description fully bears the burden. It explicitly states DESTRUCTIVE behavior (no undo), direct write bypassing TLB, silent drops on read-only regions, 2-byte alignment requirement, and unaligned access corruption risks. Also covers error conditions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with labeled sections (PURPOSE, USAGE, BEHAVIOR, landmarks, RETURNS). However, alignment warnings appear both in main description and param descriptions, adding minor redundancy. Still fairly concise for the complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers all necessary context for a memory-write tool on PS2: address landmarks, alignment, endianness, destructive nature, and return format. No output schema but return line is sufficient.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, but description adds value: explains LSB/MSB placement, signed encoding via two's complement, and reinforces alignment. Slight redundancy with schema but overall adds context.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description explicitly states the tool writes an unsigned 16-bit little-endian value to the EE main address space. It distinguishes from siblings by referencing pine_write8, pine_write32, and pine_write64, and addresses big-endian handling.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides clear when-to-use (16-bit pokes) and when-not-to (single bytes, larger, big-endian) with named alternatives. Also recommends snapshotting via pine_save_state for rollback.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pine_write32A
PURPOSE: Write an unsigned 32-bit little-endian value to the emulator's EE main address space at the given absolute address. USAGE: Use for 32-bit cheats and pokes — timestamps, large counters, RGBA colors, the lower half of pointers. For single byte / 16-bit values use pine_write8/write16; for true 64-bit fields use pine_write64 — chaining two pine_write32 calls is non-atomic and can be observed mid-update by the running game. For big-endian layouts, byteswap into a little-endian value yourself first. BEHAVIOR: DESTRUCTIVE: overwrites four bytes starting at address with no undo. Direct memory write — bypasses TLB protection and DMA mediation; writes to read-only regions (BIOS) are silently dropped with no error. Address MUST be 4-byte aligned. PINE on PCSX2 does NOT enforce alignment — unaligned access typically returns whatever bytes are at the aligned address below, silently corrupting the value. If you need an unaligned multi-byte read, use pine_read_range and assemble the bytes yourself. Values are NOT truncated by this tool: the schema rejects anything outside 0-4294967295 (0x00000000-0xFFFFFFFF) before the call ever reaches PINE. Returns an error if the connection drops or PINE returns FAIL on a wholly invalid address.
PlayStation 2 main address space landmarks (PCSX2): 0x00100000-0x01FFFFFF EE main RAM (32 MiB) — game code & data; the most common target 0x10000000 Hardware registers (DMA, GIF, VIF, etc.) 0x11000000 VU0 / VU1 memory 0x12000000 GS privileged registers 0x1C000000-0x1C1FFFFF IOP RAM (2 MiB) 0x1F800000 IOP scratchpad 0x70000000 EE scratchpad (16 KiB) PINE memory operations target the EE address space.
RETURNS: Single line 'Wrote VAL_DEC (0xVAL_HEX) → ADDR_HEX'.
| Name | Required | Description | Default |
|---|---|---|---|
| address | Yes | Absolute byte address in the EE main address space (NOT a per-domain offset). Pass as a number; hex literals like 0x00200000 are fine. Reads 4 consecutive bytes starting here. MUST be 4-byte aligned (address % 4 === 0). PINE on PCSX2 does NOT enforce alignment — unaligned access typically returns whatever bytes are at the aligned address below, silently corrupting the value. If you need an unaligned multi-byte read, use pine_read_range and assemble the bytes yourself. Useful range: 0x00100000-0x01FFFFFF for EE main RAM (where 99% of game state lives). An unmapped or invalid address returns a PINE FAIL response. | |
| value | Yes | 32-bit value to write. Must be 0-4294967295 (0x00000000-0xFFFFFFFF). LSB lands at `address`, MSB at `address+3`. For signed 32-bit values, encode as two's complement (e.g. -1 → 0xFFFFFFFF). For floats, reinterpret the IEEE-754 bits as an integer first. Values outside the range are rejected by the schema, NOT silently truncated — pass the value you actually want stored. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided; the description discloses destructiveness, lack of undo, bypass of TLB/DMA, silent drops on BIOS, alignment requirements, unaligned corruption risk, and error conditions fully.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with sections, but somewhat lengthy due to address space landmarks. However, all content is relevant and front-loaded, justifying the length.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers purpose, usage, behavior, address space, parameters, and returns fully. No output schema, but return format is described, making it complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, but the description adds endianness details, signed/float encoding, alignment warnings, and return format, providing significant value beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool writes an unsigned 32-bit little-endian value to the EE main address space, and mentions it for cheats/pokes. It distinguishes from siblings by naming pine_write8/write16/write64 for other sizes.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit when-to-use (timestamps, large counters) and when-not (use other size tools, avoid chaining for 64-bit). Also advises on big-endian handling. Very clear guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pine_write64A
PURPOSE: Write an unsigned 64-bit little-endian value to EE main address space. USAGE: For true 64-bit writes — full pointers, large IDs, packed doubleword state. Atomic from the emulator's perspective; preferred over chaining two pine_write32 calls (a running game can observe the in-between state). For 8/16/32-bit values use the corresponding sibling. BEHAVIOR: DESTRUCTIVE: overwrites eight bytes from address with no undo. Direct write — bypasses TLB; writes to read-only regions silently dropped. Address MUST be 8-byte aligned. PINE on PCSX2 does NOT enforce alignment — unaligned access typically returns whatever bytes are at the aligned address below, silently corrupting the value. If you need an unaligned multi-byte read, use pine_read_range and assemble the bytes yourself. value is a DECIMAL STRING (0 through 18446744073709551615) to preserve precision past JS's 2^53 number limit. Errors on connection drop or PINE FAIL.
PlayStation 2 main address space landmarks (PCSX2): 0x00100000-0x01FFFFFF EE main RAM (32 MiB) — game code & data; the most common target 0x10000000 Hardware registers (DMA, GIF, VIF, etc.) 0x11000000 VU0 / VU1 memory 0x12000000 GS privileged registers 0x1C000000-0x1C1FFFFF IOP RAM (2 MiB) 0x1F800000 IOP scratchpad 0x70000000 EE scratchpad (16 KiB) PINE memory operations target the EE address space.
RETURNS: 'Wrote VAL_DEC (0xVAL_HEX) → ADDR_HEX' — VAL_DEC may exceed 2^53.
| Name | Required | Description | Default |
|---|---|---|---|
| address | Yes | Absolute byte address in the EE main address space (NOT a per-domain offset). Pass as a number; hex literals like 0x00200000 are fine. Reads 8 consecutive bytes starting here. MUST be 8-byte aligned (address % 8 === 0). PINE on PCSX2 does NOT enforce alignment — unaligned access typically returns whatever bytes are at the aligned address below, silently corrupting the value. If you need an unaligned multi-byte read, use pine_read_range and assemble the bytes yourself. Useful range: 0x00100000-0x01FFFFFF for EE main RAM (where 99% of game state lives). An unmapped or invalid address returns a PINE FAIL response. | |
| value | Yes | 64-bit value to write, as a non-negative DECIMAL STRING (digits only, no '0x' prefix, no sign, no separators). Range 0 through 18446744073709551615 (2^64 - 1). Example: "18446744073709551615" writes 0xFFFFFFFFFFFFFFFF. Encoded as a string so values past 2^53 are preserved exactly (JSON numbers lose precision at that point). For signed 64-bit values, encode as two's complement (e.g. -1 → "18446744073709551615"). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description fully discloses behaviors: 'DESTRUCTIVE: overwrites eight bytes from address with no undo', 'Direct write — bypasses TLB; writes to read-only regions silently dropped', alignment constraints and silent corruption on unaligned access, atomicity from emulator perspective, and error conditions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with clear sections (PURPOSE, USAGE, BEHAVIOR, returns) and a helpful memory map. Every sentence adds necessary context; no filler. It is front-loaded with purpose and atomicity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite no output schema, the description specifies the return format. It provides extensive context: alignment enforcement details, address space landmarks, atomicity, error handling, and prerequisites. It is self-contained and leaves no ambiguity for a competent agent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, but the description adds significant value: explains address landmarks (EE main RAM regions), alignment requirements beyond schema, the reason for decimal string (precision beyond 2^53), and two's complement encoding for signed values.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Write an unsigned 64-bit little-endian value to EE main address space' and distinguishes from siblings by explicitly mentioning 'For true 64-bit writes' and contrasting with chaining two write32 calls. It also references smaller siblings for other bit widths.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly advises when to use this tool ('For true 64-bit writes — full pointers, large IDs, packed doubleword state') and when not ('For 8/16/32-bit values use the corresponding sibling'). Also warns about alignment and recommends pine_read_range for unaligned multi-byte reads.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pine_write8A
PURPOSE: Write a single unsigned byte (0-255) to the emulator's EE main address space at the given absolute 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/64-bit values prefer pine_write16/write32/write64 (single call instead of byte-at-a-time, and atomic from the emulator's perspective). For seeding many bytes there is no native bulk write — loop pine_write8 yourself or batch via pine_write64 on aligned regions. To roll back later use pine_save_state BEFORE the write and pine_load_state to restore. BEHAVIOR: DESTRUCTIVE: overwrites whatever was at address with no undo. The write is direct memory access — bypasses TLB protection and any DMA semantics — so writes to read-only regions (BIOS, etc.) are silently dropped by the emulator with no error. The write takes effect immediately, but visible game-state effects only appear when the emulator next ticks (so writing while paused shows changes only after unpause or frame-step). No alignment requirement for byte access. Returns an error if the connection drops or PINE returns FAIL on a wholly invalid address.
PlayStation 2 main address space landmarks (PCSX2): 0x00100000-0x01FFFFFF EE main RAM (32 MiB) — game code & data; the most common target 0x10000000 Hardware registers (DMA, GIF, VIF, etc.) 0x11000000 VU0 / VU1 memory 0x12000000 GS privileged registers 0x1C000000-0x1C1FFFFF IOP RAM (2 MiB) 0x1F800000 IOP scratchpad 0x70000000 EE scratchpad (16 KiB) PINE memory operations target the EE address space.
RETURNS: Single line 'Wrote VAL_DEC (0xVAL_HEX) → ADDR_HEX'.
| Name | Required | Description | Default |
|---|---|---|---|
| address | Yes | Absolute byte address in the EE main address space (NOT a per-domain offset). Pass as a number; hex literals like 0x00200000 are fine. Reads 1 consecutive byte starting here. No alignment requirement for byte access. Useful range: 0x00100000-0x01FFFFFF for EE main RAM (where 99% of game state lives). An unmapped or invalid address returns a PINE FAIL response. | |
| value | Yes | Byte value to write. Must be 0-255 (0x00-0xFF). Values outside this range are rejected by the schema. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Even without annotations, the description thoroughly discloses behavioral traits: destructive overwrite, silent drop on read-only regions, immediate effect but only visible after emulator tick, no alignment requirement, and error conditions. This fully informs the agent of side effects and constraints.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with clear section headers (PURPOSE, USAGE, BEHAVIOR, RETURNS) and uses bullet points for address ranges. It is moderately long but each sentence earns its place, though the address list could be slightly trimmed.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity of PS2 memory model and lack of output schema, the description covers all needed context: purpose, usage guidelines with alternatives, detailed behavior, parameter semantics, error conditions, and even the return format. It is fully self-contained.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Both parameters are fully described in the schema (100% coverage), so the baseline is 3. The description adds value by providing PS2 memory landmarks for the address parameter and explicit range for value, enhancing meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a clear 'PURPOSE' section stating exactly what the tool does: write a single unsigned byte to the emulator's EE main address space. It distinguishes from siblings by explicitly mentioning write16/write32/write64 for larger values.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The USAGE section provides concrete scenarios (single-byte cheats, debug pokes) and explicitly states when to use alternatives (write16/32/64 for larger values). It also advises on bulk writes (loop or batch via write64) and rollback (save_state/load_state), giving clear guidance.
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. Dates show when Glama detected each change.
9 tool updates
v0.3.0- Changed
pine_load_state1 field changed- changed
Input schema / properties / slot / descriptionPrevious value: -"Save state slot number (0-255). PCSX2 conventionally uses slots 0-9 (mapped to F1-F10 in the GUI), but the PINE protocol accepts the full 0-255 range. Slot files live in PCSX2's per-game savestate folder (typically %USERPROFILE%/Documents/PCSX2/sstates on Windows, ~/.config/PCSX2/sstates on Linux) with filenames like '<serial> (<crc>).<slot>.p2s'. Slot numbers are independent of any path."New value: +"Save state slot number (0-255). The PINE protocol accepts the full 0-255 range. PCSX2 slot files live in PCSX2's per-game savestate folder (typically %USERPROFILE%/Documents/PCSX2/sstates on Windows, ~/.config/PCSX2/sstates on Linux) with filenames like '<serial> (<crc>).<slot>.p2s'. Slot numbers are independent of any path."
- Changed
pine_read_range1 field changed- changed
Input schema / properties / address / descriptionPrevious value: -"Starting absolute byte address in the EE address space. Bytes [address, address+length) are read. No alignment requirement — the tool picks the largest aligned load it can at each step (e.g. an unaligned start, an aligned middle, and an unaligned tail are handled in three different load widths)."New value: +"Starting absolute byte address in the EE main address space. Bytes [address, address+length) are read. No alignment requirement — the tool picks the largest aligned load it can at each step (e.g. an unaligned start, an aligned middle, and an unaligned tail are handled in three different load widths)."
- Changed
pine_read161 field changed- changed
Input schema / properties / address / descriptionPrevious value: -"Absolute byte address in the EE main address space (NOT a per-domain offset). Pass as a number; hex literals like 0x00200000 are fine. Reads 2 consecutive bytes starting here. MUST be 2-byte aligned (address % 2 === 0). PINE on PCSX2 does NOT enforce alignment — unaligned 16-bit access typically returns whatever bytes are at the aligned address below, silently corrupting the value. If you need an unaligned multi-byte read, use pine_read_range and assemble the bytes yourself. Useful range: 0x00100000-0x01FFFFFF for EE main RAM (where 99% of game state lives). An unmapped or invalid address returns a PINE FAIL response."New value: +"Absolute byte address in the EE main address space (NOT a per-domain offset). Pass as a number; hex literals like 0x00200000 are fine. Reads 2 consecutive bytes starting here. MUST be 2-byte aligned (address % 2 === 0). PINE on PCSX2 does NOT enforce alignment — unaligned access typically returns whatever bytes are at the aligned address below, silently corrupting the value. If you need an unaligned multi-byte read, use pine_read_range and assemble the bytes yourself. Useful range: 0x00100000-0x01FFFFFF for EE main RAM (where 99% of game state lives). An unmapped or invalid address returns a PINE FAIL response."
- Changed
pine_read321 field changed- changed
Input schema / properties / address / descriptionPrevious value: -"Absolute byte address in the EE main address space (NOT a per-domain offset). Pass as a number; hex literals like 0x00200000 are fine. Reads 4 consecutive bytes starting here. MUST be 4-byte aligned (address % 4 === 0). PINE on PCSX2 does NOT enforce alignment — unaligned 32-bit access typically returns whatever bytes are at the aligned address below, silently corrupting the value. If you need an unaligned multi-byte read, use pine_read_range and assemble the bytes yourself. Useful range: 0x00100000-0x01FFFFFF for EE main RAM (where 99% of game state lives). An unmapped or invalid address returns a PINE FAIL response."New value: +"Absolute byte address in the EE main address space (NOT a per-domain offset). Pass as a number; hex literals like 0x00200000 are fine. Reads 4 consecutive bytes starting here. MUST be 4-byte aligned (address % 4 === 0). PINE on PCSX2 does NOT enforce alignment — unaligned access typically returns whatever bytes are at the aligned address below, silently corrupting the value. If you need an unaligned multi-byte read, use pine_read_range and assemble the bytes yourself. Useful range: 0x00100000-0x01FFFFFF for EE main RAM (where 99% of game state lives). An unmapped or invalid address returns a PINE FAIL response."
- Changed
pine_read641 field changed- changed
Input schema / properties / address / descriptionPrevious value: -"Absolute byte address in the EE main address space (NOT a per-domain offset). Pass as a number; hex literals like 0x00200000 are fine. Reads 8 consecutive bytes starting here. MUST be 8-byte aligned (address % 8 === 0). PINE on PCSX2 does NOT enforce alignment — unaligned 64-bit access typically returns whatever bytes are at the aligned address below, silently corrupting the value. If you need an unaligned multi-byte read, use pine_read_range and assemble the bytes yourself. Useful range: 0x00100000-0x01FFFFFF for EE main RAM (where 99% of game state lives). An unmapped or invalid address returns a PINE FAIL response."New value: +"Absolute byte address in the EE main address space (NOT a per-domain offset). Pass as a number; hex literals like 0x00200000 are fine. Reads 8 consecutive bytes starting here. MUST be 8-byte aligned (address % 8 === 0). PINE on PCSX2 does NOT enforce alignment — unaligned access typically returns whatever bytes are at the aligned address below, silently corrupting the value. If you need an unaligned multi-byte read, use pine_read_range and assemble the bytes yourself. Useful range: 0x00100000-0x01FFFFFF for EE main RAM (where 99% of game state lives). An unmapped or invalid address returns a PINE FAIL response."
- Changed
pine_save_state1 field changed- changed
Input schema / properties / slot / descriptionPrevious value: -"Save state slot number (0-255). PCSX2 conventionally uses slots 0-9 (mapped to F1-F10 in the GUI), but the PINE protocol accepts the full 0-255 range. Slot files live in PCSX2's per-game savestate folder (typically %USERPROFILE%/Documents/PCSX2/sstates on Windows, ~/.config/PCSX2/sstates on Linux) with filenames like '<serial> (<crc>).<slot>.p2s'. Slot numbers are independent of any path."New value: +"Save state slot number (0-255). The PINE protocol accepts the full 0-255 range. PCSX2 slot files live in PCSX2's per-game savestate folder (typically %USERPROFILE%/Documents/PCSX2/sstates on Windows, ~/.config/PCSX2/sstates on Linux) with filenames like '<serial> (<crc>).<slot>.p2s'. Slot numbers are independent of any path."
- Changed
pine_write161 field changed- changed
Input schema / properties / address / descriptionPrevious value: -"Absolute byte address in the EE main address space (NOT a per-domain offset). Pass as a number; hex literals like 0x00200000 are fine. Reads 2 consecutive bytes starting here. MUST be 2-byte aligned (address % 2 === 0). PINE on PCSX2 does NOT enforce alignment — unaligned 16-bit access typically returns whatever bytes are at the aligned address below, silently corrupting the value. If you need an unaligned multi-byte read, use pine_read_range and assemble the bytes yourself. Useful range: 0x00100000-0x01FFFFFF for EE main RAM (where 99% of game state lives). An unmapped or invalid address returns a PINE FAIL response."New value: +"Absolute byte address in the EE main address space (NOT a per-domain offset). Pass as a number; hex literals like 0x00200000 are fine. Reads 2 consecutive bytes starting here. MUST be 2-byte aligned (address % 2 === 0). PINE on PCSX2 does NOT enforce alignment — unaligned access typically returns whatever bytes are at the aligned address below, silently corrupting the value. If you need an unaligned multi-byte read, use pine_read_range and assemble the bytes yourself. Useful range: 0x00100000-0x01FFFFFF for EE main RAM (where 99% of game state lives). An unmapped or invalid address returns a PINE FAIL response."
- Changed
pine_write321 field changed- changed
Input schema / properties / address / descriptionPrevious value: -"Absolute byte address in the EE main address space (NOT a per-domain offset). Pass as a number; hex literals like 0x00200000 are fine. Reads 4 consecutive bytes starting here. MUST be 4-byte aligned (address % 4 === 0). PINE on PCSX2 does NOT enforce alignment — unaligned 32-bit access typically returns whatever bytes are at the aligned address below, silently corrupting the value. If you need an unaligned multi-byte read, use pine_read_range and assemble the bytes yourself. Useful range: 0x00100000-0x01FFFFFF for EE main RAM (where 99% of game state lives). An unmapped or invalid address returns a PINE FAIL response."New value: +"Absolute byte address in the EE main address space (NOT a per-domain offset). Pass as a number; hex literals like 0x00200000 are fine. Reads 4 consecutive bytes starting here. MUST be 4-byte aligned (address % 4 === 0). PINE on PCSX2 does NOT enforce alignment — unaligned access typically returns whatever bytes are at the aligned address below, silently corrupting the value. If you need an unaligned multi-byte read, use pine_read_range and assemble the bytes yourself. Useful range: 0x00100000-0x01FFFFFF for EE main RAM (where 99% of game state lives). An unmapped or invalid address returns a PINE FAIL response."
- Changed
pine_write641 field changed- changed
Input schema / properties / address / descriptionPrevious value: -"Absolute byte address in the EE main address space (NOT a per-domain offset). Pass as a number; hex literals like 0x00200000 are fine. Reads 8 consecutive bytes starting here. MUST be 8-byte aligned (address % 8 === 0). PINE on PCSX2 does NOT enforce alignment — unaligned 64-bit access typically returns whatever bytes are at the aligned address below, silently corrupting the value. If you need an unaligned multi-byte read, use pine_read_range and assemble the bytes yourself. Useful range: 0x00100000-0x01FFFFFF for EE main RAM (where 99% of game state lives). An unmapped or invalid address returns a PINE FAIL response."New value: +"Absolute byte address in the EE main address space (NOT a per-domain offset). Pass as a number; hex literals like 0x00200000 are fine. Reads 8 consecutive bytes starting here. MUST be 8-byte aligned (address % 8 === 0). PINE on PCSX2 does NOT enforce alignment — unaligned access typically returns whatever bytes are at the aligned address below, silently corrupting the value. If you need an unaligned multi-byte read, use pine_read_range and assemble the bytes yourself. Useful range: 0x00100000-0x01FFFFFF for EE main RAM (where 99% of game state lives). An unmapped or invalid address returns a PINE FAIL response."
11 tool updates
v0.2.1- Changed
pine_load_state2 fields changed- added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / slot / descriptionPrevious value: -"Save state slot (0-255)"New value: +"Save state slot number (0-255). PCSX2 conventionally uses slots 0-9 (mapped to F1-F10 in the GUI), but the PINE protocol accepts the full 0-255 range. Slot files live in PCSX2's per-game savestate folder (typically %USERPROFILE%/Documents/PCSX2/sstates on Windows, ~/.config/PCSX2/sstates on Linux) with filenames like '<serial> (<crc>).<slot>.p2s'. Slot numbers are independent of any path."
- Changed
pine_read_range4 fields changed- added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / address / descriptionPrevious value: -"Start address"New value: +"Starting absolute byte address in the EE address space. Bytes [address, address+length) are read. No alignment requirement — the tool picks the largest aligned load it can at each step (e.g. an unaligned start, an aligned middle, and an unaligned tail are handled in three different load widths)." - added
Input schema / properties / address / minimumAdded value: +0 - changed
Input schema / properties / length / descriptionPrevious value: -"Number of bytes to read"New value: +"Number of consecutive bytes to read (1-4096). Hard cap is the tool's max; chunk larger reads yourself. Latency is roughly proportional to length / 8 in serial mode (the default) — a 4096-byte read is ~512 PINE round-trips on a typical 8-byte-aligned region, around 50 ms over loopback."
- Changed
pine_read163 fields changed- added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / address / descriptionPrevious value: -"Memory address (2-byte aligned)"New value: +"Absolute byte address in the EE main address space (NOT a per-domain offset). Pass as a number; hex literals like 0x00200000 are fine. Reads 2 consecutive bytes starting here. MUST be 2-byte aligned (address % 2 === 0). PINE on PCSX2 does NOT enforce alignment — unaligned 16-bit access typically returns whatever bytes are at the aligned address below, silently corrupting the value. If you need an unaligned multi-byte read, use pine_read_range and assemble the bytes yourself. Useful range: 0x00100000-0x01FFFFFF for EE main RAM (where 99% of game state lives). An unmapped or invalid address returns a PINE FAIL response." - added
Input schema / properties / address / minimumAdded value: +0
- Changed
pine_read323 fields changed- added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / address / descriptionPrevious value: -"Memory address (4-byte aligned)"New value: +"Absolute byte address in the EE main address space (NOT a per-domain offset). Pass as a number; hex literals like 0x00200000 are fine. Reads 4 consecutive bytes starting here. MUST be 4-byte aligned (address % 4 === 0). PINE on PCSX2 does NOT enforce alignment — unaligned 32-bit access typically returns whatever bytes are at the aligned address below, silently corrupting the value. If you need an unaligned multi-byte read, use pine_read_range and assemble the bytes yourself. Useful range: 0x00100000-0x01FFFFFF for EE main RAM (where 99% of game state lives). An unmapped or invalid address returns a PINE FAIL response." - added
Input schema / properties / address / minimumAdded value: +0
- Changed
pine_read643 fields changed- added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / address / descriptionPrevious value: -"Memory address (8-byte aligned)"New value: +"Absolute byte address in the EE main address space (NOT a per-domain offset). Pass as a number; hex literals like 0x00200000 are fine. Reads 8 consecutive bytes starting here. MUST be 8-byte aligned (address % 8 === 0). PINE on PCSX2 does NOT enforce alignment — unaligned 64-bit access typically returns whatever bytes are at the aligned address below, silently corrupting the value. If you need an unaligned multi-byte read, use pine_read_range and assemble the bytes yourself. Useful range: 0x00100000-0x01FFFFFF for EE main RAM (where 99% of game state lives). An unmapped or invalid address returns a PINE FAIL response." - added
Input schema / properties / address / minimumAdded value: +0
- Changed
pine_read83 fields changed- added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / address / descriptionPrevious value: -"Memory address"New value: +"Absolute byte address in the EE main address space (NOT a per-domain offset). Pass as a number; hex literals like 0x00200000 are fine. Reads 1 consecutive byte starting here. No alignment requirement for byte access. Useful range: 0x00100000-0x01FFFFFF for EE main RAM (where 99% of game state lives). An unmapped or invalid address returns a PINE FAIL response." - added
Input schema / properties / address / minimumAdded value: +0
- Changed
pine_save_state2 fields changed- added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / slot / descriptionPrevious value: -"Save state slot (0-255)"New value: +"Save state slot number (0-255). PCSX2 conventionally uses slots 0-9 (mapped to F1-F10 in the GUI), but the PINE protocol accepts the full 0-255 range. Slot files live in PCSX2's per-game savestate folder (typically %USERPROFILE%/Documents/PCSX2/sstates on Windows, ~/.config/PCSX2/sstates on Linux) with filenames like '<serial> (<crc>).<slot>.p2s'. Slot numbers are independent of any path."
- Changed
pine_write164 fields changed- added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / address / descriptionPrevious value: -"Memory address (2-byte aligned)"New value: +"Absolute byte address in the EE main address space (NOT a per-domain offset). Pass as a number; hex literals like 0x00200000 are fine. Reads 2 consecutive bytes starting here. MUST be 2-byte aligned (address % 2 === 0). PINE on PCSX2 does NOT enforce alignment — unaligned 16-bit access typically returns whatever bytes are at the aligned address below, silently corrupting the value. If you need an unaligned multi-byte read, use pine_read_range and assemble the bytes yourself. Useful range: 0x00100000-0x01FFFFFF for EE main RAM (where 99% of game state lives). An unmapped or invalid address returns a PINE FAIL response." - added
Input schema / properties / address / minimumAdded value: +0 - added
Input schema / properties / value / descriptionAdded value: +"16-bit value to write. Must be 0-65535 (0x0000-0xFFFF). LSB lands at `address`, MSB at `address+1`. For signed 16-bit values, encode as two's complement (e.g. -1 → 0xFFFF). Values outside the range are rejected by the schema."
- Changed
pine_write325 fields changed- added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / address / descriptionPrevious value: -"Memory address (4-byte aligned)"New value: +"Absolute byte address in the EE main address space (NOT a per-domain offset). Pass as a number; hex literals like 0x00200000 are fine. Reads 4 consecutive bytes starting here. MUST be 4-byte aligned (address % 4 === 0). PINE on PCSX2 does NOT enforce alignment — unaligned 32-bit access typically returns whatever bytes are at the aligned address below, silently corrupting the value. If you need an unaligned multi-byte read, use pine_read_range and assemble the bytes yourself. Useful range: 0x00100000-0x01FFFFFF for EE main RAM (where 99% of game state lives). An unmapped or invalid address returns a PINE FAIL response." - added
Input schema / properties / address / minimumAdded value: +0 - added
Input schema / properties / value / descriptionAdded value: +"32-bit value to write. Must be 0-4294967295 (0x00000000-0xFFFFFFFF). LSB lands at `address`, MSB at `address+3`. For signed 32-bit values, encode as two's complement (e.g. -1 → 0xFFFFFFFF). For floats, reinterpret the IEEE-754 bits as an integer first. Values outside the range are rejected by the schema, NOT silently truncated — pass the value you actually want stored." - added
Input schema / properties / value / maximumAdded value: +4294967295
- Changed
pine_write644 fields changed- added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / address / descriptionPrevious value: -"Memory address (8-byte aligned)"New value: +"Absolute byte address in the EE main address space (NOT a per-domain offset). Pass as a number; hex literals like 0x00200000 are fine. Reads 8 consecutive bytes starting here. MUST be 8-byte aligned (address % 8 === 0). PINE on PCSX2 does NOT enforce alignment — unaligned 64-bit access typically returns whatever bytes are at the aligned address below, silently corrupting the value. If you need an unaligned multi-byte read, use pine_read_range and assemble the bytes yourself. Useful range: 0x00100000-0x01FFFFFF for EE main RAM (where 99% of game state lives). An unmapped or invalid address returns a PINE FAIL response." - added
Input schema / properties / address / minimumAdded value: +0 - changed
Input schema / properties / value / descriptionPrevious value: -"Decimal string (e.g. \"18446744073709551615\")"New value: +"64-bit value to write, as a non-negative DECIMAL STRING (digits only, no '0x' prefix, no sign, no separators). Range 0 through 18446744073709551615 (2^64 - 1). Example: \"18446744073709551615\" writes 0xFFFFFFFFFFFFFFFF. Encoded as a string so values past 2^53 are preserved exactly (JSON numbers lose precision at that point). For signed 64-bit values, encode as two's complement (e.g. -1 → \"18446744073709551615\")."
- Changed
pine_write84 fields changed- added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / address / descriptionPrevious value: -"Memory address"New value: +"Absolute byte address in the EE main address space (NOT a per-domain offset). Pass as a number; hex literals like 0x00200000 are fine. Reads 1 consecutive byte starting here. No alignment requirement for byte access. Useful range: 0x00100000-0x01FFFFFF for EE main RAM (where 99% of game state lives). An unmapped or invalid address returns a PINE FAIL response." - added
Input schema / properties / address / minimumAdded value: +0 - added
Input schema / properties / value / descriptionAdded value: +"Byte value to write. Must be 0-255 (0x00-0xFF). Values outside this range are rejected by the schema."
14 tool updates
v0.2.0- First observed
pine_get_info - First observed
pine_get_status - First observed
pine_load_state - First observed
pine_ping - First observed
pine_read_range - First observed
pine_read16 - First observed
pine_read32 - First observed
pine_read64 - First observed
pine_read8 - First observed
pine_save_state - First observed
pine_write16 - First observed
pine_write32 - First observed
pine_write64 - First observed
pine_write8
TDQS
Every tool has a clearly distinct purpose: ping for connectivity, get_info/get_status for metadata, read/write tools differentiated by data width and alignment, save/load state for snapshotting, and read_range for bulk reads. No two tools overlap in what they do.
All tools follow a consistent pine_verb_noun pattern (e.g., pine_read8, pine_write32, pine_save_state, pine_get_info). The naming is predictable and immediately conveys the tool's action and operand size or target.
14 tools is well-scoped for a PS2 emulator memory debugger. It covers connection, memory reads/writes at multiple widths, bulk reads, save states, and metadata—all essential operations without unnecessary bloat.
The set covers core read/write, save/load, and metadata operations comprehensively. Minor gaps exist: no bulk write tool (only loop-based), no pause/resume (unavailable via PINE), and no reset. Still, the surface is sufficiently complete for the intended domain.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
MCP server for understanding Javascript internals from ECMAScript specification.
A simple MCP server built with FastMCP and python
An MCP server that provides read access to your cloud storage providers, bank accounts and more.
Related MCP Servers
- AlicenseAqualityCmaintenanceMCP server for RetroArch via its Network Control Interface. Drive any libretro core — read/write memory, save/load state, screenshot, pause/frame-advance/reset — across NES, SNES, Genesis, N64, GBA, PS1 and more.17243MIT
- AlicenseAqualityBmaintenanceMCP server for the mGBA Game Boy Advance emulator. Read and write GBA memory, inject button presses, take screenshots, save/load state, and step the emulator through a Lua bridge.18361MIT
- AlicenseAqualityCmaintenanceMCP server for BizHawk, the multi-system emulator. Drive NES, SNES, GB/GBC/GBA, Genesis, N64, PSX, Saturn and more through one Lua bridge — memory r/w across named domains, joypad input, frame-advance, screenshot, save/load state.20264MIT
- AlicenseAqualityCmaintenanceAn 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 debugg23256MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/dmang-dev/mcp-pine'
If you have feedback or need assistance with the MCP directory API, please join our Discord server