Skip to main content
Glama

mcp-pine

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

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

PINE_TARGET

PCSX2 ≥ 1.7 (setup)

PlayStation 2

✅ Yes (toggle in settings)

28011

pcsx2 (default)

RPCS3 (setup)

PlayStation 3

⚠️ Has IPC with PINE-compatible opcodes — verify before relying on it

28012

rpcs3

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

npm install -g mcp-pine

Verify with mcp-pine (it prints a startup line and waits for stdio — Ctrl+C to exit).

Option B — npx (no install)

npx -y mcp-pine

Option 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` hook

Emulator setup

PCSX2

  1. Launch PCSX2 (1.7.x Qt or newer).

  2. Settings → Advanced → Enable PINE Server (the option may live under a different submenu in some builds — search the settings for "PINE").

  3. Default slot is 28011. If you change it, set PINE_SLOT for mcp-pine.

  4. 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:

  1. Configuration → Advanced → Enable IPC server (or similar — check current RPCS3 docs).

  2. Note the configured port.

  3. 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-pine

Verify:

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

Claude Desktop

Edit claude_desktop_config.json:

Platform

Path

macOS

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

Windows

%APPDATA%\Claude\claude_desktop_config.json

Linux

~/.config/Claude/claude_desktop_config.json

{
  "mcpServers": {
    "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

PINE_TARGET

pcsx2

Emulator name. Known values: pcsx2, rpcs3. Selects (1) the Unix socket file prefix on Linux/macOS (<target>.sock.<slot>), and (2) the memory map and setup help shown in tool descriptions. Unknown values pass through with a generic memory map.

PINE_SLOT

target default

PINE slot — also the TCP port on Windows. Defaults: pcsx2=28011, rpcs3=28012. Set explicitly to override.

PINE_HOST

127.0.0.1

Override the host (TCP only)

PINE_SOCKET_PATH

(auto)

Override the full Unix socket path on Linux/macOS, bypassing automatic resolution

Tools

Tool

Description

pine_ping

Verify the connection by querying the emulator version

pine_get_info

Title, serial (e.g. SLUS-21274), disc CRC, game version, status

pine_get_status

Just the running/paused/shutdown state

pine_read8 / pine_read16 / pine_read32 / pine_read64

Read memory

pine_read_range

Bulk read up to 4096 bytes (client-side pipelined PINE calls)

pine_write8 / pine_write16 / pine_write32 / pine_write64

Write memory (RAM only — ROM writes are silently dropped)

pine_save_state

Trigger save state to a numbered slot (0-255)

pine_load_state

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

0x00100000-0x01FFFFFF

EE main RAM (32 MiB) — start here for game data

0x10000000

Hardware registers (DMA, GIF, VIF)

0x11000000

VU0 / VU1 memory

0x12000000

GS privileged registers

0x1C000000-0x1C1FFFFF

IOP RAM (2 MiB)

0x1F800000

IOP scratchpad

0x70000000

EE scratchpad (16 KiB)

Troubleshooting

Symptom

Cause / Fix

Cannot reach PINE server

Emulator isn't running, PINE isn't enabled in its settings, or the slot/port doesn't match. Check PINE_SLOT.

PINE FAIL response (0xFF)

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 0x00100000 first (almost always inside loaded EE RAM).

Tool calls work but values look corrupted

Check endianness expectations — PINE returns little-endian; if you're interpreting strings, use read_range-style byte reads.

PINE call timed out (10s) from pine_ping after some heavy 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 pine_ping times out. Fix: fully restart PCSX2. Reconnecting alone won't help — the corruption is on the emulator side.

pine_read_range slower than mGBA's read_range

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 PINE_PIPELINE_BATCH=2.

Development

npm install
npm run dev      # tsc --watch

Quick smoke test against a running PCSX2:

node .scratch/smoke.cjs

Debugging with the MCP Inspector

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

PINE_TARGET=pcsx2 npm run inspector

Build 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

MIT

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

Inputs: no named parameters.

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

Inputs: no named parameters.

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

Inputs: slot (required).

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

Inputs: no named parameters.

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)'.

Inputs: address (required).

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)'.

Inputs: address (required).

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.

Inputs: address (required).

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)'.

Inputs: address (required).

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.

Inputs: address (required), length (required).

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

Inputs: slot (required).

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

Inputs: address (required), value (required).

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

Inputs: address (required), value (required).

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.

Inputs: address (required), value (required).

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

Inputs: address (required), value (required).

Tool Schema Changelog

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

Loading tool schema changelog…

    TDQS

    A4.6/5.0

    Scored across 14 tools

    Disambiguation5/5

    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.

    Naming Consistency5/5

    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.

    Tool Count5/5

    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.

    Completeness4/5

    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

    ActivityActive
    ResponsivenessLimited data

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      A
      quality
      C
      maintenance
      MCP server for RetroArch via its Network Control Interface. Drive any libretro core — read/write memory, save/load state, screenshot, pause/frame-advance/reset — across NES, SNES, Genesis, N64, GBA, PS1 and more.
      17
      26 npm
      6
      MIT
    • A
      license
      A
      quality
      B
      maintenance
      MCP server for the mGBA Game Boy Advance emulator. Read and write GBA memory, inject button presses, take screenshots, save/load state, and step the emulator through a Lua bridge.
      18
      35 npm
      7
      MIT
    • A
      license
      A
      quality
      C
      maintenance
      MCP 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.
      20
      68 npm
      6
      MIT
    • A
      license
      A
      quality
      B
      maintenance
      An MCP server that exposes PPSSPP — the PlayStation Portable emulator — to any MCP-compatible client (Claude Desktop, Claude Code, etc.) via PPSSPP's built-in WebSocket debugger interface. Read and write PSP memory, drive games with button input, capture screenshots, set CPU breakpoints, inspect MIPS Allegrex registers — all through a clean tool interface. No bridge plugin needed; PPSSPP's debugg
      23
      29 npm
      13
      MIT