Skip to main content
Glama

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
RMMZ_BROWSERNoPath to a Chromium-family browser if it is somewhere unusual.
RMMZ_PROJECTYesProject folder to operate on. Also accepted as --project <dir>.
RMMZ_CODEBOOKNoPath to a generated commands.json if it is not in the default place.
RMMZ_SETTINGSNoThe MCP client settings file the scripted suites read the four values above out of, so you never set a path twice. Defaults to ~/.qoder-cn/settings.json, then ~/.qoder/settings.json.
RMMZ_LIVE_TOKENNoShared secret between the server and RMMZLiveBridge.js. Required for any live tool; the plugin's Token parameter must be the same value.
RMMZ_ENGINE_VERSIONNoPin the engine version (e.g. 1.8.0) when several are installed.
RMMZ_CORESCRIPT_ROOTNo<install>/data/corescript. Skipped if auto-discovery finds your install.

Instructions

Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.

This server publishes no instructions, or was last inspected before Glama recorded them.

Capabilities

Features and capabilities supported by this server

Protocol revision2025-11-25

CapabilityDetails
tools
{
  "listChanged": true
}

Tools

Functions exposed to the LLM to take actions

NameDescription
project_infoA

Summarize the configured RPG Maker MZ project: maps, tilesets, database tables, switch and variable names, and which engine version the renderer uses.

list_mapsA

List every map with its size, tileset, event count and encounter settings.

get_mapA

Read a map's structure: dimensions, tileset, every event with position, graphic, trigger and page conditions. Optionally dump a rectangular slice of one tile layer as ids.

inspect_cellA

Read every tile layer, shadow bits, region id, terrain tag and the event standing on a single cell.

tileset_slotsB

Show which image is bound to each A1-A5/B-E slot of a tileset and the first tile id of each slot, so tile ids can be chosen without guessing.

render_mapB

Composite a map exactly the way the engine does (autotiles, shadow bits, higher-tile z-order) and return it as an image, so layout can be verified visually. Overlays can show passability, region ids or terrain tags.

create_mapC

Create an empty map file plus its MapInfos entry.

delete_mapA

Remove data/MapNNN.json and clear its MapInfos slot — the other half of create_map, and the call that lets a build script tidy the prototypes it made on the way to the version it wanted. It refuses while some event on another map still transfers the player there, because that is a door into a map that is gone, and it lists those events so the caller can decide; force deletes anyway and still lists them. Both files are backed up first, so undo_writes puts the map file and its tree entry back together.

set_map_propertiesA

Set the map-level fields that are not tiles and not events: display name, tileset, the map-name banner, dashing, battlebacks, parallax (name, loop, auto-scroll, start offset), the map's own BGM/BGS and whether they autoplay, and the encounter table. Encounters are the reason this exists — list_maps reports them, and without a writer a playtest can be built that never meets a monster. Pass encounters as [{regionId, troopId, appearances}]: regionId 0 means the whole map, otherwise it matches the region ids painted on layer 5 with set_tiles, and appearances is the weight against the other rows. Omit clearEncounters to replace the list, set it true to empty it. Size is not here on purpose: resizing means rebuilding the tile array, and a wrong array length corrupts the map, so create the map at the size you want.

set_tilesA

Write tile ids on one map. Pass explicit cells, or a rectangle to fill. Layer 0-3 are tile layers, 4 holds shadow bits 0-15, 5 holds region ids. MZ puts A1/A2 ground on layer 1, A3 on 2, A4 upper walls on 3 and A5/B/C/D/E on 0 — leave layer out and each tile goes to the layer its own slot belongs to, which is the difference between a forest and a field of trees buried under the grass. Pass it to override, and painting a tile on a layer it does not belong to still renders, only at the wrong depth, so the reply says so.

place_eventB

Create an event at a cell, or move and rename an existing one by id.

remove_eventB

Delete an event from a map, leaving a null hole in the events array as the editor does.

copy_eventA

Duplicate an event onto another cell or another map: every page with its conditions, graphic, trigger and full command list, deep-cloned, plus the note. The copy gets a fresh id and its own self switches (those are keyed by event id at runtime), so a chest copy starts closed even if the original is open. Both copies are live afterwards, which matters for an autorun or parallel-process event. The source is not modified.

set_event_pageC

Set a page's graphic, trigger, priority, movement and conditions. Adds the page when it does not exist yet. trigger: 0 action button, 1 player touch, 2 event touch, 3 autorun, 4 parallel. priorityType: 0 below tiles, 1 same as tiles, 2 above tiles.

