Skip to main content
Glama

worldanvil-mcp-server

MCP server for World Anvil: browse, search, and manage a world's content, and export a complete copy for migrations or backups. 18 focused tools.

Unofficial community project, not affiliated with World Anvil. Requires Node 18+.

Tools

Group

Tools

Navigate

list_worlds, get_world, get_identity, list_categories

Articles

list_articles (all pages, category/type filters), search_articles (title/slug/tags), get_article (full BBCode content + template fields)

Assets

list_assets (secrets, maps, timelines, histories, notebooks, subscribergroups), get_asset (maps/notebooks include their full hierarchy)

Search

search_content (full-text across articles, secrets, notes), find_references (backlinks to an article)

Export

export_world (raw JSON tree + image binaries + id→slug index, to disk)

Write

create_article (defaults private+draft), update_article, delete_article, create_category, update_category, delete_category

Related MCP server: wow-casc-mcp-server

Setup

npm install
npm run build

Credentials

Both from worldanvil.com → profile picture → User API Tokens:

  • WA_AUTH_TOKEN — your personal API token

  • WA_APPLICATION_KEY — via the Application Key Form on the same page (manually approved by World Anvil).

Alternatively, WA_API_BASE_URL can point at a proxy that injects an application key (instead of WA_APPLICATION_KEY). Only use a proxy you run or trust — your auth token, which grants full API access to your account, transits it on every request.

Claude Code

claude mcp add --scope user worldanvil \
  -e WA_AUTH_TOKEN=your-token \
  -e WA_APPLICATION_KEY=your-app-key \
  -- node /absolute/path/to/worldanvil-mcp/dist/index.js

Claude Desktop

Add to the config file (macOS: ~/Library/Application Support/Claude/claude_desktop_config.json, Windows: %APPDATA%\Claude\claude_desktop_config.json):

"worldanvil": {
  "command": "node",
  "args": ["/absolute/path/to/worldanvil-mcp/dist/index.js"],
  "env": {
    "WA_AUTH_TOKEN": "your-token",
    "WA_APPLICATION_KEY": "your-app-key"
  }
}

