mv-ai-bridge
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mv-ai-bridgeread the current game state and talk to the nearest NPC"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Two pieces: an in-game plugin that exposes state and accepts player-level input over a local WebSocket, and an MCP server that turns it into tools. Grab the prebuilt zip or build from source.
Gameplay only. The bridge reads state and presses buttons. It does not edit the database or teleport the player. A few conveniences (
manage.formation,manage.use_item,checkpoint.load) call runtime APIs directly and therefore bypass plugin-level side effects; each one is markedbypasses:in its tool description.Native MCP. Stdio and Streamable HTTP, no agent-specific glue.
Built for long sessions. Composite actions stop at the next decision point, checkpoints retry a bad room, notes survive context resets.
How it works
MCP client (agent)
│ stdio or Streamable HTTP (bearer token)
▼
mv-ai-bridge ── WebSocket ws://127.0.0.1:7321/game ── MV_AI_Bridge.js (in game)
│
RPG Maker MV runtimeOne process serves both halves:
ws://<host>:<port>/gamefor the game plugin (the game dials out to the bridge).http://<host>:<port>/mcpfor MCP clients (Streamable HTTP, JSON responses).http://<host>:<port>/healthfor a quick status check. It requires the token because it returns the game title and a copy of the last observed game state, not just a boolean.
The bridge binds to loopback by default and requires a bearer token.
Related MCP server: RPG Maker MZ MCP Server
Requirements
Node.js 20 or newer.
An RPG Maker MV game on PC (NW.js), MV 1.5+ / 1.6.x. RPG Maker MZ uses a different runtime and is not supported.
Windows, macOS or Linux. The game and the bridge run on the same machine.
Install
Prebuilt (no build step): grab rpgmaker-mv-ai-bridge-v0.1.0.zip from
Releases — it holds the plugin, the bridge bundled into a
single file, install.bat / install.sh and serve.bat. Node.js 20+ is the only requirement.
Or build from source:
git clone https://github.com/K-ame/rpgmaker-mv-ai-bridge.git
cd rpgmaker-mv-ai-bridge
npm install
npm run build
# copy the plugin into the game and register it in plugins.js
node dist/cli/index.js install "/path/to/MyGame"install writes www/js/plugins/MV_AI_Bridge.js, appends the entry at the end of www/js/plugins.js (so the plugin
wraps every other plugin's behaviour), and keeps a one-time backup at plugins.js.mv-ai-bridge.bak.
A short manual snippet is printed if plugins.js is not plain JSON. See Uninstall to undo it.
Run node dist/cli/index.js doctor "/path/to/MyGame" to check Node version, project layout, plugin placement,
token and session state.
Run
node dist/cli/index.js serve # HTTP MCP + game WebSocket
node dist/cli/index.js serve --stdio # also speak MCP over stdin/stdout
node dist/cli/index.js serve --no-stdio # HTTP onlyDefault address is 127.0.0.1:7321. The bridge writes the live token and URL to ~/.mv-ai-bridge/session.json;
node dist/cli/index.js session prints it. Then launch the game — the plugin retries the socket every few seconds.
Stdio MCP is only enabled with --stdio; it is never inferred from stdin, so background or piped runs keep stdout
clean. To let an MCP client launch the bridge as a child process:
{
"mcpServers": {
"mv-ai-bridge": {
"command": "node",
"args": ["C:/path/to/rpgmaker-mv-ai-bridge/dist/cli/index.js", "serve", "--stdio"]
}
}
}Or connect over HTTP. The token is in ~/.mv-ai-bridge/token:
{
"mcpServers": {
"mv-ai-bridge": {
"type": "streamable-http",
"url": "http://127.0.0.1:7321/mcp",
"headers": { "Authorization": "Bearer <token>" }
}
}
}Files
Path | Purpose |
| Bearer token for |
| Running bridge address, pid and version. |
| Persistent agent notes, keyed by game title. |
Set MV_AI_BRIDGE_HOME to relocate that directory.
Tools
Every call returns the same envelope:
{
"ok": true,
"status": "done",
"action": "walk",
"effect": { "steps_done": 3 },
"interrupted_by": null,
"reason": null,
"tick": 12345,
"state": { "scene": "map", "map": { "id": 100, "name": "Cave 3", "area": ["Cave 1", "Cave 2"] } },
"new_log": [],
"warnings": []
}status is one of:
done— the goal was reached or the action naturally stopped.partial— a budget ran out or movement was blocked;effectshows how far it got.interrupted— a message, choice, battle, transfer or scene change took control.interrupted_bysays which.error— the action could not start (ok: false).
partial and interrupted are normal gameplay outcomes, not tool failures.
Tool | What it does |
| Scene, map, player tile/facing, open message, choices, party, battle, nearby events. |
| Local map as a character grid ( |
| Nearby events with names, distance, trigger type, |
| Hold a direction for up to N tiles. Returns |
| A* pathfind to an exact tile. On failure returns |
| Start a map event with the action button: face it from an adjacent tile, walk onto its tile for |
| One action-button press. |
| Fast-forward typing, turn pages, stop at a choice or the end of the event. |
| Pick an option by index or label in the message choice, an event's Select Item window, or the active menu/shop/battle window (same index as |
| Cancel button (close menus, back out). |
| Drive the battle UI: |
| Out-of-battle party control: roster with equipment/skills/inventory, equip a slot, swap formation, use an item. |
| New game, continue from the newest save, options, back. The argument is |
| Wait for settled / message / choice / battle / scene change / milliseconds. |
| Save, load, list or delete an in-memory snapshot. Never touches save slots on disk. |
| Raw engine button press ( |
| Polled event log: messages, choices, transfers, scene changes, battle starts/ends, party or enemy state and equipment changes, plus |
| Persistent notes on the bridge machine, keyed by game title. The value under key |
Error reasons
When an action cannot start, ok is false and reason is usually one of:
| Meaning |
| The action only works on the map (or another specific scene) and the current scene is different. |
| The scene looks like a map but no usable map data was found, usually a missing or partial |
|
|
|
|
| The button cannot act right now; |
Other reasons (blocked, threat_nearby, busy, unreachable, ...) describe action-specific outcomes and are
documented with the action that returns them.
Inferred fields
Two fields are heuristics, not data the engine exposes:
balloon(onlist_events) andballoons(onobserve) — RPG Maker has no quest-marker flag. The bridge reports one when the event page's overlay image name matchesbikkuri(!) orhatena/question(?), or when a balloon is playing on the event right now. A marker drawn with a differently named image, as a picture, or by a balloon that has already finished is missed.hint(inlog) — added when a dialogue line matches a small set of requirement or clue patterns. A hint phrased unusually can be missed, and ordinary text that happens to match can be flagged.
Everything else in the envelope is read from runtime objects.
Reading pace
advance keeps each dialogue page on screen for page_delay_ms before tapping through it, so the text stays
readable. The default comes from the plugin parameter ReadDelay (2000 ms). Pass page_delay_ms: 0 to skip at
full speed. The delay applies to message windows only; battle-log lines keep the game's own pace.
Debug log file
NW.js hides its console, so the plugin parameter Debug is usually invisible in a real play session. Set LogFile
to a path (for example www/mv-ai-bridge.log, resolved against the game's working directory) to write the same
diagnostics to a file: connection, every command with its arguments, the final job status and errors. true is
shorthand for www/mv-ai-bridge.log. The file is appended, never rotated.
Freeze while thinking
Set the plugin parameter FreezeWhileThinking to true (default false; edit the entry in plugins.js, or
re-run install and change it) to pause map updates whenever the game is settled and no bridge action is running. The scene keeps
rendering; bridge actions (walking, menus) unfreeze the world while they run. Only the world simulation (event
movement, parallel events) stops. observe then reports state.world_frozen: true.
The freeze does not apply while a message, choice, battle or transfer is active, so dialogue and combat animate
normally. It reduces, but does not replace, avoid_hazard: a monster that already reached an adjacent tile will
still engage when the agent acts.
Roaming monsters
Many MV games implement world-map enemies as ordinary events that start a battle, either directly (Battle
Processing) or through a common event the page calls. list_events reports hazard: true for those, scanning only
the page that is active right now, and chases: true when the move route follows the player. observe adds a
threats list of battle events within 8 tiles, so the first perception call is enough to decide whether to engage.
walk and go_to accept avoid_hazard: N, which keeps the route N tiles away from battle events and stops with
status: "partial", reason: "threat_nearby" before stepping closer. This is best-effort: a chasing monster whose
chase range meets or exceeds the margin will still reach a player who stands still. Treat it as a way to reduce
accidental encounters, not a guarantee of evasion.
Battle tactics
The bridge does not decide tactics; it exposes every option and executes the one the agent picks. battle auto is
the exception: it hands the whole fight to the engine's auto-battle loop, so it is meant for trash encounters.
observeduring battle returnsstate.battle.commands(the actor command window: attack, one entry per skill type, guard, item),state.battle.actor(who is choosing),skill_typeswith every skill and itsmp_cost/tp_cost/usable, the battleitems, andtargets.battlewithcommand_index(oractionplusskill_type_index),skill_index,item_indexandtarget_indexissues one command for the inputting actor and returns as soon as the game commits it. Callobserveagain to command the next actor.Costs come from the game's skill plugins, so they are read with
skillMpCost/skillTpCostrather than thempfield ofSkills.json, which is often absent or overridden.Perception covers more than HP:
observelistsstatesfor every party member, every enemy and both target windows, and the event log recordsactor_state/actor_equipentries whenever a state is added or removed or an equipment slot changes. Enemy state changes are logged the same way asenemy_state. Costume damage and similar conditions implemented as states or unequips are visible even if they only exist for a single round.
Party management
manage covers equipment, formation and item use outside battle:
roster(read-only) — party order, level, HP/MP/TP, states, equipment per slot, learned skills and inventory;detail: "full"adds the items each slot can accept.equip— change one slot byactor_id+slot+item_id(item_id: 0unequips).formation— swap two party positions withswap: [i, j]. This calls the runtime party-order API directly (bypasses:party-change plugins that charge a fee or enforce restrictions when the player reorders in the menu).use_item— apply an inventory item through the engine action system rather than selecting it in the item menu (bypasses:plugins that hook menu item selection, add their own confirmation or enforce extra targeting rules; the user is the movable member with the highestpha).
Everything except roster requires a settled map with no message, choice, event or transfer running.
Menus and shops
Menus and shops are driven with input, back and observe. Outside the map and outside battle, observe adds a
ui block listing every visible window with its class name, active flag, cursor index and the entries the window
itself holds — menu commands, item lists with counts, shop goods with prices. The bridge does not model individual
menu plugins; it reads the window objects the game built, so the stock MV menus and heavily redesigned ones look the
same to the agent. Open the menu with input menu, move with the arrow buttons and confirm with ok; back
closes a screen.
Checkpoints
checkpoint save serialises the whole runtime state with JsonEx and keeps it in memory. checkpoint load restores
it and returns to the map scene; it replaces the runtime state wholesale, so plugin logic that normally runs when the
player loads from the menu is bypassed. This is ideal for retrying a room or a choice, but it is not a save slot: it
dies with the game process and never appears in the game's load menu.
Uninstall
To remove the bridge from a game:
Delete
www/js/plugins/MV_AI_Bridge.js.Remove the
MV_AI_Bridgeentry fromwww/js/plugins.js, or restorewww/js/plugins.js.mv-ai-bridge.bakover it.Optionally delete
~/.mv-ai-bridge/to remove the token, session file and notes.
Steam's "Verify integrity of game files" may restore plugins.js, which also removes the entry. Check the game's
licence first: some commercial titles do not permit modifying their files.
Security
The bridge listens on
127.0.0.1unless you pass--host. Do not expose it to a network you do not control./mcpand/healthrequire the bearer token from~/.mv-ai-bridge/token. Delete the file to rotate it.The game plugin connects outwards to the bridge; no inbound port on the game side.
Only one write action runs at a time, so an agent cannot interleave two movement routines.
Development
npm run build
npm test # mock game on a random port, no real game needed
node test/live.js observe '{}' # one-shot call against a running bridgetest/live.js reads ~/.mv-ai-bridge/session.json and calls a single tool; it is a manual tool, not part of npm test.
Tested against RPG Maker MV 1.6.1 on two projects: a commercial Japanese title with 127 plugin files of its own, with the bridge
registered last in plugins.js (custom message, battle and menu systems), and a Chinese fan game. Live sessions covered map movement and
pathfinding, dialogue and choices, menus, and the event log. The battle tools have only been exercised against the
mock game in npm test; a live battle is still pending, so treat battle support as protocol-tested, not play-tested.
npm test covers the bridge protocol against a mock game.
Known limitations
Plugins that replace, not wrap. The plugin must load last. It virtualises input by writing
Input._currentStateand hooksSceneManager.updateMain/SceneManager.updateScene; a plugin that replaces those symbols wholesale instead of calling the previous implementation can break movement or freezing.Project layout.
installexpectswww/js/plugins.jspluswww/js/plugins/. Games whose runtime sits at the root (js/,data/besideGame.exe), or that are packed with Enigma or similar protection, need a manual plugin copy and a manualplugins.jsentry.One game per bridge. A bridge process serves one game connection at a time. To drive a second game at the same time, install that game with a different
--portand run a second bridge on that port.PC only. NW.js desktop builds are supported. Mobile, Cordova and browser deployments are not.
Battle plugins that bypass the window layer. The battle tools drive the stock command windows. A battle plugin with its own input flow can degrade them; use
inputfor screens it does not model.Checkpoints are memory-only. They live in the running process, never appear in the load menu and disappear when the game closes.
License
MIT. See LICENSE.
This server cannot be deployed
Maintenance
Related MCP Connectors
AI game assets for agents: consistent sprites, 2D animations, tiles, maps, music and engine exports.
Deterministic reasoning stack for AI agents: simulate, decide & compute, plus cross-domain tools.
Persistent memory, hybrid search and a goal graph for AI agents, over stdio or remote HTTP.
Games for AI agents. Each game runs inside a single context window.
Related MCP Servers
- AlicenseBqualityDmaintenanceEnables AI agents to directly manipulate RPG Maker MZ projects through natural language commands, allowing creation and modification of game assets like items, weapons, enemies, maps, and plugins without manually editing game files.36126 npm2MIT
- AlicenseCqualityDmaintenanceEnables AI models to develop and automate RPG Maker MZ projects by creating maps, events, and plugins through natural language commands. It provides comprehensive tools for database management, asset integrity checks, and direct map tile manipulation.287 npm1ISC
- AlicenseBqualityAmaintenanceEnables AI assistants to act as co-developers for RPG Maker MV projects, providing full database CRUD, map and event editing, plugin management, playtest control, and automatic backups.7835 npm5MIT
- AlicenseCqualityDmaintenanceProvides tools for managing RPG Maker MZ game data, maps, events, and system settings through natural language, enabling AI-assisted game development.35126 npm32MIT