Odel
RPG Maker MV Ultimate MCP

RPG Maker MV Ultimate MCP

Local
@diegolopez020821TypeScriptMITUpdated 6 days ago

RPG Maker MV Ultimate: AI copilot to generate, edit and understand RPG Maker MV projects (MCP)

๐ŸŽฎ RPG Maker MV Ultimate

An AI copilot that builds, understands and watches your RPG Maker MV game

npm downloads CI MCP Registry node license

Quick start ยท What it does ยท Map generation ยท Live bridge ยท Intelligence ยท Tools


A Model Context Protocol server that lets an AI agent work on a real RPG Maker MV project on disk โ€” database, maps, events, plugins, system โ€” through 13 consolidated tools validated against the actual engine, so what comes out is coherent and playable.

It does three things that are usually missing:

๐Ÿ—๏ธ BuildsGenerates maps that look hand-made, wires events from presets, and edits every database with real IDs instead of invented ones.
๐Ÿง  UnderstandsReads the whole project and answers why the door never opens, which map nobody can reach, which skill breaks the game.
๐Ÿ‘€ WatchesRuns the game and reports back: exceptions, player position, screenshots โ€” and reloads a map you just edited without losing the save.

โšก Quick start

1 โ€” Add it to your MCP client. No clone needed; the package ships an executable.

{
  "mcpServers": {
    "rpgmaker-mv": {
      "command": "npx",
      "args": ["-y", "rpgmaker-mv-mcp"],
      "env": {
        "RPGMAKER_PROJECT_PATH": "C:/path/to/your/RPGMakerMV/project"
      }
    }
  }
}
Claude Code one-liner, and running from source
# Claude Code, user scope
claude mcp add rpgmaker --scope user \
  --env RPGMAKER_PROJECT_PATH="C:/path/to/project" \
  -- npx -y rpgmaker-mv-mcp
# From source
git clone https://github.com/DiegoLopez0208/RpgMakerMVUltimate-MCP
cd RpgMakerMVUltimate-MCP
npm install && npm run build
RPGMAKER_PROJECT_PATH=/path/to/your/project npm start

MCP clients load tool definitions once at startup, so restart the client after adding or upgrading the server.

2 โ€” Point it at a project. RPGMAKER_PROJECT_PATH is the folder containing data/, js/ and index.html. The server starts without it; call set_project_path at runtime instead if you prefer.

3 โ€” Let the agent look around first.

get_project_context { detail: "full" }        โ†’ what exists, with real IDs
analyze_project     { view: "overview" }      โ†’ health, counts, unreachable maps

Works with Claude Desktop, Claude Code, opencode, and any MCP-compatible client.


๐Ÿงญ What it does

flowchart LR
    A["๐Ÿค– Agent"] -->|"generate_map ยท manage_map_event"| B["๐Ÿ“ Project on disk"]
    B -->|"validate ยท balance ยท metrics"| A
    B -->|"playtest"| C["๐ŸŽฎ Running game"]
    C -->|"exceptions ยท position ยท screenshots"| A
    A -->|"reload_map"| C

The bottom half of that loop is what the bridge adds. Before it, the agent wrote files and hoped.


๐Ÿ—บ๏ธ Map generation

Two paths, both behind generate_map. Pick by whether your project uses RTP art.

mode: "procedural" (default)mode: "semantic"
HowClones a hand-authored map from the 106 bundled RTP templates, closest size firstLays out a mission graph, then paints it through a tileset profile
Looks likeReal multi-tile buildings, walls, furnitureRooms and corridors shaped by what the space is for
TilesetsRTP, or close to itAny โ€” DLC, itch.io, custom
GuaranteesSame seed โ†’ same mapSame seed โ†’ same map, and the key is always reachable before the door it opens

The knowledge-driven path

{ "mode": "procedural", "theme": "town", "name": "Riverbend", "width": 40, "height": 30 }

Themes with a matching template โ€” town, village, dungeon, interior, castle, world and more โ€” clone a real map instead of painting tile noise. Themes without one (beach, swamp, desertโ€ฆ) fall back to Perlin terrain, BSP dungeons and cellular caves. Combat themes auto-wire random encounters from your existing troops; town and village auto-create enterable house interiors with two-way warps.

Themes ยท forest town village castle dungeon cave beach desert swamp ruins interior snow harbor volcano sewer fortress magic_forest magic_interior space_interior space_exterior world

Other modes: blank (empty canvas), themed (simple layout), template (one specific bundled map), batch (many at once), duplicate (copy an existing map).

The tileset-independent path

The bundled templates are raw MV map JSON, so their tile IDs only mean anything on RTP sheets. Change the tileset and the map turns to noise. semantic keeps the layout abstract until the last moment:

manage_system { action: "mine_templates" }               # learn from THIS project
generate_map  { mode: "semantic", tilesetId: 5, rooms: 6, seed: 42 }
  • Mining reads every map you already made and derives semantic layouts (ground / wall / water / prop / door, multi-tile props kept whole), a tileset profile naming the concrete tile your project uses for each role, and token adjacency counts. Nothing in the project is modified โ€” everything lands in .mcp-cache/.
  • Generating builds the mission first โ€” entrance โ†’ key โ†’ locked door โ†’ treasure โ†’ boss โ†’ exit, plus side rooms โ€” as a graph whose edges are the only ways through, then paints it. Because the lock is an edge and the key sits on the entrance side of it, the map is solvable by construction. Autotile shapes are recomputed at the end from the finished neighbourhood, never guessed cell by cell.
  • The result includes markers naming the cell of every mission role, which is where to put events with manage_map_event.
  • Pass a mined templateId (e.g. "mined-3") to re-materialise one of your own maps onto a different tileset.

๐Ÿ”Œ The live bridge

playtest on its own is fire-and-forget: the game opens and nothing comes back. The bridge closes the loop.

manage_system { action: "install_bridge_plugin" }   # once per project
manage_system { action: "bridge_start" }            # opens ws://127.0.0.1:32123
manage_system { action: "playtest" }                # the game connects on its own
manage_system { action: "bridge_telemetry", types: ["exception", "log"] }
sequenceDiagram
    participant A as ๐Ÿค– Agent
    participant S as ๐Ÿ–ฅ๏ธ MCP server
    participant G as ๐ŸŽฎ Game (nwjs)
    A->>S: edit_map
    S->>S: atomic write to Map002.json
    A->>S: bridge_command reload_map
    S->>G: reload_map
    G->>G: reserveTransfer + _needsMapReload
    G-->>S: reload_complete
    A->>S: take_screenshot
    S->>G: capture_screenshot
    G-->>S: PNG in base64
    S-->>A: path for analyze_image
  • ๐Ÿ“ก Telemetry โ€” exceptions with stack traces, console.error/warn, scene changes, player position, which event command is executing (so a hung event can be pinpointed), FPS and heap. Frames are consumed as you read them unless you pass peek.
  • โ™ป๏ธ Hot reload โ€” reload_map re-reads the current MapXXX.json and rebuilds the scene without losing party state: it reserves a transfer to the player's own position with _needsMapReload, the engine's own reload seam, rather than rebuilding Spriteset_Map by hand. reload_database re-reads one data file; System.json and Tilesets.json need a fresh playtest and are refused with an explanation.
  • ๐Ÿ“ธ Screenshots โ€” take_screenshot { name: "collision-proof" } captures the live playtest through the MCP plugin, saves a timestamped PNG under .mcp-cache/screenshots/, and returns its path for inspection or QA evidence. No shell screenshot command is involved. manage_system { action: "bridge_screenshot" } remains as a compatibility alias.

๐Ÿ”’ Security

The plugin returns before anything else runs unless the game is under NW.js and was launched with a test argument. A deployed build a player double-clicks never reaches the socket code, or even require('fs').

It checks every argument rather than only argv[0] the way Utils.isOptionValid does, because playtest passes the project path first. So a deployed build deliberately launched with a literal test argument would get past the guard โ€” and then find no handshake file, and never connect.

The server binds 127.0.0.1 only, refuses any upgrade carrying a browser Origin (cross-site WebSocket hijacking), and requires the session token from .mcp-bridge.json โ€” compared in constant time โ€” within 5 seconds or the connection is dropped.

The command surface is a fixed allowlist with no eval primitive.


๐Ÿ” Project intelligence

analyze_project is read-only and fully offline. It models the whole project once, so an agent can reason about a game it did not build.

ViewAnswers
overviewCall this first. Counts, health summary, maps unreachable from the start
validateEvery consistency problem at once โ€” see below
explainWhy does this never happen? e.g. "Switch 12 is gated in 3 places but never set ON"
usageEvery event, common event and troop that touches a switch/variable/item, with read-write roles
graphThe map transfer network and what is reachable
astOne event's logic as a readable tree
pluginsWhat plugins the project uses, their parameters and commands
critiqueA designer's opinion on one map: dead space, clutter, event spread, monotony
metricsThe same map measured โ€” see below
balanceDatabase entries that are out of line with their peers โ€” see below
refactorCommand sequences copy-pasted across events, worth extracting into a Common Event
searchFind things by meaning across names, dialogue and descriptions
indexThe structured digest the other views are built on
validate โ€” the problems the editor never warns about