add_commandsA

Append raw {code, indent, parameters} commands to a page, keeping the terminating code-0 entry last. Use command_catalog first to learn the parameter layout of a code. The page's block structure is re-read after the append, and anything whose indent does not match the branch it sits under comes back in warnings.

set_commandsB

Overwrite an event page's whole command list, terminator included. Block levels are read the way the engine reads them: a body written at the same indent as its Conditional Branch or Loop is reported in warnings instead of being quietly kept.

show_textA

Add a Show Text dialog to an event page. MZ stores a dialog as one command 101 carrying [faceName, faceIndex, background, positionType, speakerName] followed by one command 401 per text line, each holding its line in parameters[0]; this tool builds that shape so lines can never end up as null in $gameMessage._texts.

decode_commandsC

Render a page's command list as readable lines using the engine-derived command dictionary.

command_catalogA

Search the command dictionary derived from the engine's Game_Interpreter. Returns each code's parameter names in order, so event commands can be built without guessing. Ask for exact codes to also get the engine body, which shows how each parameter is consumed (a name like operateValueArg1 alone does not say whether the amount is params[1] or params[2]).

read_databaseA

Read data/.json. Returns entries compactly, or one entry in full. Covers Actors, Classes, Skills, Items, Weapons, Armors, Enemies, Troops, States, Animations, Tilesets, CommonEvents, System, MapInfos. Every table answers count and entries, so a caller can read one shape; System is a single object rather than a row table, so it answers value as well and entries holds that object as its one row.

patch_database_entryA

