dayz-agentic-modding-mcp
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": false
} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| project_openD | – |
| project_statusD | – |
| mod_buildA | Pack this project's mods. Returns a Runs
|
| server_startA | Start the test server and wait for it to be ready. Returns a job id. Two things worth knowing before calling, both observable: It CLEARS THE BRIDGE TRANSPORT first -- the command mailbox and the state
file in the -profiles directory are removed before the server is spawned, so
no world ever starts against a command or a state document left by an
earlier one. Script logs are deliberately left alone; see
clear_bridge_transport for why the two are treated differently. A file that
could not be removed is reported in It REFUSES if the game port is already held, naming the pids holding it. A stand is shared -- one machine, one port, one profile directory -- and booting into a held port produces a server that dies during world load with nothing in its own log to say why. If the holder is a server this session started, the hint says to stop it with server_stop. If it is anyone else's, the refusal identifies it (pid and -mod= tail) and offers stopping it as the caller's own act -- the owner authorised stopping a neighbouring stand that blocks a live run -- but this tool never auto-stops a process it did not start.
Readiness has two independent signals, and the summary always names which
one answered. |
| server_statusA | A quick health read: is the process alive, and is its log actually growing. A hung boot and a slow one both look "alive, no ready line yet" from the
outside -- this project has hit a genuine post-compile server hang before --
so this samples the newest log's size twice, |
| server_stopA | Stop a server this session is responsible for. With no Either way, the pid is checked against the recorded image name before it
is handed to |
| client_compile_checkA | Compile the CLIENT half of the scripts and judge the result. Returns a job id. A server boot never compiles anything behind the client-only guard, so a
broken menu, a broken widget or a broken client-side action passes every
server check and then breaks in front of a player. This runs the diagnostic
client for The client runs against a THROWAWAY -profiles directory inside this job's artifacts, so it never reads or writes the test stand. It also joins nothing: this is a compile pass, not a session. For the live client that connects to the stand -- and for looking at it, acting through it, and judging its .RPT -- the tools are client_start and its siblings, and log_verdict(source="client") reads THIS job's log while client_verdict reads the live client's.
|
| log_verdictA | Judge the newest log for
|
| log_tailD | – |
| job_statusD | – |
| job_waitA | Wait for a job to finish, or until
|
| job_artifactsD | – |
| bridge_buildA | Pack the bridge mod from this repository's own sources. The bridge is the server's own mod, not the project's: one copy serves every project, and it is built UNSIGNED -- no project's signing key is used, and the output folder is kept free of signatures and keys. Building it does not load it. Attaching it stays a profile decision (the job summary prints the two lines to add), because the bridge is an extra pbo in the stand and a run without it has to remain possible. |
| bridge_statusA | Is the bridge inside the running game still ticking? Blocks for up to A stand with no state file at all now costs the FULL window too (measured: 2.07s at the default, 10.05s at the cap), because the reader retries to the deadline rather than giving up on the first miss. If the question is only "is the bridge publishing anything yet" -- the usual one while wiring it up -- pass window=0 and get the same answer in a tenth of a second; a window buys movement, and nothing else. The answers, told apart in this order: no_server nothing is running, so there is nothing to ask. Checked
FIRST and on the process, not on the file: the state
file outlives the server that wrote it, and reading a
leftover snapshot as a live bridge is precisely the lie
this ordering prevents.
stale_command the same, but with a command still sitting in the
mailbox. Its own answer because the remedy is its own:
the command does not expire, it blocks every send, and
a stand booted OUTSIDE these tools would pick it up.
(server_start clears the transport before every boot,
so a server started through these tools will not.)
no_state_file / the server is up but nothing readable came back. Four
outdated_bridge / fixes, so four answers: the mod is not loaded; the mod
invalid_state / predates this server's protocol (no session_id at all);
unreadable_state the document is valid JSON but a named field is wrong
(the answer says which field, what was expected and
what was seen, and it is checked twice a publish
interval apart so a mangled write is never reported as
a schema bug); or it does not parse at all.
alive / restarted a comparison was made. |
| bridge_clearA | Discard whatever command is sitting in the mailbox. The remedy for Its own tool, and never a side effect of asking for status: throwing away a
queued command is a decision, and Refuses when anything suggests the bridge is alive, because a running mod
could claim that command at any moment and destroying live in-flight work
is worse than leaving the wedge. FIRST on the plain fact that a server this
session started is running -- whatever its bridge is or is not publishing,
which matters most for a mod that has not started writing state yet -- and
that refusal costs no probe at all. Otherwise the channel probes for
|
| world_readyA | Wait until the bridge inside the game is actually ticking. Call this once after Blocks, with a ceiling, because there is nothing else to do with the answer: the alternative is handing back "not yet" and having the caller poll, which is the same wait with more round trips. |
| world_stateC | What the world looks like right now. With NO class_name this costs nothing and waits for nothing: the mod republishes the player's position, health and what is in their hands every tick, so the answer is already on disk. That is deliberate -- a snapshot a caller has to pay a full command round trip for (a second to be claimed, two more of terminal dwell) would make the cheapest question the most expensive one. With a class_name it also sends a |
| world_spawnA | Create an item: on the ground, in the player's hands, or in their inventory.
Ground spawns are created with ECE_PLACE_ON_SURFACE and ECE_NOLIFETIME. Without the second flag the item lives by the lifetime in its own config and the central economy is free to remove it partway through a check -- which turns "my test item vanished" into a hunt through the mod under test. The flag is the mod's, not this tool's; it is named here because it is the reason a spawned item can be trusted to still be there a minute later. |
| world_teleportA | Move the player to The same format |
| world_setB | Set
|
| world_deleteA | Delete every object of The class is required: the mod will not delete everything nearby regardless of class, and the radius is clamped on its side. Players are never deleted, whatever the class filter says. |
| world_actionA | Run a mod's own action through the engine's gate, on the server.
"Accepted" is not success: the engine can drop an accepted action one frame
later without clearing it. The mod therefore holds the command |
| world_execA | Send an arbitrary verb through the bridge -- the debugging escape hatch, not a testing path. This server does not know the verb, does not validate its arguments beyond
stringifying them, and does not answer for what the mod does with it; every
answer is marked A verb this bridge build does not know comes back as a failure listing the
verbs it does -- that is the mod answering, not this tool guessing. A
project that needs its own verb adds it to ITS OWN copy of the bridge's
dispatcher ( The verb must be lowercase ASCII (letters, digits, underscore, up to 41 chars): the mod recovers a command's id by a raw string search when a parse fails, and the id embeds the verb -- characters outside that set can make a failure impossible to correlate, which is the silence this product exists to remove. |
| client_startA | Start the game client and connect it to the test stand. Returns a job id. Three things worth knowing before calling, all of them observable: IT LAUNCHES WINDOWED, always. A fullscreen D3D window does not yield the foreground -- an attempt to cover one simply hung -- so a fullscreen client can be neither typed into nor left behind while the owner works. The window size itself is the client profile's business (DayZ.cfg), not this server's. IT REFUSES WHEN THERE IS NO STAND TO JOIN. The client connects, it does not listen, so there is no port of its own to pre-flight; what there must be is something already on the stand's port. Without that the client sits at the server browser forever and every later tool answers about a client that never joined anything. IT READS READINESS IS THE PLAYER COUNT IN THE BRIDGE STATE, NOT A TIMER. Connecting
took about 50 s when it was measured and it varies; a timer would call a
still-loading client ready and a never-connecting client a success. The job
finishes when the bridge publishes
|
| client_statusD | Everything about the client that decides whether the other tools can work. Four questions in one answer, because each of them has silently broken a run before: is the process alive; is its window in a state the eyes can capture (a MINIMIZED window cannot be captured at all -- its client area is 0x0); is UPDATE IN BACKGROUND still at the value that keeps the frame live and the gamepad effective while unfocused; and has the client actually joined the stand (the player count the bridge publishes). |
| client_stopA | Stop the client this session started, and unplug the virtual controller. The pad goes with it deliberately. Nothing else in this tool set closes it, and a controller left attached is visible inside any game running on this machine -- DayZ switches its on-screen hints to controller mode as soon as one appears. Stopping the client is the end of the input session, so it is where the device is given back. Takes no pid on purpose: the client runs the same executable as the server, so a pid argument could not be checked against the image the way server_stop's is, and "stop this pid" would become a general process killer. |
| client_shotA | Capture the client's window to a PNG. NO FOCUS NEEDED. Measured rather than assumed: the frame is live with the client at the very bottom of the z-order and live when it is in front. The one state it cannot survive is MINIMIZED -- the client area collapses to 0x0 and there is nothing to copy -- and that is refused with a hint saying to restore the window, not reported as an empty picture.
With no |
| client_moveA | Walk the character with the left stick. NO FOCUS NEEDED.
This is the only tract that moves the character at all: keyboard emulation was measured at 0 m over 25 s with the foreground verified. It is also the only one that is ANALOG, so "walking rather than sprinting" is testable here and nowhere else. The first call attaches a virtual controller to this machine, which the
game can see -- DayZ switches its on-screen hints to controller mode -- and
the answer says so. |
| client_lookA | Turn the camera with the right stick. NO FOCUS NEEDED. Same units and the same guarantees as |
| client_pressA | Press one gamepad button. NO FOCUS NEEDED -- this drives the INTERFACE too. Measured with a third-party application holding the foreground the whole
time: What a pad cannot do is type -- DayZ has no on-screen keyboard. Text in
chat goes through Buttons: a b x y back start left_shoulder right_shoulder left_thumb right_thumb dpad_up dpad_down dpad_left dpad_right. |
| client_chatA | Put a line in the connected player's chat. FOCUS IS NOT NEEDED. Said plainly because the general rule about typing does not apply here. Chat is a SERVER-SIDE MESSAGE: the engine hands the mod a call that delivers text to a player, so the bridge sends it as data -- no keyboard, no window, no foreground, and nothing taken away from whoever is at the machine. It is also more trustworthy than real typing, because the command carries an id and comes back with the mod's own confirmation instead of "typed it and hoped". This is NOT the tool for a mod's own input field -- a PDA, a terminal, a
form. Those exist only on the client and are filled by The line goes to EVERY connected player, and the answer says how many got it: the engine's call names one recipient, so a verb that quietly took the first player would put the line on one screen and leave it missing from the one the caller was watching.
What success promises is that the engine accepted the call for each named recipient -- not that the line was visible. A client drops whole chat channels according to the player's own profile options, so an accepted line that nobody can see is a client setting, not a fault in the bridge. Requires the bridge to be loaded and ticking, like every other world command, and requires the stand to be running a bridge build that knows the verb; if it is not, the mod says so and the hint says what to do. |
| client_typeA | Type into a CLIENT-SIDE INPUT FIELD -- a mod's PDA, terminal or form. REQUIRES THE ACTIVE WINDOW, and takes it. This is not chat. Chat is a server-side message and So it brings the client window to the front and VERIFIES that it got there before sending a single keystroke. If Windows refuses -- which it does to a background process -- nothing is typed and the refusal says so, rather than keystrokes going into whatever window the person at the machine is using. That accident happened here once and is why the verification is not optional. A successful call reports that the foreground was taken, because that is a side effect on a human, not an implementation detail. The text is typed as US-layout scancodes, because the client starts on another layout and a virtual-key code would produce different characters. Anything with no scancode is refused by name BEFORE the screen is taken -- an underscore that arrived as a hyphen once failed a run as if the mod were at fault.
|
| client_verdictA | Judge the running (or last) client by its own .RPT. The .RPT and not a script log, and that is a finding rather than a preference: in the Steam DIAG build the script log receivers are compiled out, so -logToFile / -logToScript / -logToRpt inject nothing and no script_*.log is produced for a client at all. Whatever the mod printed to the RPT is here; whatever it wrote only to the script log does not exist, and this says so instead of returning a clean verdict over an empty file. Not to be confused with
|
| knowledge_buildA | Build or refresh a knowledge layer. Returns a Layers, and how often each one needs this: project the mod's own sources, read where they lie. Goes stale on every edit -- rebuild it whenever you want to ask about code you just wrote. Measured: 0.11 s for 41 files. deps the archives of the mods this project declares as dependencies, read without unpacking them. Stale when a dependency is updated or the declared set changes. Measured: 150 s for 36 mods. core the game itself: scripts.pbo for the API, Addons/*.pbo for the item classes. Stale when the game updates. Measured: 3.9 s for the scripts alone, 69 s with the configs. all (the default) every layer that applies to this project. Layers that cannot be built here -- no game installed, no dependencies declared -- are named with the reason instead of failing the call. Nothing here blocks: wait with
|
| knowledge_statusA | What each knowledge layer holds, how old it is, and whether it still matches what is on disk. Staleness is a measurement, never a guess: each layer records the size and modification time of every source it read, and this compares them against the files as they are now. A layer reports what changed, what appeared and what is gone -- so "the project was edited" is a different fact from "the game was updated", which is the whole reason there are three layers. Two counts that must not be confused, and both are here: |
| knowledge_findA | Find declarations by name: classes, methods, constants, enums, configs. Matching is case-insensitive and exact unless
'class' a class declared in Enforce Script 'method' a function, with its owning class and full signature 'constant' / 'enum' what flags like ECE_* are found through 'config' a class declared in a config.cpp or a binarised config.bin -- this is how you ask "does the game have an item class called X". Kept apart because the game alone holds 88 102 of them against 43 595 script declarations, and mixed together they bury every script answer. Every answer names the layers it used and how old each one is -- and an answer with no results names every layer it searched, because "not found" is worth exactly as much as the layers behind it are current. The project layer's staleness is measured on every call, so an answer taken from an index built before your last edit says so instead of describing code that no longer exists. A search that finds nothing while a layer that could have held it was never built is refused, not answered: "not found" and "not looked" are different facts. Narrowing has the same trap one level down, so an empty narrowed answer
checks whether the name exists outside the narrowing and says where in
Every search runs under a hard time ceiling and a result limit; neither can be removed. |
| knowledge_showA | Everything the index holds about one declaration. Where
Matches come nearest-layer-first, so a class a dependency reopens with
Like every answer here, it names the layer each declaration came from and how old that layer is -- and when it finds nothing, every layer it looked in. |
| knowledge_overridesA | Who overrides this class or this method -- the question a text sweep answers worst. For a method: every declaration of it marked For a class: everyone who extends it, and every Both readings are answered at once, because a caller asking "who overrides X" usually does not yet know which X it is. The answer names the layer each hit came from and how old that layer is; a search over a layer that was never built is refused rather than answered emptily. |
| knowledge_callersA | Who CALLS this -- every place a method is invoked or a class is built. A different question from
What it does NOT see, so that an empty answer is not read as proof: a call
reached through a variable whose type the index does not track is recorded
under the method's own name, not the variable's, and |
| mod_lintA | Check a mod's Enforce Script without packing or booting anything.
Refusals: a class that extends itself ( Warnings: a statement continued onto the next line with a leading The |
| server_signaturesA | Read -- or deliberately change -- the stand's signature policy. With no argument this only reports. With WHY THIS IS ITS OWN TOOL. WHAT KEEPS IT SAFE. It edits exactly one file: |
| world_entitiesA | WHICH objects are nearby, not how many.
The list is a page: the mod caps it at 200 entries and reports the true
total separately, so
Players are not in it. The mod's own gather step skips them, which is what
keeps a |
| world_time_setA | Move the world clock. Every field left at -1 keeps the value the world already has, read back from the engine before the change. That matters because the engine sets a date as five numbers at once: a tool that filled in the missing ones would move the date every time somebody set the hour. Ranges are the engine's own documented ones -- month 1-12, day 1-31, hour 0-23, minute 0-59 -- and are checked in the mod, before a native call that would otherwise be handed a value it does not define behaviour for. The answer carries the world's clock as it stands after the change, from the mod's own snapshot rather than from what was asked for. |
| world_weather_setA | Move one weather phenomenon towards a value.
THIS IS A NUDGE, NOT A LOCK. The engine keeps simulating weather, so a value set here drifts afterwards -- said here and in the mod's own answer, because the alternative is a caller who sets rain, looks up two minutes later and concludes the tool did nothing. |
| ui_menuA | What the client's interface is doing right now. Free: the client half republishes the open menu's class, whether the cursor
is visible and whether a modal dialog is up on every tick, so this answer is
already on disk and costs no command round trip -- the same bargain
|
| ui_treeB | The client's widget tree: what is on screen, as the engine holds it.
The answer is A PAGE: |
| ui_findA | Find widgets by name, class or text, without fetching the whole tree.
Filtering happens in the client, not here: sending the whole tree back so it could be filtered locally is exactly what the page limit exists to avoid. |
| ui_clickA | Press a widget, by path, having checked it is still the one meant.
TWO TRACTS, and the answer always says which one was used:
A handler that returns false is reported as what it is: the click was delivered and the menu did not act on it. That is a fact about the mod, not a failure of this tool, and the answer says so rather than inventing a verdict. |
| ui_textA | Write into an edit box, and read it back. Only a field the player could type into may be written. A plain
The value is read back out of the widget before the answer is returned:
|
| knowledge_scopeA | Declare, inspect or clear the active mod set. With no arguments it reports the set in force and every mod folder the dependency layer holds, so a caller can see what there is to choose from.
Nothing is hidden by the narrowing. A search whose answer lies in a mod outside the set does not come back empty: it comes back naming the mod that holds it, and it comes back as a refusal, so it cannot be read as "no such thing". That is the whole point of the feature -- an invisible narrowing is the same silent lie as an answer from a stale layer.
The set is stored beside the index and survives a restart. It is NOT
changed by |
| server_modsA | Ask a running server which mods it runs, and PROPOSE an active set.
The answer is three buckets, matched by Workshop id and never by name: matched the server runs it and it is installed here on_server_not_installed the server runs it and this machine has not installed_not_on_server installed here, the server does not run it Nothing is applied. Three things this cannot see, and it says so in |
| asset_exportA | Export a model out of a Returns a This is the pipeline's OPTIONAL first step. It produces the MLOD; the
binarized model that the game loads is what The project root declared as The verdict is read off the file: it must be an MLOD, this run must be what
wrote it, all of the source's LODs must have reached it, and none of its
references may leave the mod. Measured on a real model: with the exporter's
own default arguments, 2 LODs of 5 came out as a valid MLOD with correct
paths,
Nothing else is touched: an export that produces nothing leaves the model that is already there exactly as it was, and Blender's user preferences are never written back. |
| asset_buildA | Build a mod's models from their MLOD sources and put them in the mod. Returns a What it does, in order: run
The source is the MLOD export and the ODOL is the build's output (decision
D3). Handed an ODOL, Model.cfg is never copied for you: it is what the artifact was built from, and a mismatch between the copy under the root and the copy in the mod is reported by C11 with what to do about it. Rebuilds are not byte-stable and are not expected to be -- what a rebuild is compared against is structural. |
| asset_checkA | Judge the models and textures a mod already ships. Builds nothing. Needs no DayZ Tools and no build: every check reads a file that is already on the disk, because the tools that produce these files are structurally unable to report failure. Answers in milliseconds. Twelve checks (C1-C12). Four of them refuse, and this call fails when one
does: a built model is there and is an ODOL, no reference escapes the mod,
a material was actually inlined, and nothing already binarized is offered
back to
A texture is judged against the PNG it came from -- beside it or at the
same place under |
| asset_convertA | Convert one texture between Which compression
The verdict is read off the file that was written, never off the exit code. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/covalschi/dayz-agentic-modding-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server