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:
- Copy JSON Config — an
mcpServersentry, the JSON most MCP clients read. Paste it into your client's MCP configuration. - Copy for Other Clients — the command, arguments and environment as separate fields, for clients that configure a stdio server field by field.
- Copy Claude Code Command — the same server as one
claude mcp addcommand, for registering it from a terminal with Claude Code.
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:
dry_runoncreate_entity,update_entity,save_custom_rowsandrename_entityreports what would happen — including validation results — without touching disk.- Schema errors are refused.
create_entity,update_entityandsave_custom_rowsvalidate the result in memory first. If what is being written has aSCHEMAerror of its own, the tool returnswritten: falsewith the issues and nothing on disk changes. Other issues, such as aREFto an id that doesn't exist yet, don't block the write. - Every result carries the project's issues. After a write the tools re-run
the project validator and return the issues, so the agent sees the
consequences of its edit in the same turn and can fix its own
REFerrors.
A typical agent loop
Batch-importing entities from an outline (or a Notion database, a spreadsheet, anywhere):
generate_idfor each name, with collision checking on.entity_exists→ decide create vs. update.create_entity/update_entitywith the mapped fields,dry_runfirst if the mapping is new.- One final
validate_projectto 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.