A Model Context Protocol (MCP) server that integrates with FoundryVTT, allowing AI assistants to interact with your tabletop gaming sessions through natural language.
- Dice Rolling — standard RPG notation with any formula
- Data Querying — search and inspect actors, items, scenes, journals
- Game State — combat tracking, chat messages, user presence
- Content Generation — NPCs, loot tables, rule lookups
- World Search — full-text search across all game entities
- Live Connection — Socket.IO loads complete world state on connect
- MCP Resources —
foundry://URIs for direct data access - Diagnostics — optional server health monitoring (requires REST API module)
- Node.js 18+ (or Bun)
- FoundryVTT server running with an active world
- MCP-compatible AI client (Claude Desktop, Claude Code, VS Code, etc.)
It is recommended to create a separate FoundryVTT user account for the MCP server rather than using your own GM or player account. This provides better security and auditability.
In FoundryVTT:
- Go to Configuration → User Management
- Click Create User
- Set a username (e.g.,
mcp-api) and a strong password - Assign the Assistant GM role (needed to read world data and roll dice)
- Use this account's credentials in your MCP configuration
Benefits:
- Chat messages and actions from the MCP server are clearly attributed to a separate user
- You can revoke access by disabling the API user without affecting your own account
- Limits blast radius if credentials are ever exposed
Run directly without installing — no clone needed:
bunx foundryvtt-mcpOr with npx:
npx -y foundryvtt-mcpAdd to your MCP configuration (claude_desktop_config.json or .mcp.json):
{
"mcpServers": {
"foundryvtt": {
"command": "bunx",
"args": ["foundryvtt-mcp"],
"env": {
"FOUNDRY_URL": "http://localhost:30000",
"FOUNDRY_USERNAME": "your_username",
"FOUNDRY_PASSWORD": "your_password"
}
}
}
}Add to your VS Code MCP settings:
{
"servers": {
"foundryvtt": {
"command": "bunx",
"args": ["foundryvtt-mcp"],
"env": {
"FOUNDRY_URL": "http://localhost:30000",
"FOUNDRY_USERNAME": "your_username",
"FOUNDRY_PASSWORD": "your_password"
}
}
}
}For local development or contributing:
git clone https://github.com/laurigates/foundryvtt-mcp.git
cd foundryvtt-mcp
bun install
bun run setup-wizardThe setup wizard will detect your FoundryVTT server, test connectivity, and generate your .env configuration.
To configure manually, see the Configuration Guide.
| Variable | Required | Description |
|---|---|---|
FOUNDRY_URL |
Yes | FoundryVTT server URL (e.g., http://localhost:30000) |
FOUNDRY_USERNAME |
Yes | FoundryVTT user account |
FOUNDRY_PASSWORD |
Yes | FoundryVTT user password |
FOUNDRY_USER_ID |
No | Bypass username-to-ID resolution |
FOUNDRY_API_KEY |
No | REST API module key (enables diagnostics tools) |
FOUNDRY_WRITE_ENABLED |
No | Enable game-state mutations — true required for the write tools (default: false) |
LOG_LEVEL |
No | debug, info, warn, or error (default: info) |
FOUNDRY_TIMEOUT |
No | Request timeout in ms (default: 10000) |
Ask your AI assistant things like:
- "Roll 1d20+5 for an attack roll"
- "Show me all the NPCs in this scene"
- "What's the current combat initiative order?"
- "Search the world for anything related to dragons"
- "Generate a random NPC merchant"
search_actors— find characters, NPCs, monstersget_actor_details— detailed character informationsearch_items— find equipment, spells, consumablesget_scene_info— current scene detailssearch_journals— search notes and handoutsget_journal— retrieve a specific journal entryget_users— list users, roles, and live online statusget_combat_state— combat state and initiative orderget_chat_messages— recent chat history
Game-state mutations are disabled by default. They use the Socket.IO
modifyDocument protocol over an authenticated session, and the connected user
needs GM/owner permission. Set FOUNDRY_WRITE_ENABLED=true to enable them.
start_combat— begin a new encounter, seeding combatants from tokens (does not check for an existing combat — calling it during an active one creates a second encounter)next_turn— advance the active combat to the next turn (wraps to the next round)end_combat— end (delete) the active combat encounterset_initiative— set a combatant's initiative in the active combat, moving the turn marker with the acting combatant if the reorder shifts themmove_token— move a token to new x/y coordinates on its sceneapply_status_effect— apply or remove a status condition (e.g. prone, stunned) on a token's actorupdate_actor_attributes— patch an actor'ssystemattributes (HP, currency, spell slots, …)create_actor_item— add an inline item to an actorupdate_actor_item— apply a JSON merge patch to an actor's itemdelete_actor_item— remove an item from an actorcreate_journal_entry— create a journal entry with one or more text pages (GM-only by default; passvisibilityto let players read it)
search_world— full-text search across all game entitiesget_world_summary— overview of the current world staterefresh_world_data— reload world data from FoundryVTT; needed after a dropped connection, whose missed updates are never replayed into the cache
roll_dice— roll dice; dice terms (NdS) and whole numbers joined by+/-, with unsupported notation (4d6kh3,1d20r1,*) rejected rather than dropped. Parentheses are the one transport difference: FoundryVTT evaluates them whenFOUNDRY_API_KEYis set, the local roller rejects them otherwiselookup_rule— stub: returns a templated placeholder, consults no rules source
generate_npc— generate NPC text (not written to the world)generate_loot— generate treasure text for a level (not written to the world)
get_recent_logs— retrieve filtered FoundryVTT logssearch_logs— search logs by pattern, listing the matching entriesget_system_health— server health status with versions, user/module counts, memory and log error counts (no CPU or disk metrics)diagnose_errors— stub: returns a fixed "no errors detected" summaryget_health_status— comprehensive health diagnostics; flags the world snapshot when the cache has stopped following live changes
foundry://actors— all actors in the worldfoundry://items— all items in the worldfoundry://scenes— all scenesfoundry://scenes/current— current active scenefoundry://journals— all journal entriesfoundry://users— online usersfoundry://combat— active combat state;combatantsare in initiative order, socombat.turnindexes them directlyfoundry://world/settings— world and campaign settingsfoundry://system/diagnostics— system diagnostics (requires REST API module)
The connectivity and setup helpers ship in the source tree (not the published bin), so run them from a dev checkout:
git clone https://github.com/laurigates/foundryvtt-mcp.git
cd foundryvtt-mcp && bun install
bun run test-connection # Probe FoundryVTT connectivity
bun run setup-wizard # Re-run interactive setupDetailed guide: TROUBLESHOOTING.md
bun run build # Compile TypeScript and make dist/index.js executable
bun run dev # Development mode with hot reload
bun test # Unit tests (Vitest)
bun run test:e2e # E2E tests (Playwright)
bun run lint # Lint code (Biome)
bun run smoke # Startup smoke test against the local build
bun run smoke:pack # Pack-and-install smoke test (mirrors what npx consumers get)See Development Guide for project structure, adding tools, testing, and building.
See Feature Tracker for completed and planned features.
See CONTRIBUTING.md.
MIT License — see LICENSE for details.
- Issues: GitHub Issues
- Discord: FoundryVTT Discord #api-development
- Docs: FoundryVTT API
- FoundryVTT team for the excellent VTT platform
- Anthropic for the Model Context Protocol
- The tabletop gaming community for inspiration and feedback