Automated Assistant Game Master - Kimi
AAGM-K puts Kimi Code CLI behind your Foundry GM screen. Locally.
Version 2.0 replaces confirmation gates with rollback points and adds prompt interrupts, internal and external work modes, and complete local session logs.
Two loopback ports. One GM tab. Zero Kimi keys in Foundry.
The module connects a running Foundry world to a Kimi client through a localhost-only Model Context Protocol relay. Model access, authentication, and tool selection stay inside Kimi Code CLI. AAGM-K is the Kimi sibling of AAGM-C, not a plug-in for it.
Test target:
- Foundry VTT 12, build 343
- Pathfinder 1e 11.11
- Node.js 22 or newer
Two pieces. That is it.
- Foundry module: Runs in one GM browser tab, connects to the relay over WebSocket, and executes a controlled handler set.
- Relay: Runs on the same computer, exposes Streamable HTTP MCP to the Kimi client, routes JSON-RPC messages, persists rollback points, and serializes writes.
The relay binds only to loopback addresses. No cloud service can reach it directly.
See Architecture for the full data flow and Migration Inventory for the original-version reconstruction record.
The safety boundary is persistence and scope. Reads run immediately. Every supported Foundry write runs at once while the module records the before state of the documents the write touched, through Foundry document hooks.
- Document and world setting evals, damage, macro restore, and Loot Watchdog restoration each create a rollback point holding the documents the write touched: updates keep their before state, creates keep their id, deletes keep their full data.
foundry_rollbackrolls back to before a selected point, or the newest live one by default: that point and every later live point are undone newest first. Documents the points did not touch are left alone.- Rolling back records what it changed as a new
redopoint, so rolling that point back redoes the work. - A failed write is not undone automatically. The documents it touched before failing still land in a point, and the error names that point.
- The relay and the module both serialize writes, so concurrent workers cannot overlap world changes.
- Side effects that a rollback point cannot reverse are refused.
- Protected database journals are blocked.
- Evaluated results are depth and size capped.
- The relay and WebSocket server refuse non localhost binding.
- One listener owns the chat queue at a time.
- Macro Mirror never deletes files or writes outside its configured root.
- Protected database journals never enter a rollback point and are never restored.
- Session audit logs and rollback points remain local to the repository root.
Rollback points cover documents only: files, and writes made in another window,
are not covered. A rollback is not a database transaction. Each document is
restored and reported on its own; a point where any document failed is marked
partial, never success.
These controls are load bearing. Bypass them and the bridge stops being the bridge.
Copy the contents of module/ into a Foundry module folder named aagm-k:
FoundryVTT/Data/modules/aagm-k/
module.json
lang/
scripts/
Enable AAGM-K: Automated Assistant Game Master - Kimi in the target world.
cd relay
npm installOpen relay/config.json. Replace <YOUR_GM_USER_ID> with the result of game.user.id from the Foundry browser console. Keep the capability set as gm.
Loot Watchdog also requires the Item Piles module and a Rescue Log journal. Before deployment, replace every REPLACE_WITH_RESCUE_LOG_JOURNAL_ID occurrence with that journal's ID. The placeholder appears in the watchdog macro, its handlers, and the relay denylist.
Kimi Code CLI reads MCP servers from mcp.json, not config.toml. Register
the relay at user level in ~/.kimi-code/mcp.json, or at project level in
.kimi-code/mcp.json:
{
"mcpServers": {
"aagm-k": {
"url": "http://127.0.0.1:7899/mcp"
}
}
}An entry with a url and no transport key uses the HTTP transport, which
is what this Streamable HTTP relay speaks. Tools then arrive prefixed, for
example mcp__aagm-k__foundry_ping.
Raise the tool call timeout past the relay's 300 second write bound plus the
25 second poll margin, so 330000 is a safe floor. Set it per server with
toolTimeoutMs in mcp.json, globally with [mcp] tool_timeout_ms in
config.toml, or through the KIMI_MCP_TOOL_TIMEOUT_MS environment
variable. Kimi Code CLI does not document its built in default, so set one
of these explicitly rather than trust it.
Start the listener one of two ways:
- Non interactive:
kimi -p "<listener prompt>". It runs one prompt and, in our testing, edits without asking; it cannot combine with-yor--auto. - Interactive: run
kimi, then paste the prompt fromrelay/LISTENER_PROMPT.md.
AAGM-K intentionally remains localhost only, so hosted or remote Kimi use is outside this build.
Start the relay:
cd relay
npm startExpected output:
[relay] ready - WS on ws://127.0.0.1:7898, MCP on http://127.0.0.1:7899/mcp
In Foundry:
- Enable the AAGM-K bridge in one GM tab.
- Open Configure Settings > AAGM-K Settings and select a mode.
- Leave the bridge disabled in every other tab using the same GM account.
- Run the auto-created Open AAGM-K Chat macro.
- Run AAGM-K Loot Watchdog once to arm it when Item Piles rescue is needed.
In Kimi Code CLI, verify the bridge with foundry_ping.
Use the complete behavior prompt in
relay/LISTENER_PROMPT.md. It requires one stable
listenerId, reads the relay enforced posture at startup, and defines
interrupt, rollback, log, mode, and subagent behavior.
The minimal polling core is:
Generate one listenerId and reuse it on every foundry_get_prompts and
foundry_get_interrupts call. Poll back to back, answer through
foundry_send_reply, and stop on terminate or -33005 listener-occupied.
The MCP call long polls for about 25 seconds, so the client should not add sleeps between calls. Foundry shows Ready to chat while a listener is active.
Internal Foundry chat is the default. /int returns to internal dispatch.
/ext switches to external Kimi work, cancels queued internal prompts, stops
internal subagents, and suspends their replies and writes until /int is
received. foundry_set_interaction_mode provides the same control through MCP.
A follow up sent to a working tab is an interrupt. Kimi Code CLI's background
coder subagents let the listener forward it to that tab's subagent at once,
by resuming the subagent with the follow up, and keep polling, including in
single task internal mode where exactly one subagent must remain active. If
subagent tools are unavailable, the listener serves work synchronously and
checks foundry_get_interrupts at safe checkpoints.
Every supported write creates a point in root Rollback Points, one JSON file
per point under a folder per day; today's points survive a relay restart. The
chat card shows what was captured and the first documents. Use the card's
Rollback button, /rollback [pointId] in the chat, or call
foundry_rollback directly. Active session logs are Markdown files in root
Logs, named as Month day HH.MM.SS.md.
Stop the listener with /exit, /stop, or /quit in the Foundry chat box. The
local relay/.loop-stop file is the emergency stop.
Read tools:
foundry_pingfoundry_query_actorfoundry_query_scenefoundry_query_macrofoundry_query_journalfoundry_query_userfoundry_tail_logsfoundry_rollback_pointsfoundry_session_logsfoundry_read_session_log
Write tools with persisted rollback points:
foundry_evalfoundry_apply_damagefoundry_restore_lootfoundry_mirror_restorefoundry_rollback
Chat and mode tools:
foundry_get_promptsfoundry_get_interruptsfoundry_send_replyfoundry_set_statusfoundry_set_interaction_mode
Rescue and mirror reads:
foundry_loot_pendingfoundry_mirror_backupfoundry_mirror_backups
module/ Foundry VTT module
scripts/bridge.js Settings, module API, dispatch
scripts/ws-client.js WebSocket lifecycle
scripts/chat-macro.js GM chat, mode, and rollback UI
scripts/loot-macro.js Manual Item Piles watchdog
scripts/settings-*.js World mode settings UI
scripts/rollback-recorder.js Hook capture for recorded writes
scripts/handlers/ Foundry command handlers
relay/ Local Node.js relay
index.js Process bootstrap
src/mcp-server.js MCP tools, rollback, and write serialization
src/ws-server.js Bridge authentication
src/dispatcher.js Request routing and notifications
src/prompt-queue.js Long-poll chat queue
src/eval-guard.js Eval classifier
src/world-settings.js Relay-enforced posture
src/rollback-store.js Rollback points and the rollback chain
src/mirror.js Scoped macro backup storage
src/write-queue.js Serialized write lane
src/audit.js Markdown session audit logs
Docs/ Architecture and migration records
cd relay
npm testFoundry runtime acceptance still requires a Foundry VTT 12.343 world running Pathfinder 1e 11.11. Verify the settings form, listener refusal toast, interrupts, interaction mode switching, recorded rollback points, chained and partial rollback, redo, Item Piles hooks, macro restore, and session log retrieval before packaging.
MIT. See LICENSE.
AAGM-K is not affiliated with or endorsed by Moonshot AI, Paizo Inc., Foundry Gaming LLC, or The Forge. Pathfinder, Foundry VTT, and other product names remain the property of their respective owners.