MCP server

@parlance/mcp exposes a Parlance project to LLM agents over the Model Context Protocol — a stdio process, no web server, no accounts. Agents write through the same storage path as the editor: canonically serialized JSON, with locked writes to the shared registry files. Every write is validated before anything touches disk. A write that would give the entity a schema error is refused and nothing is written; reference and other cross-entity issues are reported with the result, as the editor reports them, but don't block the write.

Get the server

The MCP server ships inside the desktop app — there is nothing else to install, and no separate Node.js: it runs on the app's own runtime. (It is not published to npm.)

With a project open, choose Help ▸ Connect an AI Agent…. The dialog shows the configuration for this install and this project, ready to paste, with buttons that copy it:

If no project is open, the dialog still works, and says that PARLANCE_ROOT is a placeholder for you to fill in.

Setup

Any MCP client that can launch a stdio server can run it. The config the dialog gives you has this shape — the app's own executable run as Node (ELECTRON_RUN_AS_NODE=1), with the bundled server as its argument:

{
  "mcpServers": {
    "parlance": {
      "command": "/Applications/Parlance.app/Contents/MacOS/Parlance",
      "args": ["/Applications/Parlance.app/Contents/Resources/mcp/parlance-mcp.mjs"],
      "env": {
        "ELECTRON_RUN_AS_NODE": "1",
        "PARLANCE_ROOT": "/path/to/your/project"
      }
    }
  }
}

Clients that read an mcpServers block take this entry as-is. For a client you configure through a form, use the same three fields: command is the executable, args is the path to parlance-mcp.mjs, and env sets ELECTRON_RUN_AS_NODE=1 and PARLANCE_ROOT. Where your client keeps that configuration is up to the client; check its own documentation.

For example, Claude Code registers the same server from a terminal:

claude mcp add \
  --env ELECTRON_RUN_AS_NODE=1 --env PARLANCE_ROOT=/path/to/your/project \
  parlance -- /Applications/Parlance.app/Contents/MacOS/Parlance \
  /Applications/Parlance.app/Contents/Resources/mcp/parlance-mcp.mjs

On Windows the command is Parlance.exe and the server is under its resources\mcp\ folder; on Linux, /opt/Parlance/parlance-desktop and /opt/Parlance/resources/mcp/ for the .deb. Copy the paths from the dialog rather than typing them: they are exact for your install. If you run the AppImage, the command is the .AppImage file itself and the server is copied to Parlance's settings folder, because the AppImage's own files only exist while it is running. The paths point into the app, so after moving or reinstalling Parlance, copy the config again.

The paths are specific to one machine, so a config file with them is a poor fit for committing to a shared repository; each writer takes theirs from their own dialog.

PARLANCE_ROOT is the project root: the directory that holds data/ or parlance.config.json (root resolution). Without it the server uses the directory it was started in. The root is read once, when the server starts.

Tools

Tool What it does
list_entities List all entities of a type (skills, variables, factions, characters, dialogues, quests, locations, endings, codex, items, portraits, cutscenes, routes, snapshots)
get_entity Full JSON for one entity by type + id
entity_exists Existence check — decide create vs. update before writing
generate_id Convert a human-readable name to a canonical id per the naming standards (with optional collision checking)
validate_project Run the full validator, return every issue
create_entity Write a new entity (id generated from name if omitted); refused if the entity fails its schema; supports dry_run
update_entity Shallow merge patch on an existing entity (each top-level field in the patch replaces that field); refused if the result fails its schema, or if base_hash is stale; supports dry_run
rename_entity Change an entity's id and rewrite every reference to it, as the editor's Rename id does. A quest stage or outcome is renamed within its quest with type questStages / questOutcomes and id <quest>/<stage>. dry_run returns the plan and a plan_hash; applying with that hash is refused if the project changed in between
list_custom_types The project's custom types: fields, storage and row counts
get_custom_rows A custom type's rows, each with the hash needed to change it; pages through large tables
save_custom_rows Create, replace or delete custom rows in one write — all land or none do. A row changed on disk since it was read, or a row that fails its type's fields, refuses the whole batch; supports dry_run
declare_custom_type Declare, redefine or delete a custom type, checked as the editor's Fields panel checks it; renaming a field rewrites every row

Three behaviors are the safety story:

A typical agent loop

Batch-importing entities from an outline (or a Notion database, a spreadsheet, anywhere):

  1. generate_id for each name, with collision checking on.
  2. entity_exists → decide create vs. update.
  3. create_entity / update_entity with the mapped fields, dry_run first if the mapping is new.
  4. One final validate_project to confirm a clean state.

Because everything lands as canonical JSON in git, the agent's whole session is one reviewable diff — you read what it did in a pull request, comment, and revert cleanly if the tone is off. Combined with in-editor AI drafting, this is Parlance's answer to AI-assisted writing: agents propose through validated channels, humans keep the merge button.