Behavior worth knowing

  • Content search uses a local cache. The first search_content/find_references call on a world fetches every article body (about a minute for a few hundred articles); after that, every call re-syncs only what changed. The cache lives in ~/.cache/worldanvil-mcp/ (%LOCALAPPDATA%\worldanvil-mcp\cache on Windows), is only a search index, and is safe to delete — it rebuilds itself.

  • Article content is World Anvil BBCode. Links between entities appear as @[Title](type:uuid) mentions; find_references searches for the uuid, so backlinks are exact.

  • Exports are raw and honest. export_world writes untouched API payloads, one file per entity, plus entities.json (id → {kind, title, slug, file}) for rewriting mention links during a migration. Anything it could not fetch or resolve is listed in manifest.json — never silently dropped. It refuses to write into a directory that isn't empty or a previous export.

  • Upstream API limitations (World Anvil's side, all surfaced in tool output): image endpoints currently return errors, so embedded [img:id] references may be unresolvable; marker listings on private maps return 403 even for the map's owner (set a map public temporarily to read its markers); article comments are not exposed by the API at all.

Development

npm run dev                             # run from source
node scripts/smoke.mjs                  # MCP handshake + tool list
node scripts/smoke.mjs <tool> '<json>'  # call one tool (WA_* env vars required)

Available Tools

18 tools
create_articleCreate articleA

Create a new article in a world. Content is World Anvil BBCode ([h1]..[/h1], [b], [url], @Title mentions). New articles default to private+draft so you can review before publishing (pass state='public' and is_draft=false to publish immediately).

Inputs: title (required), world_id (required), tags, state, +5 more.

create_categoryCreate categoryA

Create a category (folder) in a world, optionally nested under a parent category.

Inputs: title (required), world_id (required), parent_id, extra_fields.

delete_articleDelete articleA

PERMANENTLY delete an article. This is irreversible — World Anvil has no trash bin for articles. Confirm with the user before deleting anything they didn't explicitly name.

Inputs: article_id (required).

delete_categoryDelete categoryA

PERMANENTLY delete a category (irreversible). Articles inside are NOT deleted — they become uncategorized. Confirm with the user first.

Inputs: category_id (required).

export_worldExport entire world to diskA

Clone a COMPLETE world to a local directory as raw full-granularity JSON — articles, categories, secrets, map hierarchies (layers/groups/markers), timelines, histories, notebooks+notes, subscriber groups, world meta — plus downloaded image binaries and an entities.json id→{title,slug,file} index for rewriting @mention links during migration. Makes hundreds of API calls; takes minutes on a large world. Returns a summary; data goes to disk, NOT into context — read specific exported files afterwards if needed. Refuses to write into a non-empty directory that isn't a previous export. Requires an absolute output path.

Inputs: world_id (required), output_dir (required).

find_referencesFind references (backlinks)A

Find every article, secret or note that LINKS TO a given article. World Anvil stores links as @Title mentions, so this searches cached text for the target's uuid — exact backlinks, no false positives from name coincidences. Use it for questions like 'where is this NPC mentioned?' or before deleting an article. Self-refreshing cache; first call on a world builds it (can take a minute).

Inputs: world_id (required), article_id (required).

get_articleRead articleA

Read one article in full: content (BBCode), sidebar, tags, category, relations, and template-specific fields (a person's dob/ethnicity/organizations, etc.). Content uses World Anvil BBCode; links to other articles appear as @Title mentions — those uuids can be fetched with get_article too, which makes this the way to walk the world's knowledge graph for context.

Inputs: article_id (required).

get_assetRead one assetA

Read a single asset in full. kind=map returns the ASSEMBLED hierarchy (map + layers + marker groups + all markers with their article links — several API calls, worth it: markers are where geography meets lore). kind=notebook returns notebook + sections + notes. secret/timeline/history/subscribergroup return the entity itself. For articles use get_article.

Inputs: id (required), kind (required).

get_identityWho am IA

Return the authenticated World Anvil user (id + username). Use to verify credentials are working.

Inputs: no named parameters.

get_worldGet world detailsA

Full details of one world: description, settings, counts and links. Use list_worlds first to find the world_id.

Inputs: world_id (required).

list_articlesList articlesA

List ALL articles in a world (auto-paginates; nothing is hidden). Every World Anvil entity — NPCs (person), locations, organizations, session reports, plots, myths — is an article with a template type, shown as [type] on each line. Optionally filter by category or template type. For keyword lookups prefer search_articles.

Inputs: world_id (required), type, category_id.

list_assetsList world assetsA

List a world's non-article resources: secrets (GM-only notes), maps, timelines, histories (timeline events), notebooks, or subscribergroups (player visibility groups). Auto-paginates; returns one line per asset with its id. Use get_asset to read one in full. For articles use list_articles instead.

Inputs: kind (required), world_id (required).

list_categoriesList categoriesA

List all categories (folders) of a world. Articles reference these by id in their category= field; use the ids to filter list_articles or to file new articles.

Inputs: world_id (required).

list_worldsList worldsA

List all worlds owned by (or shared with) the authenticated user, with their ids. Usually the first call in a session — most other tools need a world_id from here.

Inputs: no named parameters.

search_articlesSearch articlesA

Find articles in a world by keyword. Case-insensitive match against title, slug and tags. Multiple words must all match. Fast (metadata only) — to search inside article body text use search_content instead. Use get_article on a result id to read content.

Inputs: query (required), world_id (required), type.

search_contentSearch all contentA

Full-text search INSIDE the world's text: article bodies (content, sidebars, footnotes …), GM-only secrets, and notebook notes, returning matches with context snippets. All words must appear in the same entity (case-insensitive). Backed by a local cache that self-refreshes on every call, so results are always current; the very first call on a world builds the cache and can take a minute. For title/tag lookups search_articles is faster.

Inputs: query (required), world_id (required), type.

update_articleUpdate articleA

Update an existing article. Only the fields you provide are changed. NOTE: content is REPLACED wholesale — to edit, get_article first, modify, send back the full body.

Inputs: article_id (required), tags, state, title, +5 more.

update_categoryUpdate categoryA

Rename a category or move it under a different parent. Only provided fields change.

Inputs: category_id (required), title, parent_id, extra_fields.

Tool Schema Changelog

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

Loading tool schema changelog…

    TDQS

    A4.1/5.0

    Scored across 18 tools

    Disambiguation5/5

    Each tool has a clearly distinct purpose: identity, worlds, articles, categories, assets, search (metadata vs full-text), backlinks, and export. The descriptions are explicit about when to use each, with cross-references to avoid ambiguity. No two tools appear to do the same thing.

    Naming Consistency5/5

    All tools follow a consistent verb_noun pattern with snake_case: get_identity, list_worlds, create_article, update_category, search_content, etc. Actions are limited to get, list, search, find, create, update, delete, and export, applied uniformly across resources.

    Tool Count4/5

    18 tools is slightly above the typical well-scoped range, but each tool earns its place given the complexity of World Anvil (articles, categories, assets, search, export). The count feels reasonable for a rich domain, though it edges toward heavy.

    Completeness4/5

    The tool set provides full CRUD for articles and categories, plus read access to all asset types, search capabilities, backlink lookup, and world export. Minor gaps exist: no create/update/delete for assets and no world-level editing, but these are likely outside the server's intended scope.

    Maintenance

    ActivityNo data
    ResponsivenessOutdated data

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      B
      quality
      D
      maintenance
      An MCP server that interfaces with the World Anvil API to facilitate AI-assisted worldbuilding and D\&D campaign management. It allows users to manage articles, maps, and RPG-specific resources like session notes and timelines through natural language.
      1
      1
      BSD 3-Clause
    • F
      license
      Not graded
      quality
      D
      maintenance
      MCP server for managing a writer's bible, a structured and searchable knowledge base of a narrative universe with tools for characters, places, events, and semantic search.
      -