MCP Hub
Back to servers

foundry-vtt-mcp

A lightweight MCP server that enables direct interaction with FoundryVTT via WebSockets. It allows for advanced document management, world metadata retrieval, and multi-instance switching without requiring custom server-side modules.

Tools
32
Updated
Jan 3, 2026
Validated
Jan 9, 2026

FoundryMCP

A lightweight MCP (Model Context Protocol) server for FoundryVTT that communicates directly via WebSockets.

Why This Server?

Unlike other FoundryVTT MCP servers that require:

  • Installing a custom module on your Foundry server
  • Running a headless browser

This server natively authenticates with FoundryVTT and exchanges WebSocket messages directly using the same protocol as the official Foundry client. This makes it:

  • Lightweight - No browser overhead, just direct WebSocket communication
  • Zero server-side setup - No modules to install on your Foundry instance
  • Secure - Uses the same authentication flow as the official client

Security Recommendation

Create a dedicated FoundryVTT user for each game world you want the MCP server to access. Grant that user only the permissions you want the MCP server to have. This provides:

  • Fine-grained access control
  • Clear audit trail of MCP actions
  • Easy revocation if needed
  • Isolation between different games/worlds

Installation

npm install
npm run build

Configuration

Credentials File

Create a file at config/foundry_credentials.json:

[
  {
    "_id": "my-campaign",
    "hostname": "your-foundry-server.com",
    "userid": "your-user-id",
    "password": "your-password"
  },
  {
    "_id": "test-world",
    "hostname": "test.foundry-server.com",
    "userid": "test-user-id",
    "password": "test-password"
  }
]

Fields:

  • _id - A user-defined identifier for this credential entry (used to switch between instances)
  • hostname - The domain/IP of your FoundryVTT server
  • userid - Your Foundry user document ID (find by inspecting Users in Foundry admin panel)
  • password - Your Foundry user password

You can configure multiple Foundry instances and switch between them at runtime using the choose_foundry_instance tool.

Environment Variable

Override the default credentials path by setting:

export FOUNDRY_CREDENTIALS=/path/to/credentials.json

Usage with MCP Clients

Add to your MCP client configuration:

{
  "mcpServers": {
    "foundry": {
      "command": "node",
      "args": ["/path/to/FoundryMCP/build/server.js"]
    }
  }
}

Or if installed globally:

{
  "mcpServers": {
    "foundry": {
      "command": "foundry-mcp"
    }
  }
}

Available Tools

Document Retrieval (List)

These tools retrieve all documents of a given type from the connected world.

ToolDescription
get_actorsGet all actors (characters, NPCs, etc.)
get_itemsGet all items
get_foldersGet all folders
get_usersGet all users
get_scenesGet all scenes
get_journalsGet all journal entries
get_macrosGet all macros
get_cardsGet all cards
get_playlistsGet all playlists
get_tablesGet all roll tables
get_combatsGet all combats
get_messagesGet all chat messages
get_settingsGet all settings

Parameters:

  • max_length (integer, optional): Maximum response size in bytes. Documents are removed from the response until it fits within this limit.
  • requested_fields (string[], optional): Specific fields to include. Always includes _id and name. If omitted, all fields are returned.
  • where (object, optional): Filter documents by field values. See Filtering with where below.

Document Retrieval (Single)

These tools retrieve a single document by ID or name.

ToolDescription
get_actorGet a specific actor
get_itemGet a specific item
get_folderGet a specific folder
get_userGet a specific user
get_sceneGet a specific scene
get_journalGet a specific journal entry
get_macroGet a specific macro
get_cardGet a specific card
get_playlistGet a specific playlist
get_tableGet a specific roll table
get_combatGet a specific combat
get_messageGet a specific chat message
get_settingGet a specific setting

Parameters (at least one required):

  • id (string): Document ID
  • _id (string): Document ID (alias)
  • name (string): Document name
  • requested_fields (string[], optional): Specific fields to include.

World Metadata

get_world

Get world metadata from FoundryVTT (title, system, version, etc.), excluding document collections like actors or items. Use the get_* document tools for collection data.

Document Manipulation

modify_document

Modify an existing document in FoundryVTT.

