pz-nitrado-mcp

pz-nitrado-mcp

MCP server for managing a Nitrado-hosted Project Zomboid server. It lets you check status, edit sandbox settings, manage mods, and tail logs through natural language.

Category
访问服务器

README

pz-nitrado-mcp

An MCP server for managing a Project Zomboid dedicated server hosted on Nitrado, so you can check status, tune sandbox settings and manage mods by talking to Claude instead of clicking through the web panel.

There is no official Nitrado MCP server; the only community one targets ARK. This one speaks PZ: it knows where servertest.ini and SandboxVars.lua actually live, edits the .ini without trashing your comments, and keeps Mods and WorkshopItems in sync.

Tools

Tool What it does
nitrado_list_services List every service on the account — use it to find your service_id
nitrado_event_log Audit trail: who restarted, who changed which file, and when
pz_list_config_profiles Saved config snapshots — the server's config history
pz_get_config_profile A config file as it was when a snapshot was taken
pz_diff_config_profile What changed between a snapshot and the live config
pz_server_status Online/offline, address, slots, players connected, version
pz_locate_configs Discover the real config paths (the server name is host-assigned)
pz_list_files List or recursively glob a remote directory
pz_read_file Read any file; ini / sandbox / spawnregions are shortcuts
pz_get_settings The main .ini parsed into key/value pairs
pz_get_sandbox Sandbox settings, searchable, with the docs for each enum
pz_set_sandbox Change sandbox settings in place, comments preserved
pz_get_mods Current Mods and WorkshopItems, in load order
pz_list_logs Available logs newest-first: console plus PZ's rotated logs
pz_tail_log Tail the last N lines of a log, with an optional filter
pz_write_file Overwrite a file (keeps a timestamped .bak)
pz_set_settings Set individual .ini keys, preserving comments and ordering
pz_set_mods Add / remove / replace mods, updating both id lists together
pz_restart Restart the server so changes take effect — also starts a stopped one
pz_stop Stop the server

Every write takes a timestamped backup next to the original first, so a bad edit is always recoverable from the file server. The five most recent backups per file are kept and older ones are pruned — set PZ_BACKUP_KEEP to change that, or to 0 to disable backups entirely.

Setup

1. Get a Nitrado API token

In the Nitrado panel: your account menu → Developer (or /developer) → Create token. Tick the service scope and nothing else — it covers gameserver status, the file server and restarts. In particular do not tick service_order, which allows ordering (and paying for) new services. The token is shown once; treat it like a password.

2. Install

git clone https://github.com/aolmosj/pz-nitrado-mcp.git
cd pz-nitrado-mcp
python3 -m venv .venv
.venv/bin/pip install -r requirements.txt      # editable install; add ".[dev]" for tests

Or straight from GitHub into an existing environment:

pip install git+https://github.com/aolmosj/pz-nitrado-mcp.git

3. Store the token

Put it in the shared config directory, so every project and session picks it up and it never lives inside an editor config file:

mkdir -p ~/.config/nitrado && chmod 700 ~/.config/nitrado
printf '%s' 'your-token-here' > ~/.config/nitrado/token
chmod 600 ~/.config/nitrado/token

# optional: a default service id, so tools can omit it
printf '%s' '1234567' > ~/.config/nitrado/service_id

Use printf rather than echo to avoid a trailing newline — though the server strips whitespace anyway. It warns on stderr if the token file is readable by other users.

Don't know your service id? Leave it out and ask nitrado_list_services.

4. Register it with Claude Code

Add to .mcp.json in your project (or ~/.claude.json for all projects). No credentials here — they come from the config directory:

{
  "mcpServers": {
    "pz-nitrado": {
      "command": "/absolute/path/to/pz-nitrado-mcp/.venv/bin/python",
      "args": ["-m", "pz_nitrado_mcp"]
    }
  }
}

The installed console script works too, if you prefer a single token: "command": "/absolute/path/to/.venv/bin/pz-nitrado-mcp" with no args.

Don't reach for a cwd field. It is tempting to skip the install and point cwd at the checkout instead — but Claude Code does not apply it, so the server starts somewhere else, fails with No module named pz_nitrado_mcp, and the client reports only -32000: Connection closed. claude mcp list shows the underlying error.

Configuration reference

Each setting is resolved from the first source that has it:

Setting 1. Env var 2. <VAR>_FILE 3. Config dir
Token (required) NITRADO_TOKEN NITRADO_TOKEN_FILE ~/.config/nitrado/token
Default service id NITRADO_SERVICE_ID NITRADO_SERVICE_ID_FILE ~/.config/nitrado/service_id

XDG_CONFIG_HOME is honoured if set.

Two behaviour switches, environment-only:

Variable Default Effect
PZ_ALLOW_WRITES 1 0 runs read-only — no writes, no restarts. A reasonable default for a shared or automated setup.
PZ_BACKUP_KEEP 5 Backups retained per file; older ones are pruned after each write. 0 disables backups entirely.

Usage