Broken transfers, missing map files, dangling common-event/item/troop references, duplicate IDs, named-but-unused switches and variables, a bad starting position, unreachable maps โ€” and actor names written into dialogue as \N[id] that do not resolve.

That last one is worth its own sentence: the engine resolves \N[id] at draw time, not from any structural parameter, so a bad id passes every other check and the editor shows nothing wrong. The line just renders in-game with a hole where the name should be, and a player finds it before you do.

metrics โ€” measured, not judged
  • Reachability โ€” flood fill from the real entry point. Walkable tiles the player can never get to, and events with no reachable tile beside them, are softlocks rather than style notes.
  • Dead space โ€” the unreachable share of the rectangle, against a band for expected (interior / dungeon / exterior).
  • Shape โ€” the walkable area thinned to a one-cell skeleton and read as a graph: endpoints, junctions, cycles, critical path, linearity. Linearity near 1 is a corridor with no choice to make.
  • Variety โ€” Shannon entropy over 5ร—5 tile windows: the monotonous-floor problem, measured.
  • Tension โ€” for maps with random encounters, how many steps the player is from a shop, inn or save point.
balance โ€” outliers relative to their peers, not to invented thresholds

A skill dealing 400 damage is fine in a game where everything does, and broken in one where nothing else breaks 60. So each entry is scored on a power metric and compared against the others in its category: damage per MP for skills, gold per point of ATK+MAT for weapons, gold per DEF+MDF for armors, HP per EXP for enemies.

The comparison is leave-one-out โ€” an entry is judged against statistics it had no hand in creating. Included in its own numbers, a badly broken entry drags the mean toward itself until it stops looking unusual at all.

Damage formulas are parsed, never executed (tokenise โ†’ shunting-yard โ†’ evaluate). One that cannot be read statically is listed under unreadableFormulas rather than scored as zero damage, which would pull every average down and hide the very outliers you were looking for.

Narrow with category, loosen or tighten with thresholdSd (default 2).

Offline map inspection

  • query_map { view: "ascii", mapId } โ€” render a map as a character grid with event markers. The cheapest way to see a layout and pick coordinates.
  • query_map { view: "validate", mapId } โ€” lint one map for invalid tile IDs, broken transfers and missing event terminators.

๐Ÿงฐ The 14 tools

Click to expand the full surface
ToolPurpose
query_databaseList / get by ID / search any database (actors, classes, skills, items, weapons, armors, enemies, states, troops, tilesets, common events, animations)
create_database_entryCreate entries, with presets: damage_skill, healing_skill, buff_skill, state_skill, boss_enemy, encounter_troop
update_database_entryPartial updates (incl. troops & animations); append commands to common events; add enemies to troops
delete_database_entryDelete entries with reference-breakage warnings
query_mapMap tree, full map data, events, single event, lint, offline ASCII render
generate_mapKnowledge-driven, semantic, procedural, blank, themed, template, batch or duplicate
edit_mapFill tile layers, set display names, organize the map tree, connect two maps, set encounters
manage_map_eventCreate (presets: npc, chest, teleport, door, shop, inn, boss, puzzle_switch), update, convert an NPC into a merchant/inn/sign in place, delete, add commands, bulk-populate
manage_systemTitle, switch/variable names, starting position, author a plugin, scaffold an editor-openable project, playtest, open/repair in editor, mine templates, and the live bridge
take_screenshotCapture and name a live playtest PNG through the authenticated MCP bridge
analyze_projectThe read-only intelligence layer above
get_project_contextProject digest, asset index, per-tileset tile IDs, bundled-template catalog
set_project_pathSwitch projects at runtime
analyze_imageOptional Vision-AI image analysis, plus offline tileset grid measurement and quadrant colors

The 101 fine-grained v4 tool names still work as call aliases. Set RPGMV_LEGACY_TOOLS=1 to advertise them too.


๐Ÿ›ก๏ธ Write safety

  • Atomic. Every write goes to a temp file and is renamed over the target, so an interrupted call can never leave half-written JSON.
  • Backed up. Rotated timestamped copies under .mcp-backups/ (last N, RPGMV_BACKUP_KEEP, default 10).
  • Previewable. Pass dryRun: true to any mutating tool to see exactly what it would write, without touching disk.

โš ๏ธ Close the RPG Maker editor while an agent is working. The editor holds the project in memory and will overwrite changes when it saves.


โš™๏ธ Configuration