Parameters:

  • type (string, required): Document type. Valid types:
    • Core: Actor, Item, Scene, JournalEntry, Folder, User, Playlist, Macro, RollTable, Cards, ChatMessage
    • Scene objects: Combat, Combatant, ActiveEffect, Drawing, MeasuredTemplate, Note, Tile, Token, Wall, AmbientLight, AmbientSound
  • _id (string, required): The document's unique identifier
  • updates (object[], required): Array of update objects with fields to modify

Example - Update actor HP:

{
  "type": "Actor",
  "_id": "abc123",
  "updates": [{ "system": { "attributes": { "hp": { "value": 25 } } } }]
}

create_document

Create new documents in FoundryVTT.

Parameters:

  • type (string, required): Document type to create
  • data (object[], required): Array of document data objects

Example - Create an item:

{
  "type": "Item",
  "data": [{ "name": "Healing Potion", "type": "consumable" }]
}

delete_document

Permanently delete documents from FoundryVTT. This cannot be undone.

Parameters:

  • type (string, required): Document type to delete
  • ids (string[], required): Array of document _id values to delete

Example:

{
  "type": "Item",
  "ids": ["vlcf6AI5FaE9qjgJ", "abc123def456"]
}

Instance Management

show_credentials

Show all configured Foundry credentials without revealing passwords. Returns the _id, hostname, userid, item_order (zero-based index), and currently_active status for each credential entry.

Example response:

[
  {
    "_id": "my-campaign",
    "hostname": "your-foundry-server.com",
    "userid": "abc123",
    "item_order": 0,
    "currently_active": true
  },
  {
    "_id": "test-world",
    "hostname": "test.foundry-server.com",
    "userid": "def456",
    "item_order": 1,
    "currently_active": false
  }
]

choose_foundry_instance

Switch to a different Foundry instance. Disconnects from the current instance (if any) and connects to the specified one.

Parameters (at least one required):

  • item_order (integer): Zero-based index of the credential in the array
  • _id (string): The user-defined identifier for the credential entry

Example - Switch by item_order:

{
  "item_order": 1
}

Example - Switch by _id:

{
  "_id": "test-world"
}

Tips

Understanding Document Structure

Document schemas vary significantly between game systems (D&D 5e, Pathfinder, etc.). Use the get_* tools to inspect existing documents before attempting to modify or create new ones.

Filtering with where

All collection retrieval tools (get_actors, get_items, etc.) support the where parameter for filtering results. The where parameter accepts an object with key-value pairs that documents must match.

How it works:

  • Each key-value pair in where is a condition that must be satisfied
  • All conditions use AND logic - a document must match ALL conditions to be included
  • Values are compared using strict equality

Example - Get actors in a specific folder:

{
  "where": {
    "folder": "abcd1234"
  }
}

Example - Get NPC actors in a specific folder:

{
  "where": {
    "folder": "abcd1234",
    "type": "npc"
  }
}

This returns only actors where folder equals "abcd1234" AND type equals "npc".

Example - Get items of a specific type:

{
  "where": {
    "type": "weapon"
  }
}

Example - Combine with other parameters:

{
  "where": {
    "folder": "abcd1234"
  },
  "requested_fields": ["name", "type", "system.quantity"],
  "max_length": 5000
}

Common filter fields:

  • folder - Filter by folder ID
  • type - Filter by document subtype (e.g., "npc", "character" for actors; "weapon", "armor" for items)
  • ownership - Filter by ownership settings
  • Any top-level field on the document can be used as a filter key

Response Size Management

When working with large worlds, use max_length and requested_fields to limit response sizes:

{
  "max_length": 10000,
  "requested_fields": ["name", "type", "system.attributes.hp"]
}

How It Works

  1. Authentication: The server authenticates with FoundryVTT using the same HTTP POST flow as the official client
  2. WebSocket Connection: Establishes a persistent WebSocket connection using Socket.IO protocol
  3. Message Exchange: Sends and receives JSON messages using Foundry's native protocol
  4. Automatic Reconnection: Handles connection drops and re-authenticates as needed

License

MIT

Reviews

No reviews yet

Sign in to write a review