Once registered, just ask:

  • "¿Está arriba el servidor? ¿Quién está jugando?"
  • "Sube la población de zombis a insane y baja el loot a rare"
  • "Añade Authentic Z y Brita's Weapon Pack, y reinicia"
  • "¿Qué mods tengo instalados ahora mismo?"

Reading logs

PZ rotates its logs on every server start, naming them DD-MM-YY_HH-MM-SS_<kind>.txt under Zomboid/Logs/, alongside a live server-console.txt. You don't need to know the timestamps — pz_tail_log takes a kind and resolves it to the most recent file:

  • console — the live server console (default; where crashes and mod load failures show up)
  • chat, user, admin, pvp, map, item, cmd — PZ's per-category logs
  • DebugLog-server — verbose server debug output

Only the tail is fetched, using Nitrado's seek endpoint with a negative byte offset, so tailing a multi-megabyte log stays cheap. The endpoint caps each request at 64 KiB, so large tails page backwards in chunks. The optional contains filter is applied to the fetched window — if you expect older matches, raise lines rather than assuming there are none.

Sandbox settings

SandboxVars.lua holds ~270 settings — zombie population and speed, loot rarity, day length, XP rates, erosion. Most are numeric enums whose meaning is documented in comments right above them, and pz_get_sandbox returns those comments alongside the value:

pz_get_sandbox(search="insane")

  Zombies = 4
    Changing this also sets the "Population Multiplier". Default = Normal
    1 = Insane   2 = Very High   3 = High   4 = Normal   5 = Low   6 = None

So "make the zombies insane" becomes pz_set_sandbox({"Zombies": 1}) without anyone having to memorise the numbering. Nested settings use dotted names (ZombieLore.Speed, MultiplierConfig.*).

Edits are line-surgical: only the lines you name change, and the file's 738 comments, ordering and numeric formatting survive untouched. Writing 2 into a setting that reads 0.8 produces 2.0, not 2.

Unknown setting names are rejected, not appended. The game silently ignores settings it doesn't recognise, so a typo would otherwise look like it worked and do nothing; the error suggests the closest real names instead.

Configuration history

Nitrado snapshots the config most days, and keeps whatever you save by hand — the panel's "Perfiles de Configuración". pz_diff_config_profile is the useful end of it: point it at a snapshot and it reports only what differs from the config running now.

pz_diff_config_profile("09.07.2026 - 22:21")

  differences: 111
    PVP:        'false' -> 'true'
    NoFire:     'true'  -> 'false'
    Mods:       'Ashenwood;BBL;Blackwood;…(+6000 more chars)' -> 'CleanHotBar'

⚠️ These snapshots contain passwords in plain text — the admin password in the settings block, and the server and RCON passwords inside the config file. Every profile tool redacts them by default; include_secrets=true turns that off deliberately. A profile is a full copy of your config, so treat its output as sensitive.

Long values are abbreviated so one enormous Mods line doesn't bury the rest of a diff; pass full_values=true when you need the whole thing.

Event log vs game log

Two different things, easy to confuse:

  • nitrado_event_log — what people did to the service. Restarts, stops, file uploads and deletions, settings changes, game installs, each with the account name and a timestamp. This is the panel's "Registro de eventos".
  • pz_tail_log — what the game did. Startup sequence, errors, chat, connections.

"Who restarted the server at 3am?" is the first; "why did it crash?" is the second.

Config writes made through this MCP server show up in the event log as filebrowser uploads, so its own activity is auditable alongside everything else. Filtering is done client-side because the endpoint ignores filter parameters, and category matching is case-insensitive — the live log contains both server and Server, and an exact match silently drops the latter (which is where the error entries live).

A note on mods

PZ needs two identifiers per mod and they are not interchangeable:

  • workshopId — the numeric Steam Workshop id, what the server downloads
  • modId — the string from the mod's mod.info, what the game loads

pz_set_mods takes both and keeps Mods= and WorkshopItems= consistent. List order is load order, which matters when mods conflict.

Notes and limitations

  • Paths are discovered, not assumed. On Nitrado the gameserver root holds the game install; the server's own state lives under profile/Zomboid (Server/, Logs/, Saves/, server-console.txt). Other hosts differ, so the server probes candidate locations and identifies the right one by its contents. pz_locate_configs and pz_list_logs report what it found.
  • Config files only exist after first boot. PZ writes servertest.ini and friends when the server first starts, so pz_locate_configs will fail on a server that has never run. Start it once from the panel.
  • Changes need a restart. Nothing is applied live; every write tool says so.
  • pz_restart is also "start". The API has no start action, so a server stopped with pz_stop comes back only via pz_restart. A restart takes about a minute (started → restarting → stopping → started), and the status lags a few seconds behind the request — a status of started immediately after calling restart doesn't mean it was ignored.
  • Build 42 wants at least 8 GB of RAM. If the plan is smaller, you will feel it once several players are on.

Development

.venv/bin/pip install -e ".[dev]"     # pytest + pytest-asyncio
.venv/bin/python -m pytest tests/ -q

The tests cover the config-manipulation logic — .ini editing, mod list merging, path resolution — which is the part that can corrupt a live server, and they run without touching the network.

License

MIT

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选