Repository navigation
Releases: mswdev/better-unraid-mcp
Release list
v0.1.0
0.1.0 — MCP SDK v2, zod 4, protocol 2026-07-28
The platform release: same 67 tools, same arguments and outputs, new foundation.
Changed
- MCP TypeScript SDK v2 (
@modelcontextprotocol/server+@modelcontextprotocol/node, protocol revision 2026-07-28). Clients on older protocol revisions negotiate down automatically — verified with a v1 SDK client: tools, structured output, prompts, resources, and live subscriptions all work. - zod 4. Every tool input/output schema is now an explicit
z.object(). - Behavioral deltas inherited from the SDK (decision D34):
listChanged: trueis advertised for tools/resources/prompts; the stdio read buffer is capped at 10 MB and non-JSON stdout lines are skipped; HTTP POSTs withoutContent-Type: application/jsonanswer 415. - Node floor stays
>=20(D35).
Added
mcpNamein package.json and aserver.jsonfor the official MCP Registry (io.github.mswdev/better-unraid-mcp).
Attached
better-unraid-mcp-0.1.0.mcpb— Claude Desktop one-click bundle (download, open, enter URL + API key).
Full Changelog: v0.0.15...v0.1.0
v0.0.15
0.0.15 — metric history
Added
- Opt-in metrics recorder — set
MCP_METRICS_HISTORY=trueand the server subscribes to the CPU, memory, and network WebSocket feeds at start and keeps 24 hours of 30-second min/avg/max buckets per topic in memory (2880 slots each; nothing is written to disk; cleared on restart). metrics_history(read-only) —topiccpu | memory | network,window_minutes(default 60, max 1440). Concise output folds the window into at most 24 rows; detailed output returns every point with ISO times; missing buckets are counted as gaps, never interpolated. When recording is off the tool explains exactly how to turn it on.unraid://live/historyresource — the last hour of every recorded topic (or the enable hint).
Internals
- The three metric subscription documents now live in one place (
metric-subscriptions.ts) shared by the live resource and the recorder.
Docs
- README configuration row, resources bullet, tool row (67 tools);
.env.example; decision log D32–D33.
Full Changelog: v0.0.14...v0.0.15
v0.0.14
0.0.14 — host configuration over SSH
Seven new tools for what the Unraid GraphQL API cannot do, each validated live (read-only) against a real Unraid 7.3.2 server and against the unraid/webgui source, and each verifying its own result by reading it back. 66 tools total.
Services
service_list— running / stopped / not-installed state of samba, nfs, sshd, docker, libvirt, tailscale via/etc/rc.d/rc.* status(parsed from the status sentence — the scripts exit 0 either way).service_action(tier-2) —restart/start/stopwith a status read-back.stopalso needsallow_stop: true(it cuts clients off their shares); stopping docker or libvirt is refused outright — usearray_actionor the web UI.
Unassigned devices
unassigned_list— disks outside the array, pools, and flash (lsblk cross-referenced with emhttpd'sdisks.ini; pseudo-disks such as zram filtered), with partitions, filesystems, and mount points.unassigned_action(tier-2) — mount / unmount a partition through the Unassigned Devices plugin'src.unassigned, verified with lsblk. Refuses partitions of assigned disks and refuses entirely when the plugin is missing (no raw mount fallback).
Shares
share_create,share_edit,share_delete(tier-2) — go through emhttpd exactly as the web UI does (the ShareEdit and SecuritySMB forms, viaemcmd), expose a validated settings subset (comment, allocator, cache mode/pool, SMB export/security), pass every other setting through unchanged, validate names like the UI (reserved, disk, and pool names refused), and verify each write by re-reading/boot/config/shares/<name>.cfg— any mismatch is reported as "not verified".share_deleteonly removes the configuration and refuses while the share still holds data.
Docs
- README "Host configuration (SSH)" section; decision log D29–D31; the Phase 3 plan carries the full live-validation record.
Full Changelog: v0.0.13...v0.0.14
v0.0.13
0.0.13 — flash backup
Added
flash_backup(tier-2, SSH) — archives the Unraid flash device into a user share:/boot/configby default (settings, plugins, keys), or the whole flash withfull: true. Writes/mnt/user/<share>/flash-backups/flash-backup-<scope>-<UTC timestamp>.tar.gz, verifies it withtar -tzf, reports size and entry count, and withkeep: Nprunes older archives while listing exactly what it removed. Progress heartbeats cover the multi-GB full case. The archive contains your license key, API keys, and passwords — it stays on your array; the tool never copies it off the server. This replaces the Unraid API's flash-backup mutation, which is an unimplemented stub upstream.
Decisions
- VM snapshot revert/delete remain deliberately unshipped (D27): the live-validation server has VMs disabled, and the web UI flow depends on webgui-private snapshot metadata, domain-XML rewrites, backing-chain unlinking, and NVRAM handling that cannot be reproduced chain-safely through
virshalone.vm_snapshot_create/vm_snapshot_liststill point at the UI for those.
Full Changelog: v0.0.12...v0.0.13
v0.0.12
0.0.12 — DX quick wins
Added
npx better-unraid-mcp doctor— runs the connection-doctor checks from the command line (GraphQL reachability and versions, schema skew, SSH, rate limit, read-only mode) and exits non-zero when a check fails. README quick start step 3.- Schema skew check —
connection_doctorand the CLI compare the server's API version with the version the vendored schema was fetched from (major.minor, warn-only).npm run schema:updatenow records that version inschema/schema-version.json. - Local validation for raw GraphQL —
graphql_queryandgraphql_mutationvalidate documents against the vendored schema before sending anything (typos get did-you-mean hints);dry_run: truevalidates only and needs no confirm.
Changed
- Vendored schema refreshed to unraid/api 4.37.4. Consequences:
array_disk_actionno longer offersremove— upstream retiredremoveDiskFromArray(unraid/api#2068); a legacyremovecall gets an explicit refusal pointing at the web UI.docker_container_action restartuses the API's nativerestartmutation instead of the composed stop-then-start.
notification_archivesays plainly that the batch API swallows per-id failures (verify withnotification_list).
Docs
- Decision log D22–D26; the acceptance-test prompt's
archiveAllselection corrected to a schema-valid one.
Full Changelog: v0.0.11...v0.0.12
v0.0.11
0.0.11 — validated on real hardware
The first release exercised end-to-end against a real Unraid box (Unraid 7.3.2, API 4.37.4, 29-disk array, 58 containers, Intel iGPU, NUT-managed UPS). The acceptance run and its findings are in docs/superpowers/specs/roadmap-acceptance-report-2026-09-17.md.
Fixed
system_healthandunraid://healthno longer fail when apcaccess has no data. UPS is now read in its own query; when the Unraid API cannot read apcupsd (NUT-managed or absent UPS) the rollup reportsups: UPS data unavailable …instead of erroring out.ups_statusreturns an honest "No live UPS data" result (withupsDetected: falsein detailed mode) for the apcaccess-empty case, and explains that NUT-managed UPSes are invisible to the Unraid API.disk_listfilters the upstream partition-prefix bleed: on servers with more than 26 disks the API attachedsdaa1…sdae1(including the flash drive) to/dev/sda.gpu_metrics(Intel) now returns a one-line summary — actual frequency, rc6 idle share, per-engine busy %, GPU clients — parsed from theintel_gpu_top -Jstream (newline-separated, truncated bytimeout), instead of dumping raw JSON.
Docs
- Acceptance report, Phase 0 plan, decision log D18–D21.
Full Changelog: v0.0.10...v0.0.11
v0.0.10
0.0.10 — Full live coverage + review hardening
New features
unraid://live/metricsnow carries everything — CPU, memory, network, and temperature subscriptions merged into one resource with per-topic ages.- Three new live resources —
unraid://live/ups(UPS telemetry),unraid://live/array(array state/capacity),unraid://live/notifications(newest notification as it arrives).
Fixes (from a full-codebase review of the 0.0.4–0.0.9 work — 14 verified findings)
- Live feed subscriptions now stop when their server/session closes (was: a permanent WebSocket subscription leak per recycled HTTP session); errored subscriptions self-heal on the next subscribe; the docker-stats aggregate evicts containers not seen for 30 s (was: stopped containers reported as fresh "live" data).
- The snapshot cache is cleared after any mutation (was: verification reads within 5 s could serve pre-mutation state).
system_powernow reports SSH auth/DNS failures as real errors (was: a false "the reboot command was issued" success); a remote command that dies without an exit status maps to exit −1, never 0 (was: signal-killed destructive commands reported success); timed-out commands close their SSH channel.- HTTP session mode: failed initializations no longer leak server/transport pairs, and sessions with an open SSE stream are exempt from the idle sweeper.
user_script_runrejects./..names;system_healthhandles phantom UPS devices and multi-token apcupsd statuses; the truncation envelope re-shrinks until it fits the output budget; SSH channel-semaphore race fixed.
Changes
.env.examplecaught up with all of the roadmap's environment variables.
v0.0.9
0.0.9 — Live telemetry + launch kit
The roadmap's final planned release: real-time data over WebSocket, surfaced the MCP-native way.
New features
- Subscription client — a graphql-ws client (graphql-transport-ws subprotocol, authenticated via the
connection_initpayload) with lazy connect and bounded auto-retry, feeding an age-stamped live sample store. - Subscribable MCP resources —
unraid://live/parity,unraid://live/docker-stats,unraid://live/metrics, and the templatedunraid://logs/{path}log follow. Clients that issueresources/subscribegetnotifications/resources/updatedon every sample; clients that don't get an honest{"waiting": true}envelope on read. docker_statslive preference — serves a fresh subscription-fed sample when one is ≤ 10 s old (labelledsource: live subscription, age Xms), falling back to the SSHdocker statssnapshot (labelledsource: ssh).- Launch kit — README overhaul (58-tool feature tour, cautious read-only quickstart, per-client install snippets) and a draft Unraid-forum announcement at
docs/launch/forum-post.md.
Changes
- New runtime dependencies:
graphql-ws,ws. - The roadmap deliverables shipped: decision log (
docs/superpowers/specs/roadmap-decisions.md) and acceptance-test prompt (docs/superpowers/specs/roadmap-acceptance-test.md).
v0.0.8
0.0.8 — Coverage: SSH
Twelve SSH-backed tools that reach past the API. 58 tools. Every tool probes command availability and reports absence clearly; all interpolated values are shell-quoted.
New features
- ZFS suite —
zfs_status(pool health + ARC usage from/proc/spl/kstat/zfs/arcstats),zfs_dataset_list,zfs_snapshot_list, and two-flag-gatedzfs_snapshot_action(create / destroy / rollback — destroy can only ever target adataset@snapshot, and rollback deliberately refuses non-latest snapshots). gpu_metrics— full per-GPU metrics via nvidia-smi; Intel detection with a boundedintel_gpu_topsample; clear absence report otherwise.process_list— top host processes by CPU or memory.disk_spin— spin array slots through emhttpd (emcmd, keeping the UI's spin state consistent) or unassigned/dev/sdXviasdspin; NVMe rejected.- User Scripts —
user_script_list, and two-flag-gateduser_script_runreplicating the plugin's noexec-flash runner (copy to tmp, strip CRs, run via bash, preserve the exit code). - VM snapshots —
vm_snapshot_listand two-flag-gatedvm_snapshot_create, using EXTERNAL disk snapshots (virsh snapshot-create-as --atomic --disk-only, the same flow Unraid 7 uses). Revert/delete deliberately stay in the Unraid UI for now (external-chain corruption risk). disk_smart_report— the full smartctl attribute report for one disk, tolerating smartctl's informational exit-code bitmask.
v0.0.7
0.0.7 — Coverage: GraphQL
Four new capability areas from the Unraid GraphQL API. 46 tools.
New features
array_disk_action— add/remove a disk to/from the protected array, mount/unmount an array disk, or clear disk statistics. Array-state preconditions are checked first (membership changes require a STOPPED array; live-disk actions require STARTED), and the tool is two-flag gated — a wrong disk id here risks data loss.- API key management —
apikey_list(metadata only; key values are never selected) and two-flag-gatedapikey_manage(create / update / add_role / remove_role / delete). The key value is disclosed exactly once, at creation. notification_unread— move a notification back to the unread bucket (reversible, ungated).plugin_install_plg— install a native Unraid OS plugin from a.plgURL (two-flag gated; a.plgruns arbitrary code as root).
Changes
- The spec's rclone-remotes/flash-backup item ships nothing, deliberately: upstream's
initiateFlashBackupis a Not-implemented stub and rclone is disabled in production builds (decision D9 in the decision log).