Apply a shallow field patch to one entry of a database table (or to System.json's top-level keys). Nested objects and arrays must be passed complete, because MZ has no partial-update semantics on them — a nested object that arrives without a key the entry already had loses that key, and the reply names the keys it lost so the caller can read the entry first. System's switches and variables are the exception: pass either an array of names or an object keyed by id, and the array the engine needs is what gets written.

create_database_entryA

Claim a row in a database table the way the editor does. MZ keeps these as 1-based arrays in which the row's id is its array index, and it never removes one: a fresh project ships unused slots as complete rows with an empty name, and those names are what keeps an id from being reused under a saved game. So this takes the first blank slot, and only grows the table when none is left — pass no id and it behaves like the editor's add button. The field shape comes from the blank slot itself, else from a blank sibling, else from copyFrom (or the last row, which the reply reports as basedOn because you have just copied a real entry's stats, icon and all). fields is then merged over that, shallowly, exactly as patch_database_entry does. System.json has no rows and MapInfos is the map tree, so those two refuse; use patch_database_entry and create_map. There is no delete: blanking a name is what removal means here, and it is a patch.

find_eventsB

Find events by name, by command code used, or by graphic. Answers questions like 'which events call common event 12' without reading every map by hand.

map_connectivityA

Flood-fill walkable cells from a start position and report which events the player can actually reach. Answers 'can the player get there' instead of trusting tile placement. An event blocks a cell only when one of its pages is same as tiles (the engine's isNormalPriority), which is why a chest stops you and a floor decal does not; conditions are not evaluated, so a page that only applies later still counts as blocking. An event is standable when its own cell is reachable and touchable when a neighbour is, which is all an action-button event needs; an event with an autorun or parallel page is automatic and needs no path at all. Transfer Player commands found on standable events are followed into their destination maps, so a game whose rooms are joined only by portals reads as one connected space instead of a pile of isolated cells — and a portal that lands on an impassable tile is called out, because that is a trap the player cannot escape. reports carries one entry per map walked, in the order they were reached.

list_backupsA

Every write copies the previous file into .rpgmaker-mcp/backups. List them for a data file, or pass a project-relative path like js/plugins.js for one of the few files outside data/ that the tools also write.

rollback_dataA

Restore a backed-up copy of one file. table takes the same identifier list_backups prints: a database name like System, a map as Map037 or 37, or a project-relative path like js/plugins.js. Without to this reverts the newest change (or the one before it, when the newest already matches what is on disk); with to it restores a specific backup number from list_backups, where 0 is the oldest. For undoing several of your own recent edits across files, prefer undo_writes.

write_historyA

Every file this server process has written, newest first, with the backup each one can be reverted to. This is the ledger undo_writes steps through; it lives in memory, so it starts empty when the server restarts even though the backup files are still on disk (list_backups sees those).

undo_writesA

Step the last writes back, newest first, each file restored to the bytes it had before that write — which is what Ctrl+Z stands in for here, since the editor keeps its undo stack in a process this server cannot reach. A write that created a file removes it again. Pass steps to undo several, or since with the index a previous write_history reported to land exactly back at that point whatever was written in between; check write_history first, because one tool call can touch more than one file and a half-undone operation is worse than the mistake you meant to take back.

check_assetsA

Scan every image and audio name the project data mentions — database fields (character, face, battler, title1/title2, battlebacks, tileset names, animation effect), map parallax/bgm/bgs fields, and Play BGM/BGS/ME/SE, Show Picture and Play Movie commands inside events — and report the ones with no file on disk plus the ones whose spelling differs from the file only in case. This is the cheap way to find both before a playtest does: a missing image stops the engine's game loop and paints an error into a DOM panel that a canvas screenshot cannot see, and a missing audio file says nothing at all. Icons are not covered: MZ draws them by index from img/system/IconSet.png rather than by name.

import_assetA

MZ has no importer and no per-asset metadata: the folder and the base name are the whole registration. This copies a file into one of the folders the engine's own loaders read (img/characters, img/faces, img/sv_actors, img/sv_enemies, img/enemies, img/battlebacks1/2, img/titles1/2, img/tilesets, img/parallaxes, img/pictures, img/animations, img/system, audio/bgm, audio/bgs, audio/me, audio/se, movies), checks the extension belongs there, refuses a name that differs from an existing file only by case (the filesystem folds those together and the second one would never load), and writes through the same backup journal as every other write, so undo_writes takes it back — including deleting a file that did not exist before. The reply gives the value to put in the data field (the name without extension) and which fields already name it, which is the half of check_assets that was missing a file. Overwriting needs overwrite: true; the bytes being replaced stay recoverable in the backup list.

list_pluginsA

Read js/plugins.js and report every entry in load order: enabled or not, its description, and the parameter values the editor stored. Each entry is cross-checked against the @param blocks in the plugin's own file, so undeclared names a key the plugin never mentions (a typo, or a leftover from an older version) and unset lists declared parameters that are running on their @default. fileExists: false means the plugin is switched on but its script is not in js/plugins/, which stops the game at boot.

patch_pluginA

Set one plugin's enabled status, description, or parameter values in js/plugins.js — the same edit as the editor's plugin manager, without reformatting the file: only the touched entry's object literal is rewritten. Parameter values are stored the way MZ stores them, so scalars become strings and struct or array values stay JSON. PluginManager.parameters is read once at boot, so a running playtest needs a restart to see this, and an editor with the plugin manager open will overwrite the file on save.

read_plugin_sourceA

Return a window of lines from js/plugins/<name>.js, the only way to see what a plugin actually hooks before editing around it. Defaults to the first 200 lines; pass fromLine to page through a long file. declared carries the parsed @param blocks so a parameter name can be matched to the code that reads it.

enable_pluginA

Put a plugin that is already sitting in js/plugins/ into js/plugins.js — the same edit the editor's plugin manager makes, and the step patch_plugin cannot do because it only reaches entries that are already listed. The parameters come from the file's own @param/@default header, so nothing runs on a value the plugin never declares, and parameters overrides single keys on top of that. Re-running it on a plugin that is already listed switches it on and merges your parameters instead of adding a second entry. A game already running read js/plugins.js at boot, so it needs a restart — and an editor with the plugin manager open overwrites this file on save.

write_plugin_sourceA

Create or replace js/plugins/<name>.js. This is Unity's manage_script equivalent, with one difference that matters for the loop: MZ plugins are plain JavaScript loaded at boot, so there is no compile step to wait for — the file is live the moment a game starts. The write is journaled, so undo_writes takes it back, and js/plugins.js is not touched unless enable is set. With enable the plugin is added to the editor's list (or switched on if it is already there) and its parameters filled from the @default values in the header it was just given, which means the header has to be written first for the parameters to be anything. A game already running will not pick any of this up: restart it.

block_structureB

Report the engine-verified rules for nested command lists: which codes take a deeper indent, which continuation codes repeat, and where a block ends. Given a page it also returns the same warnings the writers return — the places where this list's indents will not do what they look like they mean.

live_statusA

Report what the running game last sent through the RMMZLiveBridge plugin: scene, map, player position, switches, variables and party. listening is about this process's own socket, and the call waits for the bind to report, so a port another copy of this server already holds reads as a listenError here rather than as health. Also explains how to enable the bridge.

live_evalA

Run a JavaScript expression inside the live game and return its value. Requires the plugin's Allow Eval parameter, a configured RMMZ_LIVE_TOKEN, and a running playtest. Anything the engine exposes works: $gameVariables.value(3), $gamePlayer._x, $gameSwitches.value(12). An expression that returns a promise is waited for and the settled value comes back, so one call can watch a frame counter, a transfer or a scene change instead of polling for it. The game gives a promise 20000ms to settle and the call waits for the same 20000ms by default, so a promise that needs 15s is answered, not cut off; raise timeoutMs to 60000 for a longer wait, but the plugin still abandons the promise itself at 20s. Two engine behaviors bite here, so they are worth knowing before a result looks wrong. Calling an API that moves the character directly ($gamePlayer.moveStraight(6)) reaches some of what a key does and not the rest: the party step count and the touch triggers happen inside the step itself, but the encounter counter only ticks in Game_Player.updateNonmoving, which is a frame or two later, so a fast scripted walk can outrun it — live_move holds the arrow instead and gets all of it. And $gamePlayer.performTransfer() run by hand rebuilds the map from the previous map's $dataMap, because loading the new file is Scene_Map's job: the player then stands "on" the new map with the old map's events running under them. reserveTransfer(...) and wait is the way.

live_waitB

Poll an expression in the running game until it is truthy, so a sequence (menu open, battle over, message finished) can be followed instead of guessed at.

live_keyA

Press a game key in the live game (Ok=13/32, Cancel=27, Shift=16, arrow keys 37-40) to advance dialogs or drive input. Each press is held for a counted number of engine frames and re-asserted on every one of them, and the call answers once the game has run them all, so a slow or headless frame rate cannot swallow it and neither can the browser taking focus. The reply carries the measured frame rate it was sized with and whether the player's cell actually changed. To walk somewhere, prefer live_move: one press is one step only if the player happens to be standing still when it lands. Needs the RMMZLiveBridge plugin, not Allow Eval.

live_moveA

Hold an arrow key until the player has arrived cells cells away, and answer with where they really got to and what stopped them. Use this instead of live_key whenever the intent is go-there rather than press-this: a direction press only moves the player on a frame when they are standing still, so a key press is not one step, and this waits for the steps themselves. Because it drives the engine's own input path, the things that only happen when a person walks happen here too - the party's step count, the encounter roll, an event set to player-touch. A wall, a dialog, a running event or a scene change ends the walk early and says which. Needs the RMMZLiveBridge plugin, not Allow Eval.

live_reloadA

Make the running playtest re-read the current map file and rebuild itself around it: tiles, autotiles, events and map size, with the player left where they are. This is the author-then-look loop — after set_tiles / place_event / set_event_page, call it instead of booting a new game and transferring. It returns once the reloaded map is actually live, so the next live_eval or live_screenshot sees the change. Event interpreters restart from the top and database tables (System, Actors, Items, Tilesets) are not re-read, so a new game is still the answer for those. Does not need Allow Eval.

live_screenshotA

Grab the running game's own composited frame as a PNG: message windows, face graphics, fonts, weather, character sprites, tile blending. render_map shows what the data says; this shows what the player sees. It re-runs the engine's render pass (Graphics._app.render()) and reads the canvas in the same task, so it works without MZ enabling preserveDrawingBuffer. Video playback is a separate DOM element and is not part of the frame. Needs a running playtest.

live_diagnosticsA

Return what the live game has logged: uncaught exceptions, entries from the engine's own error screen, failed image/audio/data loads, and console.warn/error output. The plugin keeps a rolling 200-entry buffer and merges repeats, so a per-frame throw arrives once with a repeat count. Pass the cursor from a previous reply as since to fetch only what is new, or clear before an action so whatever appears afterwards was caused by it, or full to get the recorded call stack with each entry. This keeps answering after the game has crashed (SceneManager.stop() freezes the render loop; stopped reports it), which is exactly when the file layer cannot tell you what went wrong.

live_pauseA

Stop the engine's update loop without leaving the scene, the way Unity's pause works: SceneManager.updateMain is skipped, so nothing moves, no event interpreter advances and no input is sampled, while the last frame stays on screen and live_screenshot / live_eval / live_diagnostics keep answering. Keys sent with live_key while paused are dropped, because Input is only sampled inside the update loop. Resume with paused: false.

live_stepA

Run N engine frames and stop again, for watching an animation cycle, a message window page by page, or a battle sequence frame by frame. Pauses first if the game is running, then calls SceneManager.updateMain exactly N times (1..600), so the reported advanced is the frame delta to compare against. A frame that throws is handed to the engine's own catchException, so the error shows up in live_diagnostics rather than killing the session silently.

assert_in_gameA

Hand over a list of {label, expression} and get a pass/fail report back, the way a test runner does it, instead of writing a throwaway script for every playtest. Each expression is evaluated in game scope and has to be truthy; give one a timeoutMs to poll it until it holds, which is what a dialog opening, a transfer landing or a battle ending needs. A failing assertion does not stop the rest unless stopOnFailure is set, and whatever the game logged while the list ran comes back with the result, so a failure arrives with its own reason attached. Needs Allow Eval on the plugin.

batchA

Run a list of {tool, args} calls in order as one transaction. If a step fails — or is rejected before it runs, because the arguments do not match what that tool declares — every file the batch wrote goes back to the bytes it had before, so a bad argument on step four never leaves a half-built map behind. Each step's arguments are validated against that tool's own schema first, so the whole list is checked for the obvious mistakes before anything is written. Reading tools may be included and their results come back per step. undo_writes, rollback_data and a nested batch are refused as steps: they move the write journal this transaction rolls back against. Steps that talked to the running game are named in the reply, because a file rollback cannot un-press a key — follow it with live_reload or a new game.

live_sessionA

Own the whole loop from the tool surface: start serves the project on a loopback port, launches a windowless Chromium-family browser on it and waits for the RMMZLiveBridge plugin to report, so live_status / live_screenshot / assert_in_game have a game to answer from without anyone opening the editor. By default it then walks the title screen into a new game with the engine's own commandNewGame; a client that allows only sixty seconds per call should pass newGame: false and call boot afterwards, because a cold boot plus that walk can exceed sixty seconds. boot alone drives whatever the page is showing into a map, status reports what is running, reload reloads the page (what a freshly written plugin file needs), stop closes the browser and releases the port. The browser is the only process this tool starts, it is recorded in .rpgmaker-mcp/session.json, and stop kills that pid's tree only after confirming the recorded profile directory is still on its command line, so a recycled pid is never touched. It refuses to start a second browser while a game is already reporting, because two games on one bridge cannot be told apart. Reaching a map needs the plugin params Allow Eval and keepAwake: without the first the session comes up on the title screen and says so, without the second a headless page never has focus and MZ skips scene updates.

make_npcA

Place a non-player character in one call: graphic, movement, what it says, and an optional second page that takes over once a switch or self switch is set. The dialog compiles into the shapes the engine reads (Show Text 101 plus one 401 per line; a follow page conditioned on the self switch the first page then sets), and the whole thing runs as one transaction — if any part fails, nothing is written. Answers with the map rendered around the new NPC. The two defaults worth knowing: priorityType 1 (same as tiles), because a person should block their cell, and replace true, so re-running a build script updates this NPC instead of leaving a second copy of it. patrol writes the page's own movement route, which the editor's moveType 1 runs. For more than talk — choices, gates, battles — use script here or make_choice_scene.

make_choice_sceneA

Write an event's whole script from a step list: dialog, choice branches (each option can carry its own when gate), if over switches, variables, items, gold and buttons, loop with break, battle with win/escape/lose branches, shop, transfers, audio, screen effects, gameOver. This is the tool for a scene rather than a person: pass a cell to place a new event, or an existing eventId and pageIndex to rewrite that page. The compiler produces the indentation and the branch markers (402/403, 411/412, 413, 601-603) the engine reads, so a body cannot land outside the branch it belongs to — the mistake that otherwise shows up as a choice that always takes the first option. Checked before writing: unknown step names, conditions or commands that name a switch, variable or database row the game does not have, audio and face files the project lacks. One transaction, map rendered back.

make_chestA

Place a chest: the closed graphic, the line it says, what it gives, and the opened page that replaces it afterwards. MZ has no chest command, so this writes the two pages the engine does read — page 0 hands out the contents and sets self switch A, page 1 is conditioned on self switch A and shows the open chest. Because a self switch is keyed to the event id, copy_event of this chest gives a second chest that is closed again. requires gates the payout with a Conditional Branch rather than a page, so a locked chest stays openable once the key condition arrives instead of silently becoming an unlocked one. The contents are checked before anything is written: an id that is a blank slot, or gold that would make this a tax, fails the call.

link_mapsA

Write both ends of a connection in one call: a door event on each map that transfers the player to the other, with a graphic (!Door1, a tile, or nothing for an invisible exit), the door sound, the fade, and the direction they arrive facing. a and b are the doorway cells, and a player coming through one does not stop on it: they arrive at the first open cell beside the far door (above it, then right, left, below) facing away, and the reply's landed says which cell that was. Pass land on an end to choose it yourself — including the doorway cell itself, which is what the transfer onto the threshold used to do. A door walled in on all four sides has nowhere beside it, so it keeps the doorway and the answer carries a warning. The reason it exists is the check it does first: a player-touch door only fires when the player can stand on its cell, and a destination cell that is blocked means the player arrives stuck inside a wall with no way back — both of which a transferred playtest surfaces minutes later as 'nothing happens'. requires writes a locked pair of pages: page 0 refuses, page 1 (conditioned on the switch or item) does the transfer. twoWay: false leaves the far end alone — no door is written there, so its coordinates are the destination itself and nothing shifts. Both maps come back rendered.

make_shopA

One call for a working shop: the keeper's graphic, a greeting, the goods, and a line for after the window closes. MZ stores a shop as command 302 carrying the first good in its own parameters plus one 605 line per further good, each [kind, id, priceType, price, purchaseOnly] with kind 0 item / 1 weapon / 2 armor and priceType 0 meaning the row's own price. MZ has no purchase branch, so the commands after the goods run when the window closes whatever the player did — this says so in the reply instead of inventing a hook that does not exist. Every good is checked first: the row must exist and must not be a blank slot, and a good with no price whose item price is 0 is reported, because that is a free item. when adds the page that replaces the locked one, which is how a shop that opens after a quest is built.

make_encounter_zoneA

Paint a region, make the troops, and attach the encounter rows in one call. A zone is three writes across two files (layer 5 of the map, then the map's encounter list) plus a Troops row per group, and the row shapes are exactly the ones that break a game when they are guessed: MZ reads regionSet unconditionally, so a row without that array throws inside Scene_Map on its first roll and freezes the map mid-walk, and a row without weight makes the weight sum NaN so that no row on the map ever rolls. A troop entry either names an existing troopId or lists enemies (ids, or {id, level?, x?, y?}), and the row is cloned from a real troop so its member shape matches what the editor writes. Region 0 means the whole map. The reply calls out any row whose region no cell carries, because that is the mistake that makes a zone feel empty rather than broken.

set_tileset_flagsA

Edit what tiles do, without the editor. MZ keeps this as an 8192-entry flags array per tileset: 0x01/0x02/0x04/0x08 are impassable from Down/Left/Right/Up, 0x10 makes those four override the layers underneath, 0x20 ladder, 0x40 bush, 0x80 counter, 0x100 damage floor, 0x200/0x400/0x800 boat/ship/airship, and bits 12 up are the terrain tag. Passage is per direction, so passable: false is a fence and blockFrom: ["up"] is a ledge you can step onto but not climb back off. One bit has to be handled for you: MZ's 0x10 means "no effect on passage" — Game_Map.checkPassage skips the tile entirely — and much of the stock tileset (the pillars, trees and statues among others) ships with it set, so writing passage bits into one of those tiles without clearing it reports success and blocks nothing. Any passage change therefore clears 0x10 unless you pass overwrite: true on purpose, and the reply says when it did. For an A1-A4 autotile the id a map stores is one of 48 shapes of a base pattern and the engine reads the flags of that stored id, so a change is applied across the whole shape group unless shapes: false says otherwise; the reply reports which ids moved and what each flag became. This reaches every map that uses the tileset at once, which is the point and the danger: dryRun shows the before and after without writing, and validate_game re-checks the maps that now block.

fix_projectA

Write the System.json keys the engine reads without a fallback and this project does not have. An installation ships data/newdata as a third way to start a project besides the editor, and that template has no advanced.windowOpacity: the game stops on the title screen's first window with a stack that names clamp and nothing about the missing key, and a project copied from the template is otherwise indistinguishable. The values come out of your own installation's template — they belong to the engine, so this package does not carry a copy of them; advanced.windowOpacity is the one key the template itself lacks, and 192 is what the editor writes. It also puts switches and variables back into the array shape the engine indexes, and writes only what is genuinely absent, so running it on a project the editor made changes nothing. It does not invent maps, events or a start position: validate_game reports those and set_startup writes them. dryRun answers with the plan alone.

validate_gameA

Read-only check of the things that only show up in play. System: the start position on a map that exists, inside it, on a cell the player can stand, with a party of at least one named actor; the switch and variable tables in the array shape the engine indexes, and every id an event names that is past their end; and the keys the engine dereferences without a fallback (advanced.windowOpacity and friends), which is how a project copied from the shipped data/newdata template turns out to die on its own title screen. Events: transfer destinations (checked against the destination map's own size and passability), every database id a command reads, encounter rows (a real troop, a regionSet that is painted, a non-zero weight), pages whose indent does not match the branch they sit under, and the graphics and audio the project does not have — including the picture a Show Picture command names, which nothing else reads, and which only ever loads as <name>.png. Also tile ids painted from a slot the tileset has no image for, and reachability from the start through the portals that exist. Each problem comes back as {severity, where, what, fix} and fix names the call that clears it. This is the gate a build script should pass before a playtest starts, and it never writes.

clear_eventsA

Remove every event on a map in one transaction, or only the ones whose name or character sheet you name. This is the call that makes a rebuild script possible: without it, re-painting a map's event layer means one remove_event per event and a half-finished map if the script dies halfway, and a build that runs twice ends up with two of every NPC. dryRun answers with what would go, which is also the quickest way to see a map's cast. The map is rendered in the reply, so you can look at the empty room rather than trust the count.

set_startupA

Write the opening state of the game in one call: the title on the splash and in the window, where New Game puts the player (map, cell, facing), who starts in the party, and the switch and variable name tables. patch_database_entry can do all of it and has to be handed advanced whole to touch one key of it, which is the shape of mistake this exists to prevent — a partial nested patch drops the keys you did not send. Idempotent: re-running a build script sets the same opening rather than appending. Reads back the start cell through the engine's own passability rules and refuses to place the player inside a wall, because that is a game that boots and never moves.

make_mapA

One intent — "a 26x18 field of grass, with a stone floor and a wall ring and a gap for the door" — as one call. It makes or reuses the map, sets its tileset, resolves the entire paint plan, writes it in one pass, applies the passage flags the plan names, and answers with the rendered map. Before this the high-level layer stopped at content and every build script had to drop to create_map + set_tiles per map, which is where the depth mistakes came from. The plan is resolved to one tile per cell, the last stroke winning, because that is how the engine decides passage: Game_Map.checkPassage reads tile layers 3 down to 0 and returns on the first tile whose flags say something, so a wall left on layer 3 underneath a floor tile still blocks the doorway — the map renders as a room and the player cannot walk out of it. Paint ground first, then what sits on it, and nothing is ever stacked. On a repaint the plan owns the cell's whole stack: every layer it does not name is zeroed, so last run's roof cannot survive under this run's floor. Each tile still lands on the layer its own slot belongs to (A1/A2 → 1, A3 → 2, A4 → 3, A5/B–E → 0); that is set_tiles with layer omitted, so a forest is never buried under the grass again. flags is handed to set_tileset_flags for this map's tileset in the same transaction, so "these ids are walls" is stated where the walls are painted. regions paints layer 5 for make_encounter_zone to roll on. The reply counts the walkable cells the finished terrain leaves, because a map with no walkable cell is not something the engine will report — it is a game that boots and never moves.

describe_tilesA

The tile dictionary, read out of the project the way the engine reads it. For each id: which slot it belongs to (A1–A4 are autotile shape groups of 48, A5/B–E are fixed), which image that slot is bound to, which layer MZ draws it on, and what its entry in the tileset's 8192-entry flags array means — open or blocked from which of the four directions, whether 0x10 is set so those direction bits do nothing at all (much of the stock tileset ships that way), ladder, bush, counter, damage floor, the vehicle bits, the terrain tag — plus how many cells of a map actually use it. Ask four ways: mapId for every tile a map really paints, which is the fastest way to learn an unfamiliar tileset; tiles for the ids in your hand; slot to walk one slot one base pattern at a time; or neither, for the slot table alone. contactSheet also draws the answer: a labelled sheet, one 3x3 block per id rendered by the same code path as a real map, with the id and the engine's own passability verdict printed under each block, because "which id is the water" is a question a picture settles faster than a table. The sheet is drawn on a scratch map that this call creates and deletes again; no tileset row and no real map is touched.

live_dialogA

The dialog layer of a live game, driven by intent instead of counted key presses. read says what the game is waiting for and what it is showing: the message text, the choice options with each one's enabled state and where the cursor is, the number pad's digits, and whether the window is actually able to take a key right now. answer picks an option by index or types a number, dismiss presses on until the game stops waiting, and cancel takes the cancel branch. Every one of them ends by reading the game again, so the reply tells you what came next. Why this is a tool and not three live_key calls: $gameMessage.isChoice() turns true the moment a choice is queued, while Window_ChoiceList is still fading in, and the engine only moves the cursor when Window_Selectable.isCursorMovable() holds — which needs the window open and active. A cursor key sent in those frames is dropped, and the answer comes back as the first option whatever you meant. Measured on a real playtest: it cost a run. So answer waits for the window to be able to take keys, presses one edge at a time, and re-reads the cursor after every press instead of assuming it moved; the reply says how many presses it took and refuses an option the game has switched off, because that press does nothing and an empty wait looks like a bug.

make_battleA

Both rows a battle needs — the Enemies row and the Troops row that holds it — from one ask, plus the region that rolls it if you want it met by walking. create_database_entry will write either row, but it has to be handed the whole thing, and the shapes here are the ones that fail quietly: a drop is {kind, dataId, denominator} where kind 0 is an empty slot and denominator: 3 means one chance in three (30 would be read as one in 30, not 30%); a trait is {code, dataId, value} — 11 element rate, 12 debuff rate, 14 state resist, 21 param, 22 hit and evasion, 31 attack element, 32 attack state, 63 collapse type — where the key is value, unlike an item effect, which uses value1/value2; and an action naming a skill that has no Skills row is a battle that throws on the turn the foe decides to act. So names are resolved against the project's own tables, what is not there is refused, and what was written comes back in words. Idempotent by name: a build script that runs twice leaves one foe, not one foe per run.

make_itemB

An Items, Weapons, Armors or Skills row in one call, with the effects and equipment rules spelled in words. The effect shape is the whole reason this exists: MZ stores an item effect as {code, dataId, value1, value2} — 11 recovers HP as mhp × value1 + value2, 12 MP, 13 TP, 21 and 22 add and remove a state, 31 and 32 add a buff and a debuff (dataId is the parameter, value1 the turns), 33 and 34 remove them, 41 is the special (0 = escape), 44 runs a common event — while a trait on the same row is {code, dataId, value} with one key. Send the trait's value to an effect and the engine computes mhp × undefined, floors it to NaN, and adds NaN to the actor's HP: a number the bar cannot draw and the save file now has to carry. This compiles the words into the two shapes and refuses a state, parameter or common event the project does not have. The type ids are the other quiet failure: an item whose itypeId is not 1 or 2 is never listed — MZ has no item-type name list, the menu reads those two numbers and $dataSystem.itemCategories decides whether the tab is open at all — and a weapon whose wtypeId matches no weapon type cannot be equipped by anyone, so both are checked against System.json and said out loud. Idempotent by name, like the rest of the layer: re-running a build script rewrites the same row instead of adding one.

Prompts

Interactive templates invoked by user choice

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription

No resources

TDQS

B3.4/5.0

Scored across 65 tools

Disambiguation2/5

While each tool targets a distinct operation, the server has layered overlapping abstractions that are hard to tell apart: create_map vs make_map, set_tiles vs set_tileset_flags, place_event vs make_npc vs make_choice_scene, make_chest, link_maps, make_shop, make_encounter_zone, make_battle, and make_item all ultimately write events or database rows; add_commands vs write_plugin_source vs set_commands vs make_choice_scene write scripts; and many live_* tools overlap (live_eval, live_key, live_move, live_step). An agent choosing between the high-level builders and the low-level primitives has no clear rulebook.

Naming Consistency3/5

Mostly snake_case is consistent, but verb styles are mixed: imperative verbs (get, set, create, delete, list, add, remove, copy, place, clear), 'make_' builders (make_map, make_npc, make_battle, make_item, make_choice_scene, make_chest, make_shop, make_encounter_zone), and nouns (project_info, command_catalog, block_structure, tile_slots) coexist, with several live_* tools. The pattern is readable but not predictable.

Tool Count2/5

65 tools is far beyond typical MCP guidance and forces an agent to navigate layers of abstractions for the same underlying write operations. The high-level builders could collapse many of the primitive tools, reducing cognitive load.

Completeness5/5

The surface covers the RPG Maker MZ lifecycle end to end: map creation, tile painting, event scripting, database CRUD, plugin management, asset validation, backup/undo, validation, and live runtime control. No obvious domain gap remains; even asset import and rollback are present.

Maintenance

ActivityMaintained
ResponsivenessNo issues