Configuration
Full configuration reference for vx_mdt.
All configuration lives in config/shared/global.lua.
Full Config
return {
exportAllowlist = {},
bridges = {
debug = false,
framework = "",
license = "",
interaction = "",
inventory = "",
properties = "",
billing = "",
prison = "",
garages = "",
radar = "",
camera = "",
voice = "",
},
forensics = {
providerManaged = false,
providers = { "r14-evidence", "framework" },
},
evidence = {
allowStashIdEdit = true,
},
vehicles = {
autoLinkOwner = true,
substringSearch = false,
},
gradeSync = {
enabled = false,
syncOnLogin = true,
syncLive = true,
},
vehicleCache = {
ttlSeconds = 5 * 24 * 60 * 60,
minExpectedEntries = 100,
},
weapons = {
autoRegister = true,
autoLinkOwner = true,
},
bolos = {
autoFlagRadar = true,
syncOnStartup = false,
},
terminal = {
command = true,
keybind = true,
defaultKey = "K",
},
dispatch = {
globalOverlay = true,
overlayKeybind = "F5",
newCallNotifications = true,
panicButton = true,
panicKeybind = "F9",
panicCooldown = 30,
notificationDuration = 8000,
exportAllowlist = {},
maxCallAge = 1800,
maxCalls = 100,
dispatchCompat = "",
dispatchCompatExports = true,
autoExpireAge = 86400,
autoExpireCheckInterval = 60,
autoDetection = {
enabled = true,
events = {
gunshot = {
enabled = true,
cooldown = 15,
priority = 2,
weaponBlacklist = {
"weapon_stungun",
"weapon_flaregun",
"weapon_flare",
"weapon_snowball",
"weapon_ball",
"weapon_firework",
"weapon_fireextinguisher",
"weapon_petrolcan",
"weapon_hazardcan",
},
},
fight = { enabled = true, cooldown = 30, priority = 3 },
carjacking = { enabled = true, cooldown = 20, priority = 1 },
vehicleTheft = { enabled = true, cooldown = 30, priority = 2 },
explosion = { enabled = true, cooldown = 20, priority = 1 },
speeding = { enabled = true, cooldown = 45, speedThreshold = 130, priority = 3 },
},
},
fields = {
plate = true,
vehicleColor = true,
speed = true,
heading = true,
suspect = true,
owner = true,
},
blips = {
enabled = true,
defaultSprite = 161,
defaultColour = 1,
defaultScale = 0.8,
defaultOffset = 0,
defaultRadius = 0,
defaultRadiusColour = nil,
defaultRadiusAlpha = 128,
},
},
radio = {
enabled = true,
canUseRadio = function(srcNetId)
return true
end,
},
jobMasks = {
-- ["scammer"] = "Unemployed",
},
departments = {
["police"] = {
type = "law",
title = "Los Santos Police Department",
shortTitle = "LSPD",
symbol = "#",
accentColor = "#3b82f6",
allowAccessOffDuty = false,
defaultRadioFrequency = 1,
defaultTags = GLOBAL.DEFAULTS.TAGS,
defaultLicenses = GLOBAL.DEFAULTS.LICENSES,
defaultCertificates = GLOBAL.DEFAULTS.CERTIFICATES,
defaultTemplates = GLOBAL.DEFAULTS.TEMPLATES,
defaultUnits = GLOBAL.DEFAULTS.UNITS,
},
["bcso"] = {
type = "law",
title = "Blaine County Sheriff's Office",
shortTitle = "BCSO",
symbol = "$",
accentColor = "#F97316",
allowAccessOffDuty = false,
defaultRadioFrequency = 2,
defaultTags = GLOBAL.DEFAULTS.TAGS,
defaultLicenses = GLOBAL.DEFAULTS.LICENSES,
defaultCertificates = GLOBAL.DEFAULTS.CERTIFICATES,
defaultTemplates = GLOBAL.DEFAULTS.TEMPLATES,
defaultUnits = GLOBAL.DEFAULTS.UNITS,
},
["sahp"] = {
type = "law",
title = "San Andreas Highway Patrol",
shortTitle = "SAHP",
symbol = "%",
accentColor = "#f97316",
allowAccessOffDuty = false,
defaultRadioFrequency = 3,
defaultTags = GLOBAL.DEFAULTS.TAGS,
defaultLicenses = GLOBAL.DEFAULTS.LICENSES,
defaultCertificates = GLOBAL.DEFAULTS.CERTIFICATES,
defaultTemplates = GLOBAL.DEFAULTS.TEMPLATES,
defaultUnits = GLOBAL.DEFAULTS.UNITS,
},
["ambulance"] = {
type = "ems",
title = "Los Santos Medical Services",
shortTitle = "LSMS",
symbol = "+",
accentColor = "#22c55e",
allowAccessOffDuty = false,
defaultRadioFrequency = 4,
defaultTags = GLOBAL.DEFAULTS.TAGS_EMS,
defaultLicenses = GLOBAL.DEFAULTS.LICENSES,
defaultCertificates = GLOBAL.DEFAULTS.CERTIFICATES,
defaultTemplates = GLOBAL.DEFAULTS.TEMPLATES_EMS,
defaultUnits = GLOBAL.DEFAULTS.UNITS_EMS,
defaultMedicalConditionTypes = GLOBAL.DEFAULTS.MEDICAL_CONDITION_TYPES,
},
["judge"] = {
type = "judge",
title = "Department of Justice",
shortTitle = "DOJ",
symbol = "§",
accentColor = "#a855f7",
allowAccessOffDuty = false,
defaultRadioFrequency = 5,
defaultTags = GLOBAL.DEFAULTS.TAGS_JUDICIAL,
defaultLicenses = GLOBAL.DEFAULTS.LICENSES,
defaultCertificates = GLOBAL.DEFAULTS.CERTIFICATES,
defaultTemplates = GLOBAL.DEFAULTS.TEMPLATES_JUDICIAL,
defaultUnits = GLOBAL.DEFAULTS.UNITS_JUDICIAL,
},
},
}Bridges
| Field | Type | Default | Description |
|---|---|---|---|
debug | boolean | false | Print resolver diagnostics for every bridge candidate during startup |
framework | string | "" | Force a specific framework bridge, or "none" to disable. Empty = auto-detect |
license | string | "" | Force a specific license bridge, or "none" to disable. Empty = auto-detect |
interaction | string | "" | Force a specific interaction bridge, or "none" to disable. Empty = auto-detect |
inventory | string | "" | Force a specific inventory bridge, or "none" to disable. Empty = auto-detect |
properties | string | "" | Force a specific properties bridge, or "none" to disable. Empty = auto-detect |
billing | string | "" | Force a specific billing bridge, or "none" to disable. Empty = auto-detect |
prison | string | "" | Force a specific prison bridge, or "none" to disable. Empty = auto-detect |
garages | string | "" | Force a specific garages bridge, or "none" to disable. Empty = auto-detect |
radar | string | "" | Force a specific radar bridge, or "none" to disable. Empty = auto-detect |
camera | string | "" | Force a specific camera bridge, or "none" to disable. Empty = auto-detect |
voice | string | "" | Force a specific voice bridge, or "none" to disable. Empty = auto-detect |
Bridges are auto-detected by default. You only need to set these if you want to force a specific bridge or disable a category with "none". See the Bridges page for supported resources.
Forensics
| Field | Type | Default | Description |
|---|---|---|---|
providerManaged | boolean | false | When true, fingerprint and blood type are read-only in the MDT and fetched from external providers instead |
providers | string[] | { "r14-evidence", "framework" } | Ordered provider list — first provider that returns a value wins |
Available provider values:
"r14-evidence"— reads from r14-evidenceev_identifiers"framework"— uses QB/QBox metadata fallback (aliases:"qb","qbx","qbox")
ESX has no built-in metadata provider for biometrics. ESX servers should only list explicit providers like "r14-evidence".
Export Allowlist
exportAllowlist restricts which resources can call vx_mdt server exports. An empty table means all resources are allowed.
exportAllowlist = { "my-resource", "another-resource" },Evidence
| Field | Type | Default | Description |
|---|---|---|---|
allowStashIdEdit | boolean | true | Allow editing the stash ID field on evidence items in the UI |
Vehicles
| Field | Type | Default | Description |
|---|---|---|---|
autoLinkOwner | boolean | true | Automatically link the vehicle owner's profile when registering a vehicle |
substringSearch | boolean | false | Match vehicle plate/VIN/model searches anywhere in the string instead of only from the start (e.g. "JJJ" matches plate "BM94 JJJ"). Disables index-accelerated prefix matching and may be slower on large databases. |
Grade Sync
Bidirectional synchronization between a player's framework job grade and their MDT rank. Off by default.
| Field | Type | Default | Description |
|---|---|---|---|
enabled | boolean | false | Master toggle. When false, framework grades and MDT ranks stay completely independent. When true, framework grade ↔ MDT rank stay in sync bidirectionally. |
syncOnLogin | boolean | true | Apply inbound sync on player load and every time the MDT terminal is opened. |
syncLive | boolean | true | Apply inbound sync live when the framework grade changes mid-session (boss menu, /setjob, etc.). |
When enabled, ranks gain a Framework Grade field in the rank create/edit modal. Linking a grade activates these behaviours:
- Inbound — when a player's framework grade changes, their MDT rank is updated to match the rank linked to that grade. If the new grade has no linked rank, they fall back to the department's default (lowest priority) rank.
- Outbound — when an admin changes someone's rank in the Roster, the player's framework grade is pushed to match the linked grade. Ranks without a
framework_grademapping skip the push silently. - Job loss — if the framework job changes to unemployed or a non-MDT job, the staff record is set to
inactiveand the terminal is torn down. Existing rehire flow re-onboards them with the default rank if they regain the job.
A 2-second per-source loop guard prevents the outbound push from triggering its own inbound listener. The framework grade dropdown in the rank modal is hidden entirely when enabled = false.
Vehicle Cache
The vehicle label cache stores hash → display label pairs on disk (data/vehicles.json) so the MDT can resolve vehicle model labels without a connected client. The cache auto-populates on the first player connect after boot and persists across restarts.
| Field | Type | Default | Description |
|---|---|---|---|
ttlSeconds | number | 5 * 24 * 60 * 60 | Seconds before the cache is considered stale and auto-refreshed on next player connect. Set to 0 to disable auto-refresh (manual command only). |
minExpectedEntries | number | 100 | Reject refresh results below this many entries as likely client-side failures. GTA V has ~780 vehicles including DLC, so 100 is a safe floor. |
Use the mdt_refresh_vehicle_cache console command to trigger a manual refresh. See the Admin Tools page for details.
Weapons
| Field | Type | Default | Description |
|---|---|---|---|
autoRegister | boolean | true | Automatically register weapons in the MDT when picked up/equipped via the inventory bridge. Disable to require weapons to be created manually (or via the createWeapon export) |
autoLinkOwner | boolean | true | Automatically link the weapon owner's profile when registering a weapon |
BOLOs
| Field | Type | Default | Description |
|---|---|---|---|
autoFlagRadar | boolean | true | Automatically flag/unflag vehicle plates in the radar bridge when BOLOs are created, updated, or cancelled |
syncOnStartup | boolean | false | Re-flag all active BOLO plates in radar on resource start. Disable if your radar script persists flags in its own database |
When autoFlagRadar is enabled and a radar bridge is detected, vehicle plates linked to active BOLOs are automatically flagged in the radar system. Plates are unflagged when a BOLO is cancelled, expired, or deleted — even if the same plate appears in multiple BOLOs, it is only unflagged when no active BOLO references it.
Terminal
| Field | Type | Default | Description |
|---|---|---|---|
command | boolean | true | Enable the /mdt chat command (set false to open only via keybind, item script, or export) |
keybind | boolean | true | Enable the keybind to toggle the MDT (set false to use /mdt command only) |
defaultKey | string | "K" | Default key to toggle the MDT |
Dispatch
| Field | Type | Default | Description |
|---|---|---|---|
globalOverlay | boolean | true | Enable the global dispatch overlay panel (toggled via keybind) |
overlayKeybind | string | "F5" | Keybind to toggle the dispatch overlay |
newCallNotifications | boolean | true | Show popup notifications for new dispatch calls |
panicButton | boolean | true | Enable the panic button keybind |
panicKeybind | string | "F9" | Keybind to send a panic signal |
panicCooldown | number | 30 | Seconds between panic signals |
notificationDuration | number | 8000 | How long dispatch notifications stay visible (ms) |
exportAllowlist | table | {} | Restrict which resources can create dispatch calls via exports (empty = all) |
maxCallAge | number | 1800 | Seconds before inactive calls are eligible for eviction |
maxCalls | number | 100 | Max active calls before oldest are evicted |
dispatchCompat | string | "" | Name of third-party dispatch resource to intercept ("cd_dispatch", "cd_dispatch3d", "ps-dispatch", "rcore_dispatch", "fd_dispatch") |
dispatchCompatExports | boolean | true | Override the third-party dispatch resource's exports so external scripts route into vx_mdt. Disable if the third-party dispatch is still running to avoid duplicate notifications. |
autoExpireAge | number | 86400 | Seconds before completed/expired calls are auto-deleted |
autoExpireCheckInterval | number | 60 | How often (seconds) to check for expired calls |
autoDetection.enabled | boolean | true | Master toggle for auto-detection of game events (shots fired, carjacking, etc.) |
autoDetection.events.<event>.enabled | boolean | true | Enable/disable a specific event type |
autoDetection.events.<event>.cooldown | number | varies | Seconds before the same event can trigger again |
autoDetection.events.<event>.priority | number | varies | Dispatch call priority (1 = highest) |
autoDetection.events.speeding.speedThreshold | number | 130 | Speed in km/h above which a speeding event triggers |
autoDetection.events.gunshot.weaponBlacklist | string[] | see default | Weapon hash names (keys from data/weapons.json) that should NOT trigger a shots-fired call (e.g. stun gun, flare gun, fireworks). Applies to both on-foot and drive-by variants |
fields.plate | boolean | true | Attach vehicle plate as a structured field |
fields.vehicleColor | boolean | true | Attach vehicle color with hex swatch |
fields.speed | boolean | true | Attach vehicle speed (speeding events) |
fields.heading | boolean | true | Attach compass heading |
fields.suspect | boolean | true | Attach suspect sex description |
fields.owner | boolean | true | Look up registered vehicle owner by plate (server-side, cached) |
blips.enabled | boolean | true | Show GTA map blips for active dispatch calls |
blips.defaultSprite | number | 161 | Default GTA blip sprite ID |
blips.defaultColour | number | 1 | Default GTA blip colour ID |
blips.defaultScale | number | 0.8 | Default blip scale on the map |
blips.defaultOffset | number | 0 | Random offset applied to blip position (GTA world units). 0 = exact location. |
blips.defaultRadius | number | 0 | Radius circle overlay size (GTA world units). 0 = no circle. |
blips.defaultRadiusColour | number | nil | nil | Colour for the radius circle. nil falls back to defaultColour. |
blips.defaultRadiusAlpha | number | 128 | Alpha transparency for radius circle (0–255). |
Radio
| Field | Type | Default | Description |
|---|---|---|---|
enabled | boolean | true | Master toggle for all radio integration (auto-tuning, channel guarding) |
canUseRadio | function | nil | returns true | Called before auto-tuning a player. Return true to allow, or false, reason to deny. |
canUseRadio Example
canUseRadio = function(srcNetId)
if not sv_inventory.hasItem(srcNetId, "radio") then
return false, "Please equip a radio."
end
return true
end,Job Masks
Hide a player's real job from other MDT viewers by replacing it with a display label. Useful for illegal or internal jobs you don't want police to discover passively.
| Field | Type | Default | Description |
|---|---|---|---|
jobMasks | table<string, string> | {} | Map of real framework job name → display label shown in the MDT |
jobMasks = {
["scammer"] = "Unemployed",
["cartel"] = "Unemployed",
["lost_mc"] = "Unemployed",
},Masking is applied server-side to search results, profile views, and involved persons in records (reports, incidents, warrants, evidence, vehicles, weapons, BOLOs, properties). Grade is hidden on masked rows — a masked job renders as just the label (e.g. Unemployed), never Unemployed (Boss).
The player's actual framework job is unchanged — only how other MDT users see them is substituted. On-duty checks, speed dial, authorization, and terminal login continue to use the real job.
Departments
Each key in the departments table is a job name that maps to a department definition. Add or remove departments as needed.
| Field | Type | Description |
|---|---|---|
type | "law" | "ems" | "judge" | Determines routing, UI layout, and available features |
title | string | Full display name |
shortTitle | string | Abbreviated name shown in compact UI elements |
symbol | string | Single character shown in UI badges |
accentColor | string | Hex color for department theming |
allowAccessOffDuty | boolean | Allow opening MDT while off duty |
defaultRadioFrequency | number | Radio frequency auto-assigned to officers |
defaultTags | table | Tags seeded on first boot |
defaultLicenses | table | Licenses seeded on first boot |
defaultCertificates | table | Certificates seeded on first boot |
defaultTemplates | table | Report/incident templates seeded on first boot |
defaultUnits | table | Units seeded on first boot |
defaultMedicalConditionTypes | table | Medical condition types seeded on first boot (EMS departments only) |
Defaults (tags, licenses, certificates, templates, units) are only seeded the first time a department is created. Changing them in config after the initial boot has no effect — manage them through the MDT UI instead.