Skip to main content
Glama
mcp-rpg-worldstate

mcp-rpg-worldstate

by Eurobertics

MCP RPG Worldstate

A local, system-neutral MCP server that gives an AI game master persistent memory for role-playing worlds. It stores narrative content mostly as free text and structures only what matters for search and consistency: world membership, entity types, locations, scenes, participants, and active states.

Guiding Principle

Persistent or narratively relevant facts are stored – not every transient observation. A broken planetary weather control system can be important; a hairstyle changed by the wind usually is not.

The typical retrieval is deliberately staged:

  1. list_worlds shows existing save states.

  2. get_world_overview provides a compact save preview.

  3. get_current_context loads the immediately playable scene.

  4. search_entities fetches further details only when needed.

Changes can be bundled with apply_world_changes in a single atomic call.

Newly created entities can reference each other within the same call via local references. A compact event and checkpoint archive explains, when needed, how the current state came about without replacing the authoritative world state.

Related MCP server: Librarian

Prerequisites and Installation

  • Node.js 24 or newer (for the built-in SQLite module)

  • npm

npm install
npm run build
npm test

The server uses rpg-worldstate.sqlite in the working directory by default. For a stable, explicit storage location, RPG_WORLDSTATE_DB should be set as an absolute path.

MCP Configuration

A local MCP client can start the server via stdio. The general configuration pattern is:

{
  "mcpServers": {
    "rpg-worldstate": {
      "command": "node",
      "args": [
        "/home/eurobertics/projects/mcp_rpg_worldstate/dist/index.js"
      ],
      "env": {
        "RPG_WORLDSTATE_DB": "/home/eurobertics/projects/mcp_rpg_worldstate/rpg-worldstate.sqlite"
      }
    }
  }
}

The exact location for this configuration depends on the MCP client being used. The server writes log messages exclusively to stderr so that the MCP protocol on stdout stays clean.

Claude Desktop on Windows with Server in WSL

If Claude Desktop runs on Windows but the MCP server is installed inside WSL, Claude can start it via wsl.exe. The configuration is normally located at:

%APPDATA%\Claude\claude_desktop_config.json

Example:

{
  "mcpServers": {
    "rpg-worldstate": {
      "command": "wsl.exe",
      "args": [
        "-d",
        "Ubuntu",
        "--exec",
        "bash",
        "-lc",
        "cd /home/eurobertics/projects/mcp_rpg_worldstate && RPG_WORLDSTATE_DB=/home/eurobertics/projects/mcp_rpg_worldstate/rpg-worldstate.sqlite exec node dist/index.js"
      ]
    }
  }
}

Ubuntu must match the exact name of the WSL distribution being used. PowerShell displays the installed distributions with the following command:

wsl.exe --list --quiet

bash -lc loads a login shell. This is particularly important when Node.js was installed via a version manager such as fnm or nvm. Project and database paths are Linux paths within WSL. The full shell command must remain a single element of args in the JSON configuration.

The startup can be tested directly from PowerShell before configuring Claude:

wsl.exe -d Ubuntu --exec bash -lc "cd /home/eurobertics/projects/mcp_rpg_worldstate && RPG_WORLDSTATE_DB=/home/eurobertics/projects/mcp_rpg_worldstate/rpg-worldstate.sqlite exec node dist/index.js"

On successful startup, stderr shows, for example:

mcp-rpg-worldstate is using /home/eurobertics/projects/mcp_rpg_worldstate/rpg-worldstate.sqlite

The process then remains active and waits for MCP messages via stdin. This is the expected behavior. After changing the configuration file, Claude Desktop must be fully quit and restarted.

ChatGPT note: This configuration uses Claude Desktop's local stdio transport. It cannot be adopted unchanged for ChatGPT Desktop. For that, the server would additionally need to be provided via an HTTP transport supported by ChatGPT and a reachable URL.

Tools

Tool

Purpose

list_worlds

Compact list of all save states

create_world

Create a new isolated world/campaign

update_world

Change the persistent world description or short summary

delete_world

Recursively delete a world including all dependent data

apply_world_changes

Create, change, or delete entities in a batch

search_entities

Search characters, locations, plots, notes, and items

set_current_scene

Compact record of the current scene and participants

get_world_overview

Load a token-efficient save preview

get_current_context

Load the current playable context

create_checkpoint

Save a player-safe recap and optional GM notes

get_recent_events

Read relevant events paginated or since a checkpoint

list_checkpoints

Load older session and chapter states paginated

random_numbers

Neutral random numbers for narrative decisions