VariableRequiredDescription
RPGMAKER_PROJECT_PATHrecommendedThe project folder (the one with data/ and js/). Optional โ€” set_project_path works at runtime
RPGMAKER_MV_INSTALLfor playtestEngine install root, for playtest / open_editor / scaffold_project. Defaults to the standard Steam path
RPGMV_BRIDGE_PORToptionalLoopback port for the live bridge (default 32123)
RPGMV_BACKUP_KEEPoptionalBackups kept per file (default 10)
RPGMV_LEGACY_TOOLSoptional1 also advertises the 101 legacy tool names
VISION_API_URLto enable visionBase URL of an OpenAI-compatible vision endpoint. Unset = vision disabled
VISION_API_KEYoptionalBearer token; only sent when set
VISION_MODELoptionalModel name (default meta/llama-3.2-90b-vision-instruct)
VISION_API_PATHoptionalEndpoint path (default /v1/chat/completions)
Vision AI is opt-in

analyze_image { mode: "ai" } sends a project image (tileset, sprite, screenshot, battler) to any OpenAI-compatible endpoint. Nothing is sent anywhere unless you configure it; the grid and colors modes and every other tool work fully offline.

# OpenAI
VISION_API_URL=https://api.openai.com VISION_API_KEY=sk-... VISION_MODEL=gpt-4o npm start
# Ollama (local, no key)
VISION_API_URL=http://localhost:11434 VISION_MODEL=llava npm start

Works with OpenAI, Ollama, LocalAI, NVIDIA NIM, vLLM, LiteLLM, or any OpenAI-compatible proxy.


๐ŸŽ“ Agent Skill

A portable Agent Skill teaches any model the crash-free workflow โ€” build maps with generate_map, add content with manage_map_event presets, never hand-paint tiles or guess IDs. It lives at skill/rpgmaker-mv-mcp/SKILL.md.

# Claude Code / Claude.ai
npx degit DiegoLopez0208/RpgMakerMVUltimate-MCP/skill/rpgmaker-mv-mcp ~/.claude/skills/rpgmaker-mv-mcp
# opencode
npx degit DiegoLopez0208/RpgMakerMVUltimate-MCP/skill/rpgmaker-mv-mcp ~/.opencode/skills/rpgmaker-mv-mcp

Also listed in awesome-claude-skills.


๐Ÿ“š Knowledge base

Static reference data extracted from the MV corescript
FileContent
tile-ids.jsonTile ID ranges, autotile formula, sheet descriptions, layer meanings
passage-flags.jsonFlag bits, common flags, passage check logic
event-commands.json~140 event command codes with parameter schemas
enums.jsonScope, occasion, hitType, damageType, restriction, and the rest
trait-effect-codes.jsonTrait codes 11-64, effect codes 11-45
database-schemas.jsonFull schemas for every MV data type
image-paths.jsonimg/ directories, tileset slots, naming conventions
map-templates.jsonIndex of the 106 bundled reference maps
stamps.jsonMined multi-tile object stamps (trees, props) per tileset
maps/The 106 RTP reference map JSONs used for template cloning

๐Ÿšง Known limitations & roadmap

  • Decoration semantics are best-effort in the RTP-template path; rare multi-tile objects may land as single tiles. The mined path keeps multi-tile props whole.
  • Town and dungeon layouts keep improving โ€” planned: a central plaza or well as a landmark, houses in rows facing roads, fences and yards, richer road networks, more room variety.
  • mode: "semantic" currently generates dungeon-shaped missions. Town and open-world mission grammars are next, as is using the mined adjacency counts to decorate rather than only to describe.
  • balance compares like with like inside a category, so a boss will legitimately look like an outlier next to random encounters. Read the flag, not the verdict.
  • The bridge is Windows/nwjs playtest only and needs its plugin installed in the project.
  • Vision AI requires your own endpoint.

๐Ÿ› ๏ธ Development

npm install
npm run build      # tsc compile (+ copies knowledge/ into dist/)
npm test           # vitest
npm run typecheck
npm run dev        # tsx watch mode
WhereWhat
src/server.tsTool handlers and MCP transport
src/toolDefinitions.ts + src/router.tsThe 13-tool surface and its routing
src/tools/*Per-domain CRUD
src/utils/mapGenerator.tsTemplate cloning and procedural generation
src/utils/graphGenerator.ts + src/utils/materialize.tsMission graphs and the semantic compiler
src/bridge/*The loopback WebSocket and the in-game plugin
src/intel/*The read-only layer behind analyze_project
knowledge/Static reference data and bundled maps

๐Ÿ’ฌ Feedback

Actively developed, and feedback is very welcome โ€” bug reports, weird maps, missing tools, ideas. Open a GitHub Issue with what you asked the agent to do and what you got; an exported map JSON or a screenshot helps a lot.


DiegoLopez0208/RpgMakerMVUltimate-MCP MCP server

MIT ยท Built for RPG Maker MV