bg3-data-mcp
Query and resolve Baldur's Gate 3 game/mod data, drive the live game for testing, deploy mods, and export to the Larian Toolkit.
Layered data lookup: inspect load order (
bg3_layers), re-index changed layers (bg3_refresh), add/remove mod layers, and resolve stats entries with per-field provenance (bg3_get_entry,bg3_diff,bg3_search,bg3_references).Other game data: localization (
bg3_loca), root templates, progressions, static data (classes, level maps, action resources, feats), spell/passive lists, spell visual kits, similar-spell search, and MultiEffectInfo/effect resources (bg3_effect,bg3_search_effects).Live game via Script Extender: check game/log state, run Lua or console commands, tail the log, compare indexed vs actually-loaded entries, hot-load stats/loca without restarting, and clean up or reset Lua.
Testing in-game: list/script/plan TOML test cases, stage cases in real encounters, verify expectations with PASS/FAIL, run single cases or whole levels, and clean up spawns/statuses; plus XP-based
bg3_level_upandbg3_level_check.Static checks: lint stats and progressions for silently-dropped values, missing references, or bad UUIDs, and compare a layer against what the running game loaded.
Deploy/restart: report environment and mod-manager state, pack and deploy a mod layer, and restart the game into the newest save with an optional deploy.
Toolkit publishing: check where the Toolkit expects the mod, export its editor copy, and diff editor vs game-ready files.
Allows launching and restarting Baldur's Gate 3 via Steam into the newest save, and discovers Steam installations and libraries to locate the game.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@bg3-data-mcp show me the resolved stats for Shout_ActionSurge and which layer set each field"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
bg3-data-mcp
An MCP server (and CLI) for Baldur's Gate 3 modding: layered game-data lookup, static checks that catch what the engine silently ignores, in-game testing through Script Extender, and export to the Larian Toolkit for mod.io publishing. Works natively on Windows or under WSL, finds the game and tools itself, and isn't tied to any one mod.
Layered data: the base game read straight from the installed paks (
Shared→Gustav→GustavX→ hotfixPatch*.pak, via LSLib'sDivine.exe), so it always matches the current patch, plus your mod layers (unpacked folders or.paks) in load order. Every resolved field says which layer set it. Indexed: stats, English localization, root templates, progressions, lists, class descriptions, level maps, action resources, feats, MultiEffectInfos and named.lsfxeffects.Static checks:
bg3_lint_stats(values, functions and fields no shipped content uses - the engine drops them silently - missing references, spells that can't resolve) andbg3_lint_progressions(invalid node UUIDs, dangling lists, stacked choices).Running game (Script Extender): Lua eval, console commands, hot-loading stats without a restart, ground-truth comparison of what the game actually loaded, and a test framework: level up by XP, check a level against its progression, and TOML test cases run as real encounters (docs/TESTING.md).
Deploy and Toolkit: pack/deploy/enable any mod (
bg3_deploy), restart the game into the newest save, and generate or diff the Toolkit's editor copy (docs/TOOLKIT.md).Timing per machine:
bg3_timingkeeps each user's waits in~/.config/bg3-data-mcp/timing.json(orBG3_DATA_TIMING): ascalefor every UI / harness wait withmin_wait/max_waitclamps, and named settings (console polling, checkpoint interval...) each clamped to its own range.calibratemeasures the console and screen-helper round trips on this machine and suggests a scale.
The SQLite index is cached per machine (see Configuration). A layer is rebuilt only when its sources' timestamps or sizes change; rebuilds are atomic, so a failed rebuild keeps serving the previous index.
Not affiliated with Larian Studios. Requires a legal copy of the game; nothing from the game is redistributed - data is read from your own install.
Resolution rules (stats)
The highest-ranked
new entry NAMEamong the active layers wins.using "NAME"(the entry's own name) inherits the previous layer's definition of NAME.using "OTHER"inherits OTHER, resolved across all active layers.No
using: the entry stands alone. A redefinition withoutusingreplaces the earlier one.Every resolved field records the layer and source that set it (e.g.
base/GustavDev,dnd55e).
Related MCP server: DesyncedMCP
Tools
Tool | Purpose |
| layers, load order, source timestamps, counts |
| re-index changed layers ( |
| manage mod layers |
| resolved stats entry: |
| what a layer changes about an entry compared with the layers below |
| find entries by name or field value; |
| everything mentioning a name or GUID (stats, templates, progressions, lists) |
| handle lookup or text search |
| root template resolved through its ParentTemplateId chain |
| class/subclass nodes merged by node UUID |
| spell/passive list by UUID or name |
| a spell's effects, animations, sounds and icon |
| spells like X, with visual kits to borrow |
| a MultiEffectInfo (or effect resource): component VFX names, bones, duration, looping, |
| find effects by name, every word in any order ("necrotic beam") -> GUIDs ready for |
| fingerprint every vanilla |
| compare two effects component by component, float noise ignored: colours, timing, other properties, added/removed parts |
| trace a mod's effects to vanilla through component IDs (they survive copying): copy, recolour, recolour + edits, combined, new; non-vanilla assets; |
| recolour vanilla effects per |
| stats |
| kill the game, deploy, relaunch via Steam and wait until loaded. Vaults your own campaigns first and arms a watchdog (docs/SAFETY.md); Continues only into a harness save, else loads one from the main menu ( |
| the safe-test-session state: protected campaigns, vaulted versions, the baseline check, the watchdog, past alerts; |
| grant exactly the XP for the next level; compare the host with its class/subclass progressions |
| data-driven in-game test cases (TOML in the mod repo) run as real encounters - scripted, real-roll or AI-driven: see docs/TESTING.md |
| draft TOML test cases from a feature's stats (targets, forced saves/hits, reactions, resource pools, non-overlapping controls), with confidence + TODOs |
| ask the running game which of a layer's icons exist (5,395 known), cache them, and suggest the closest real icon for each missing one; |
| icon pipeline (import keys out the green screen the BG3 icon LoRAs paint on), no Toolkit or texconv: base-game icons out as 380 px PNGs; a mod's |
| pre-checks before writing a test: can the AI cast it, is its save the spell's own roll (interrupt-visible) or a status/surface/passive save; AI-castable spells by save ability |
| static checks before deploying: values the engine silently drops (vocabulary learned from the other layers), tooltip-only names used as functors, missing references, unknown resources, feat prerequisites the engine ignores (only FeatRequirementProficiency / FeatRequirementAbilityGreaterEqual are parsed - a level condition is dropped); deliberate exceptions go in |
| spell-container test coverage: every container with children from the layer needs a case per behaviour group of its children (children differing only by damage type or the spell/status they name share one; |
| Vortex, read-only: what it deployed into the Mods folder (deployment manifest), other paks there, staged mods with several versions of one mod flagged, and its recent install/remove/deploy/purge activity |
| sorts Vortex's enabled BG3 mods into a compatible load order (dependencies from each pak's meta.lsx, then library / standalone / built-on-others / patch tiers, your order kept otherwise); reports missing or disabled dependencies and files two mods both ship; |
| optional, for Vortex users: a small Vortex extension shipped in |
| Vortex users: a dev/test profile kept apart from your play profile. Set |
| which mods each save was made with vs the current load order (renamed/updated/missing mods = the usual "won't load" reason), and rewriting a save's mod list (sync renamed/updated entries by UUID, drop UI-only mods); dry run by default, original backed up to the cache |
| see and drive the game UI (Windows): a screenshot of the game window, OS-level clicks (in screenshot pixels) and key presses, and |
| test characters without playing: a level 1 character of any class from the current host through the game's respec (Withers' |
| newest dependency releases from Nexus through Vortex's own Nexus login (no API key): check, download (Premium direct; free: one click on the page Vortex opens), install, switch versions, deploy, then |
| the mod's class/subclass levels against the RULES (suite |
| run a test build ([[build]] in the suite TOML) hands-free: its start save is loaded, every level is taken with the plan's subclass and the spells its tests need, validated (level_check, and the spell levels the level-up screen offers) and that level's tests run; every 5th level is saved as a checkpoint ( |
| dependency drift: each meta.lsx dependency that is a layer (its deployed pak), declared vs locked ( |
| Larian Toolkit (mod.io publishing): where the Toolkit expects the mod, generate its editor copy (.stats/.tbl) from the game-ready files, and diff the two copies - formats learned from vanilla + dnd55e editor data |
| local release gate ( |
| every stats entry a layer defines vs what the running game loaded (invalid values the engine dropped) |
Install
Works natively on Windows or under WSL; the game, Script Extender and LSLib are Windows programs either way.
Needs uv, Python 3.11+, and LSLib v1.20.4+
(releases; Vortex's bundled divine.exe is too old for current LSF files).
Windows (PowerShell):
git clone <this repo> C:\Mods\bg3-data-mcp
cd C:\Mods\bg3-data-mcp
copy layers.example.json layers.json # then list your mod folders (see below)
uv run python tests\env_check.py # what it found: game, Divine.exe, mod managers, Script Extender
uv run bg3-data refresh # first index build: a few minutes (extracts from the game paks)
claude mcp add bg3-data -- uv run --quiet --directory C:\Mods\bg3-data-mcp bg3-data-mcpWSL: keep the environment on the Linux filesystem (fast), the project anywhere:
export UV_PROJECT_ENVIRONMENT=$HOME/.cache/bg3-data-mcp/venv
cp layers.example.json layers.json # then list your mod folders
uv run python tests/env_check.py && uv run bg3-data refresh
claude mcp add bg3-data -e UV_PROJECT_ENVIRONMENT=$HOME/.cache/bg3-data-mcp/venv -- \
uv run --quiet --directory /mnt/d/path/to/bg3-data-mcp bg3-data-mcpConfiguration (layers.json)
Only your mod layers are required; everything machine-specific is discovered and can be overridden.
Paths may be written Windows-style (D:\\Mods\\MyMod) or WSL-style (/mnt/d/Mods/MyMod) - both work on both.
{
"mods": [
{"name": "dnd55e", "path": "%LOCALAPPDATA%\\Larian Studios\\Baldur's Gate 3\\Mods\\DnD2024_897914ef-5c96-053c-44af-0be823f895fe.pak"},
{"name": "mymod", "path": "C:\\BG3Mods\\MyMod", "tests": "tests/bg3", "deploy": "optional custom command",
"regen": ["bash Scripts/regen_all.sh"]}
],
"base": {"game_data": "E:\\Games\\Baldurs Gate 3\\Data"},
"divine": "C:\\Tools\\LSLib\\Packed\\Tools\\Divine.exe",
"game": {"launcher": "auto", "profile": "Public", "larian_dir": "...", "steam_exe": "...", "game_exe": "..."}
}A dependency (a mod you build on) should be the .pak the game loads - the user Mods folder copy (a mod
manager's symlink is followed), the same pak you would load into the Toolkit - so the index matches the release your
players run. Your own mod is the unpacked folder you edit. bg3_layers lists the pak the game loads per folder
layer and flags one older than the indexed sources.
Setting | Discovered from (when omitted) |
| Steam (registry + every library in |
|
|
|
|
|
|
|
|
mod | none: |
cache |
|
Mod managers
bg3_environment reports what manages the game's Mods folder. Vortex (detected from its deployment
manifest) and BG3 Mod Manager (detected while running) rewrite modsettings.lsx when they deploy or
export a load order, which disables mods they don't manage: re-run bg3_deploy afterwards (it re-enables the
mod after its dependencies), or add your dev mod to the manager. The in-game mod manager lists local paks
under Installed and needs nothing extra.
Script Extender bridge (running game)
These tools talk to the live game through the SE console, using a persistent injector process
(bg3data/ps/se_inject_server.ps1, AttachConsole + WriteConsoleInput, so no window focus is needed; ~0.34 s per
call, with the one-shot se_inject.ps1 as fallback). Output is read back from the current
run's Extender Runtime log. Log file names are UTC; the bridge compares real modification times with
the game's start time.
Tool | Purpose |
| game running? PID and start time, this run's log, latest game state |
| run Lua (server/client); returns the return value as JSON plus printed lines. Runs in your live game. |
| one console line (e.g. |
| tail this run's log |
| ground truth: the entry as the game loaded it vs the index, field by field |
Hot loading (no restart)
Tool | Purpose |
| mirror a mod layer's stats |
| delete the loose |
| console |
SE only reads safe relative paths through the game's file system (absolute paths are rejected by
IsSafeRelativePath), which is why layers are mirrored as loose files. Entries created after startup must
be synced; the tool does that. Hot loading covers stats, loca and Lua. Progressions, lists and templates
load at startup and need a restart with a pak. Stats files with // comments load fine (the lines are skipped).
Measured 2026-09-30: all 661 Apotheosis entries in 3.0 s and 755 loca strings in 2.6 s. The edit → hot-load
one file → re-test loop takes about 3 s. Test-only: don't save while relying on hot-loaded entries.
Each eval is wrapped in unique BEGIN/END markers and pcall, so Lua errors come back as errors rather
than timeouts. SE replaces load() (its second argument must be an environment table). Console access is
serialised. Functor fields (SpellSuccess...) are exposed by SE as parsed userdata and can't be compared
as text. SE reports ComboCategory as empty.
Hardening
Hot reload: tool modules (testing, drafting, lint, icons, deploy, format, parse, ...) are re-imported when their source changes, so MCP code edits apply on the next tool call.
server.py,query,index,sourcesandsehold live state and still need a client reconnect.One SQLite connection shared by MCP worker threads, serialised with a lock (WAL mode).
Every tool catches errors and returns a readable message; free-text inputs are capped at 500 characters (SQLite's LIKE limit),
limitis clamped to 1-500, and output is capped at 24,000 characters.%and_in user text match literally (LIKE ESCAPE).Resolved entries are cached per layer stack; the cache is cleared on any rebuild.
Base extraction goes to a temp directory and is swapped in, so a failed extraction keeps the old cache.
The first call after a game patch rebuilds
base(about 80 s). Runuv run bg3-data refreshafter patches to do it ahead of time.
Tests
uv run python tests/gate_selftest.py: offline checks for the gate and release helpers (build report verdicts, stats/LSX change keys, Version64 math and stamping).uv run python tests/stress_test.pydrives the real server over stdio with the official MCP client: protocol, correct answers, bad input, concurrency (400 calls, 32 at a time), refresh under load,.paklayer add and remove, and a full resolution sweep. It writestests/STRESS_REPORT.md.uv run python tests/ingame_check.py [--layers dnd55e] [--sample 400]compares resolved entries with the running game through SE. The deployed paks must match the layers. It writestests/INGAME_REPORT.md. The first run (2026-09-30) compared 400 entries (200 mod-overridden) and 7,844 fields: 18 mismatches (0.23%). 16 wereComboCategory(SE doesn't expose it) and 2 were one quirk (MULTIATTACKDEFENSE: the game didn't inherit DisplayName through dnd55e'susing). A targeted test of the 72 cases where "override re-parents viausing" and "usingignored on override" predict different values sided with the resolver's model 78:1.
Known limits
SpellAnimationGUIDs are animation slot keys mapped per race and body across about 2,500 content banks, so they aren't resolved to names yet. Copy them between spells as-is.About 0.7% of MultiEffectInfo components point at effect resources outside the indexed banks.
Available Tools
44 toolsbg3_add_mod_layerB
Register a mod layer: an unpacked mod folder (containing Public/ and Mods/) or a .pak file. position: 1-based slot among mod layers (default: on top). The layer is indexed immediately.
Inputs: name (required), path (required), position. Returns: result
bg3_deployA
Pack a mod layer (Mods/ + Public/, via Divine), deploy the pak to the user Mods folder (refused while the game runs; previous pak backed up) and enable it in the active profile's modsettings.lsx after its dependencies. Works for any mod; no per-mod scripts. Re-run after a mod manager rewrites the load order.
Inputs: layer (required), enable. Returns: result
bg3_diffC
What layer changes about stats entry NAME compared with the layers below it.
Inputs: name (required), layer (required), layers. Returns: result
bg3_effectC
Resolve an effect GUID: a MultiEffectInfo (the value of stats *Effect fields) with its component effect resources (names, bones, duration, looping, .lsfx file), or a single effect resource. Also lists the stats entries that use it.
Inputs: guid (required), layers. Returns: result
bg3_environmentB
What this machine looks like to bg3-data: Windows or WSL, the discovered game install (Steam library, GOG or configured), game exe, Divine.exe, the Larian user folder (Mods, modsettings.lsx, Script Extender logs), Script Extender presence, detected mod managers (Vortex, BG3 Mod Manager, in-game) and what they mean for hand-deployed paks, and each mod layer's deploy/enable state.
Inputs: no named parameters. Returns: result
bg3_game_restartA
Kill the game, optionally deploy a mod layer (its layers.json deploy command, else the built-in
bg3_deploy), relaunch (Steam -applaunch, or the game exe for GOG/other installs; --skip-launcher
-continueGame loads the NEWEST save) and wait until a host character is loaded. Unsaved progress is lost.
Inputs: launch, deploy_layer. Returns: result
bg3_get_entryB
Resolve a stats entry (spell, status, passive, character, object, weapon, ...) through inheritance
across the selected layers. Shows the using chain and, per field, the layer/source that set it.
Inputs: name (required), layers, provenance. Returns: result
bg3_ingame_checkB
Compare EVERY stats entry a mod layer defines with what the running game loaded (the engine drops
invalid values silently). layers = what's deployed (default: all).
Inputs: layer (required), layers. Returns: result
bg3_layersA
List data layers in load order with source timestamps and entry counts.
Inputs: no named parameters. Returns: result
bg3_level_checkB
Compare the host with its class/subclass progressions up to its current level: passives added and removed, AddSpells lists (with the spell's source), ActionResource boosts, and this level's choices.
Inputs: layers. Returns: result
bg3_level_upA
Grant the host exactly enough XP (from the layers' XPData) to reach levels more levels. The user
then levels up in the UI, so every feature and spell is class-sourced; follow with bg3_level_check.
Inputs: layers, levels. Returns: result
bg3_lint_progressionsB
Static progression checks for a mod layer: invalid node UUIDs (the game silently drops those nodes), selectors referencing lists no layer defines, and same table+level nodes from different layers (both load, so their choices/feats stack).
Inputs: layer (required), layers. Returns: result
bg3_lint_statsB
Static stats lint for a mod layer, before the game ever loads it: enum values (Cooldown, StatsFunctorContext, RemoveEvents, SpellFlags, TickType...) and functor/condition/boost names that no other layer uses (the engine silently drops what it doesn't know), plus missing referenced entries (statuses, unlocked spells/interrupts, using, containers) and unknown action resources.
Inputs: layer (required), limit, layers. Returns: result
bg3_locaC
Look up a localization handle (e.g. h1a950eaag...), or search localized text.
Inputs: query (required), limit, layers. Returns: result
bg3_progressionC
Progression nodes for a class/subclass (Name, e.g. 'Soulknife', or TableUUID), merged by node UUID so a higher layer's node replaces a lower one's.
Inputs: key (required), level, layers. Returns: result
bg3_referencesC
Everything that mentions token (entry name, status, passive, GUID...) in stats, templates,
progressions and lists.
Inputs: token (required), limit, layers. Returns: result
bg3_refreshA
Re-index layers whose sources changed. force: a layer name, or 'all', to rebuild regardless.
Inputs: force. Returns: result
bg3_remove_mod_layerB
Unregister a mod layer (base cannot be removed).
Inputs: name (required). Returns: result
bg3_searchB
Find stats entries whose name or any field contains text. type: SpellData, StatusData,
PassiveData, Character, Object, Weapon, Armor, InterruptData... field: restrict to one field.
defined_in: only entries that this layer itself defines or overrides (e.g. 'dnd55e' = what dnd55e adds).
Inputs: text (required), type, field, limit, +2 more. Returns: result
bg3_search_effectsA
Find effects by what they're called (e.g. 'Necrotic', 'Impact_BodyFX', 'Radiant_Beam'): MultiEffectInfos whose name, or any component effect's name, matches. Returns the GUID to put in a stats *Effect field, what matched, and sample spells/statuses already using it.
Inputs: text (required), limit, layers. Returns: result
bg3_se_commandB
Send one Script Extender console line to the running game (e.g. '!apofeature Barbarian_PersistentRage')
and return the log lines it produced within wait seconds (max 60).
Inputs: line (required), wait, context. Returns: result
bg3_se_evalA
Run Lua inside the RUNNING game via Script Extender and return its printed output plus the return value (JSON). context: 'server' (game logic, Osi.*, Ext.Stats) or 'client' (UI/visuals). delay: seconds to wait first (e.g. for a cast or boost to resolve). The test harness, once staged, is available as the global BG3T. This executes code in the user's live game session.
Inputs: code (required), delay, context, timeout. Returns: result
bg3_se_hot_cleanA
Remove the loose hot-load folders (Data/Public/BG3DataHot_*) from the game install. Entries already hot-loaded stay in the running session until restart.
Inputs: no named parameters. Returns: result
bg3_se_hot_loadA
HOT-LOAD a mod layer into the RUNNING game without restarting: mirrors its stats .txt files as loose files under /Data/Public/BG3DataHot_/, loads them with Ext.Stats.LoadStatsFile(…, true) (overwriting existing entries), Syncs every entry to the client, and (loca=True) pushes its English strings. files: only these stats files (e.g. ['Passive.txt']). Progressions/lists/templates can't be hot-loaded (restart with a pak). Test-only: don't save the game while relying on hot-loaded entries. Clean up with bg3_se_hot_clean.
Inputs: layer (required), loca, files. Returns: result
bg3_se_live_entryB
Ground truth: compare a stats entry as the running game actually loaded it with the index's
resolution for layers. Pick layers matching what's deployed. Shows each field as MATCH or DIFF.
Inputs: name (required), fields, layers. Returns: result
bg3_se_logB
Tail the current game run's Script Extender runtime log, optionally only lines containing filter
(e.g. '[Apotheosis]', 'error', 'FAILED').
Inputs: lines, filter. Returns: result
bg3_se_reset_luaA
Reload Script Extender Lua (console reset): re-runs every loaded mod's Bootstrap scripts from its
pak/loose files. Only affects mods that were loaded at game start.
Inputs: no named parameters. Returns: result
bg3_se_statusA
Is the game running, which Script Extender log belongs to this run, and the latest game state.
Inputs: no named parameters. Returns: result
bg3_similar_spellsB
Spells matching damage type / school / spell type (Target, Projectile, Shout, Zone...) / level / name keyword, with their visual kits - to borrow effects and animations for new spells.
Inputs: level, limit, layers, school, +3 more. Returns: result
bg3_spell_listC
A spell/passive/skill list by UUID or Name (highest layer wins).
Inputs: key (required), layers. Returns: result
bg3_spell_visualsC
The visual/audio kit of a spell: effects, animations, sounds, icon - for reusing vanilla VFX.
Inputs: name (required), layers. Returns: result
bg3_staticB
Static game data by UUID or Name (highest layer wins): kind = ClassDescription (classes/subclasses, with ProgressionTableUUID), LevelMapSeries (e.g. SuperiorityDie, per-level values), ActionResourceDefinition (resources: MaxValue, ReplenishType), Feat. A partial key lists matches.
Inputs: key (required), kind (required), layers. Returns: result
bg3_templateC
Resolve a root template (MapKey GUID or Name) through its ParentTemplateId chain.
Inputs: key (required), layers. Returns: result
bg3_test_cleanupA
Remove every test spawn, boost (tag BG3Test) and applied status, and stop recording.
Inputs: no named parameters. Returns: result
bg3_test_listC
Test cases a mod layer defines (TOML under /tests/bg3, or layers.json tests), validated
against the index (spells, statuses, templates, aliases).
Inputs: layer (required), level, layers, class_name. Returns: result
bg3_test_planB
The step-by-step plan for a test build ([[build]] in the suite TOML): for every level the exact level-up choices (subclass, which spells, feat), chosen so every spell a test needs is learned by its test level, plus the tests that run there. Written to /docs/test-scripts/plan-.md.
Inputs: build (required), layer (required), layers. Returns: result
bg3_test_runA
Run one auto/script case end to end: stage (real combat, host acts first), scripted cast, verify, cleanup. Effects come from recorded events; costs are checked against the spell's loaded UseCosts (a scripted cast never charges them). player-mode cases need bg3_test_stage + a hotbar cast instead.
Inputs: layer (required), case_id (required), wait, layers. Returns: result
bg3_test_run_levelB
Run every automated case for a level, one after another, and summarise: the cases assigned to
build (see bg3_test_plan), or all of class_name's cases at that level. Lists the player-mode cases
that still need a hotbar cast.
Inputs: layer (required), level (required), wait, build, +2 more. Returns: result
bg3_test_scriptC
Write the human test script (step-by-step reading script per level and case) to /docs/test-scripts/ and return it.
Inputs: layer (required), level, layers, class_name. Returns: result
bg3_test_stageB
Set up one test case in the running game: preconditions (class level, spell learned through the class, not in combat), spawns, HP/status setup, host-first initiative, safety watch, event recorder. mode="script" cases are cast immediately. Then the user acts; finish with bg3_test_verify.
Inputs: layer (required), case_id (required), layers. Returns: result
bg3_test_verifyB
Evaluate the staged case's expectations (before/after snapshots + recorded events), report PASS/FAIL per check with its fidelity, then remove every spawn, test boost and applied status.
Inputs: wait, layers, cleanup. Returns: result
bg3_toolkit_checkB
Compare the mod's Toolkit editor copy (dest='toolkit': /Data/Editor/Mods/; 'repo': /Editor/Mods/) with an export of its game-ready files: missing/extra objects and differing fields per file. Run before publishing; 0 problems = both copies say the same.
Inputs: layer (required), dest, limit. Returns: result
bg3_toolkit_exportA
Generate the Toolkit editor copy (.stats for stats, .tbl for lists/progressions/resources/classes/ level maps/feats) from the mod's game-ready files. Existing editor UUIDs are kept. write=False is a dry run listing files, object counts and warnings; write=True writes them (dest 'toolkit' or 'repo'). Close the Toolkit first: it overwrites files it has open.
Inputs: layer (required), dest, write. Returns: result
bg3_toolkit_statusB
Where the Larian Toolkit expects this mod (Data/Projects, Mods, Public, Editor/Mods): present or missing, linked to the repo or a separate copy, file counts, and the meta.lsx version (mod.io readiness).
Inputs: layer (required). Returns: result
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 44 tools
Many tools are clearly distinct by context (layer management vs. runtime Script Extender vs. toolkit vs. tests), but several pairs overlap: bg3_ingame_check/bg3_se_live_entry both compare indexed vs. loaded data, bg3_search/bg3_search_effects/bg3_references/bg3_static all search different facets, and bg3_get_entry/bg3_diff both resolve entries. Descriptions help, but with 44 tools an agent faces real misselection risk.
All tools use the bg3_ prefix and snake_case, making them predictable and visually cohesive. However, the verb_noun pattern is not strict: many tools are noun-only (bg3_layers, bg3_environment, bg3_static, bg3_progression) while others use verbs (bg3_get_entry, bg3_search_effects), a minor deviation.
At 44 tools, the surface is far above the typical well-scoped range of 3-15 and even beyond the 25+ threshold that the rubric treats as too many. Although BG3 modding is a complex domain, the sheer count—driven by many specialized test, runtime, and toolkit operations—creates a heavy cognitive load and higher likelihood of tool selection errors.
The surface covers a broad lifecycle: layer add/remove/list/refresh, stats and effect search/resolution, runtime Script Extender interaction, hot-loading, automated and scripted testing, linting, toolkit export/check, deployment, and environment discovery. Gaps are minor—for example, there is no direct stats-entry editing or file mutation tool, but the inspection/test/deploy focus appears intentional and workable.
Maintenance
Related MCP Connectors
Savecraft serves real save game data and expert game knowledge to AI assistants.
Connect any AI to your Foundry VTT world: actors, combat, dice, journals, tokens, compendiums.
Connect your AI assistant to Blender for 3D modeling, Geometry Nodes, materials, lighting, animation, rendering and export. Inspect real scenes and viewport images, refine the result and restore checkpoints. OAuth connects your chat to Blender Bridge Desktop on an online Windows 10/11 x64 computer running Blender 4.2+. The chat can run on another device. Requires an active Blender Bridge account; 7-day trial available. AI model access is separate.
D&D and TTRPG campaign manager for GMs: your AI reads and writes a live, typed campaign database.
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceEnables AI assistants to search, browse, and manage mods across Nexus Mods, mod.io, Thunderstore, and Modrinth, as well as perform local diagnostics like detecting games and parsing crash logs.MIT
- AlicenseAqualityCmaintenanceEnables AI assistants to develop Desynced mods by providing direct access to the game's Lua API reference, base-game source, live logs, and installed mods, plus live control via a debugger link for evaluating and reloading Lua in the running game.92MIT
- AlicenseAqualityCmaintenanceEnables AI coding agents to inspect a Mount & Blade II: Bannerlord installation and safely modify it — searching game data, writing and patching module XML with XSLT, handling localization, editing scenes, prefabs and assets, and driving the live Modding Kit editor. Every change is validated against the game's own schemas and journaled with backups.431MIT
- AlicenseBqualityBmaintenanceEnables live Lua evaluation and introspection in Dragon's Dogma 2 through REFramework, along with mod deployment, save/scenario management, and Vortex profile switching for testing.25MIT