Entity types are character, location, plot, note, and item. A character or item can receive a current location via locationId. Locations can be nested with parentId. Scene participation is separate from this: a brief shared scene change does not have to automatically alter all permanent locations.

Local References in a Batch

Create operations can define a ref that is unique within the call. Other changes may use it with locationRef or parentRef, even if the referenced create operation appears later in the array:

{
  "worldId": 1,
  "changes": [
    {
      "action": "create",
      "ref": "mara",
      "kind": "character",
      "name": "Mara",
      "locationRef": "tavern"
    },
    {
      "action": "create",
      "ref": "cellar",
      "kind": "location",
      "name": "Weinkeller",
      "parentRef": "tavern"
    },
    {
      "action": "create",
      "ref": "tavern",
      "kind": "location",
      "name": "Zum hinkenden Drachen"
    }
  ],
  "summary": "Mara und ihr Gasthaus wurden eingeführt."
}

The response contains createdRefs with the generated numeric IDs. Unknown, duplicate, or circular references, as well as the simultaneous specification of, for example, locationId and locationRef, abort the entire transaction.

Events, Secrets, and Checkpoints

A summary in apply_world_changes creates a compact historical event entry. As soon as the batch concerns a secret entity, the summary must be marked as secret with eventSecret: true or omitted. This way, no secret change can accidentally appear in the public event history.

get_recent_events returns events in id DESC order by default, supports beforeId for backward pagination, text search, and sinceCheckpointId. Each checkpoint internally stores the event state at that time, so "What happened since this checkpoint?" can be answered unambiguously.

list_checkpoints also returns older checkpoints newest first and paginates via beforeId.

Player-Safe Checkpoints

Each new checkpoint separates two information channels:

{
  "worldId": 1,
  "title": "Die Nacht im hinkenden Drachen",
  "playerRecap": "Bernd fand im Keller eine königliche Münze. Mara behauptete, sie noch nie gesehen zu haben.",
  "gmNotes": "Mara ist die verschwundene Königin."
}
  • playerRecap is mandatory and intended exclusively for already observed, revealed, or reasonably known facts.

  • gmNotes is optional and always intended exclusively for the game master.

  • Hidden identities, motives, causes, plans, locations, and future developments never belong in playerRecap.

  • When in doubt, information belongs in gmNotes, a secret entity, or a secret event – not in the public recap.

The server does not automatically classify, sanitize, or reformulate content. The calling AI is responsible for correct categorization. Entities and events remain the authoritative source; checkpoints are compact narrative save previews.

get_world_overview and list_checkpoints return exclusively playerRecap by default. gmNotes is only output as a separate field with includeSecrets: true. This option may only be used in an authorized game master context. The server never merges the two texts.

The former summary input for create_checkpoint is no longer accepted. This forces every new client to explicitly create a player-safe recap.

Database Migrations

The schema is versioned via SQLite PRAGMA user_version. On server startup, older databases are automatically migrated to the current state within transactions. Old checkpoint summary contents are conservatively treated as potentially secret: they are moved to gmNotes and publicly replaced only by a neutral notice. An old summary is never automatically published as player knowledge. Nevertheless, a backup of the SQLite file is recommended before a version change.

Optional Codex Skill

Under skills/rpg-worldstate-gm there is a small companion skill with rules for economical loading, relevant state changes, secrets, and checkpoints. It is not required for the MCP server or other clients.

For local installation, the folder can be copied into the personal Codex skill directory:

cp -R skills/rpg-worldstate-gm ~/.codex/skills/

Deletion and Consistency

delete_world requires the exact confirmation DELETE: <world name> for safety. Afterwards, SQLite removes all characters, locations, plots, scenes, checkpoints, and events of that world via foreign key cascades.

Links between different worlds are rejected. Bundled changes run in a transaction: if one change is invalid, none of them are saved.

Development

npm run dev
npm run check
npm test

