MCP server by Boyarinov
Deadlock MCP Bridge
Connects Claude Code to the Deadlock game's Lua runtime via the Model Context Protocol.
Quick Start
- Clone this repo and build:
git clone https://github.com/Boyarinov/deadlock-mcp-bridge.git
cd deadlock-mcp-bridge
npm install && npm run build
- Create
.mcp.jsonin the root of the project where you use Claude Code:
{
"mcpServers": {
"deadlock": {
"command": "node",
"args": ["dist/index.js"],
"cwd": "C:/Users/YourName/deadlock-mcp-bridge",
"env": {
"DEADLOCK_SCRIPTS_DIR": "C:/Umbrella/deadlock_scripts"
}
}
}
}
cwd-- absolute path to where you cloned this repo.DEADLOCK_SCRIPTS_DIR-- absolute path to the game'sdeadlock_scripts/folder where the cheat loads.luafiles from.
The bridge script (0_mcp_bridge.lua) is automatically deployed to this folder on startup.
-
Restart Claude Code -- the tools will appear automatically.
-
Launch Deadlock with the cheat loaded -- the bridge connects on its own.
Lua Skill
For best results, install the companion skill: umbrella-deadlock-skill. It teaches Claude the Deadlock Lua API so it writes correct scripts out of the box.
Available MCP Tools
Script Management
| Tool | Description | Parameters |
|--------------------|----------------------------------------------------|-----------------------------------|
| write_script | Write a .lua file to the scripts directory | name (string), content (string) |
| delete_script | Delete a .lua file from the scripts directory | name (string) |
| list_scripts | List all .lua files in the scripts directory | -- |
| read_script | Read the content of a .lua file | name (string) |
Script names are validated to alphanumeric and underscore only. The .lua
extension is appended automatically.
Bridge Interaction
| Tool | Description | Parameters |
|--------------------|----------------------------------------------------|-----------------------------------|
| reload_scripts | Trigger a full script reload in the game runtime | -- |
| execute_lua | Execute a Lua snippet in-game and return the result| code (string) |
| get_game_state | Query game state: players, local_player, time| query (string) |
| get_bridge_status| Check if the game is alive and bridge is connected | -- |
| get_hero_abilities| Get detailed ability info for the currently played hero (names, descriptions, VData, projectile, properties, SDK class) | -- |
| get_logs | Retrieve collected print() output from the game | clear (boolean, optional) |
SDK Lookup
| Tool | Description | Parameters |
|--------------------|----------------------------------------------------|-----------------------------------|
| lookup_class | Look up SDK class fields by exact name | name (string) |
| lookup_enum | Look up SDK enum values by exact name | name (string) |
| search_sdk | Search classes and enums by substring | query (string) |
VData Ability Lookup
| Tool | Description | Parameters |
|------------------------|----------------------------------------------------|---------------------|
| get_ability_properties | Get all m_mapAbilityProperties (base values, scale types, units) | name (string) |
| get_ability_upgrades | Get m_vecAbilityUpgrades (per-tier property bonuses) | name (string) |
| search_abilities | Search ability names by substring | query (string) |
The VData tools load data/abilities.vdata (a KV3 dump of all ability definitions).
Use search_abilities to find the exact internal name, then query properties or upgrades.
The SDK tools load data/dump.json (a Source 2 schema dump with ~5500 classes
and ~740 enums). The data is loaded lazily on first use.
lookup_class resolves the full inheritance chain. For example,
C_CitadelPlayerPawn returns fields from all 9 levels of its hierarchy. Each
field is annotated with an access mode:
| Access | Meaning | Lua usage |
|-----------|------------------------------------------------------------|----------------------------------------|
| value | Primitive type, directly readable | ent.m_iHealth |
| nested | Embedded struct, returns a lua_raw_ptr_t sub-object | ent.m_CCitadelHeroComponent.m_nLevel |
| pointer | Pointer to another object | ent.m_pMovementServices.m_flSpeed |
| enum | Integer enum value | ent.m_lifeState |
| array | Fixed-size array (not directly iterable from Lua) | -- |
| bitfield| Bit-packed flags within a larger integer | -- |
| unknown | Type not recognized as a primitive, class, or enum | -- |
Environment Variables
| Variable | Required | Default | Description |
|-----------------------|----------|---------|--------------------------------------------|
| DEADLOCK_SCRIPTS_DIR| Yes | -- | Absolute path to the deadlock_scripts/ directory |
| BRIDGE_PORT | No | 3000 | Port for the HTTP server the Lua bridge connects to |
| COMMAND_TIMEOUT | No | 10000 | Timeout in ms before a queued command is considered failed |
Troubleshooting
Bridge not connecting (get_bridge_status returns connected: false):
- Verify the game is running and the cheat is loaded
- Check that
0_mcp_bridge.luais present in your scripts directory (auto-deployed on startup -- if missing, check write permissions) - Check that port 3000 (or your
BRIDGE_PORT) is not blocked or in use
Command timeout (tools return errors after ~10s):
- The game may be on a loading screen where
on_framedoes not fire - The bridge script may have crashed -- check game console output
- Increase
COMMAND_TIMEOUTif the game is under heavy load