The most important files are:

  • src/store.ts: SQLite schema, validation, and queries

  • src/server.ts: public MCP tools and input schemas

  • src/index.ts: local stdio entry point

  • src/*.test.ts: database and MCP protocol tests

Available Tools

13 tools
apply_world_changesApply relevant world-state changesA

Create, update or delete several durable entities atomically in one call. Create operations may define local refs used by locationRef or parentRef, including forward references. Store only lasting or story-relevant changes, preferably together at natural story boundaries.

Inputs: changes (required), worldId (required), summary, eventSecret.

create_checkpointCreate save-game checkpointA

Create a checkpoint with strictly separated player-safe recap and optional GM-only notes. The server does not classify or rewrite content; entities and events remain authoritative.

Inputs: title (required), worldId (required), playerRecap (required), gmNotes.

create_worldCreate RPG worldB

Create an isolated RPG world/campaign. Description holds its durable tone, setting, rules and boundaries as free text.

Inputs: name (required), summary, description.

delete_worldPermanently delete RPG worldA
Destructive

Permanently delete a world and all related entities, scenes, checkpoints and events. Requires exact confirmation 'DELETE: '.

Inputs: worldId (required), confirmation (required).

get_current_contextLoad current playable contextA
Read-only

Load world framing plus current scene, its location, characters currently assigned there and active plots. Use after the compact overview when continuing play.

Inputs: worldId (required), includeSecrets.

get_recent_eventsRead recent relevant eventsA
Read-only

Read a compact newest-first history explaining how the authoritative current state developed. Supports backward pagination and events since a checkpoint; do not use it instead of current context.

Inputs: worldId (required), limit, query, beforeId, +2 more.

get_world_overviewLoad compact save previewA
Read-only

Load a token-conscious save preview. The latest checkpoint contains only playerRecap by default; GM notes and other secret records require explicitly authorized secret access.

Inputs: worldId (required), includeSecrets.

list_checkpointsList earlier save checkpointsA
Read-only

List player-safe checkpoint recaps newest first. GM notes remain absent unless includeSecrets is explicitly true in an authorized GM context.

Inputs: worldId (required), limit, beforeId, includeSecrets.

list_worldsList RPG worldsA
Read-only

List compact save-game entries. Use this first in a new chat; it never loads full world data.

Inputs: no named parameters.

random_numbersGenerate neutral random integersA
Read-only

Generate random integers for unbiased narrative decisions. This is not a rules or dice system.

Inputs: max (required), min (required), count.

search_entitiesSearch characters, locations, plots, notes and itemsB
Read-only

Targeted lookup. Supports questions such as all characters in a world, where a character is, or which characters are at a location.

Inputs: worldId (required), kind, name, limit, +4 more.

set_current_sceneSet current story sceneA

Record the compact immediate scene in one operation. Participants describe who is narratively present; this does not move every character permanently.

Inputs: title (required), summary (required), worldId (required), locationId, +1 more.

update_worldUpdate durable world informationB

Update a world's durable framing. Do not record transient narration here.

Inputs: worldId (required), name, summary, description.

Tool Schema Changelog

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

Loading tool schema changelog…

    TDQS

    A3.7/5.0

    Scored across 13 tools

    Disambiguation4/5

    Each tool has a clear, distinct purpose with carefully worded boundaries (e.g., get_current_context vs. get_world_overview vs. get_recent_events). The descriptions are detailed enough that an agent should select correctly, though the overlapping 'get' cluster and create/update endpoints could still cause occasional confusion.

    Naming Consistency4/5

    The server consistently uses a snake_case verb_noun pattern (create_world, update_world, search_entities, set_current_scene) that makes behavior predictable. The one outlier, random_numbers, breaks the verb-first pattern but is still clear and descriptively named.

    Tool Count5/5

    13 tools is well within the ideal range for a domain of this scope. The server covers the full CRUD lifecycle for worlds, plus checkpoints, entities, scenes, and context management without accidental bloat or missing essentials.

    Completeness4/5

    The toolset provides comprehensive coverage of the worldstate domain, including world lifecycle, checkpoints, entity search, scene management, and history navigation. It could be even more complete with granular entity-level operations, but the atomic apply_world_changes and search_entities cover most reasonable workflows.

    Maintenance

    ActivityMaintained
    ResponsivenessOutdated data

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      C
      quality
      B
      maintenance
      Provides persistent, local-first AI memory across sessions via MCP tools for storing, searching, and retrieving context from past interactions.
      31
      668 PyPI
      1
      MIT
    • A
      license
      Not graded
      quality
      C
      maintenance
      Provides AI agents with persistent knowledge storage, enabling them to store, search, and retrieve text, documents, and files using semantic and keyword search via MCP tools.
      33
      Apache 2.0
    • A
      license
      A
      quality
      D
      maintenance
      Provides persistent memory with semantic search for MCP-based AI agents, enabling them to store and recall information across sessions using vector embeddings.
      4
      1
      MIT
    • A
      license
      Not graded
      quality
      B
      maintenance
      Enables AI agents to store and semantically retrieve durable memories across sessions via MCP or REST, with tools for remembering, recalling, asking, updating, and forgetting memories.
      17 npm
      MIT