Skip to main content
Glama
jmagar

Unraid MCP Server

by jmagar

Unraid MCP

PyPI ghcr.io

GraphQL-backed MCP server for Unraid. Exposes a unified unraid tool for system inspection, management operations, live telemetry, and destructive actions gated by explicit confirmation.

Installation

The plugin lives at plugins/unraid/ and launches the server with uvx unraid-mcp (the published PyPI package), so no local checkout is required once it's installed. You'll need uv on your PATH.

Claude Code (plugin + marketplace)

Add this repo as a marketplace, then install the plugin:

/plugin marketplace add jmagar/unraid-mcp
/plugin install unraid-mcp@unraid-mcp

marketplace add accepts the owner/repo shorthand (or a full git URL / local path). After install, Claude Code prompts for Unraid GraphQL API URL and Unraid API Key (the plugin's userConfig); they're passed to the server and persisted to ~/.unraid-mcp/.env by the SessionStart hook.

Codex (plugin + marketplace)

The repo ships a Codex marketplace manifest at .agents/plugins/marketplace.json:

codex plugin marketplace add jmagar/unraid-mcp
# then enable `unraid-mcp@unraid-mcp` from the Codex `/plugins` view

Codex does not expand plugin-config placeholders into the MCP env, so export your credentials in the shell that launches Codex (the manifest forwards them by name):

export UNRAID_API_URL="https://tower.local/graphql"
export UNRAID_API_KEY="your-api-key"

Alternatively, populate ~/.unraid-mcp/.env (run uvx unraid-mcp setup) — the server reads it automatically.

Gemini CLI (extension)

Install the extension straight from the repo (gemini extensions install reads gemini-extension.json from the repo root):

gemini extensions install https://github.com/jmagar/unraid-mcp

Gemini prompts for the UNRAID_API_URL and UNRAID_API_KEY settings on install and exports them to the server's environment.

Run the server directly with uvx

No clone needed — run the published package on demand:

export UNRAID_API_URL="https://tower.local/graphql"
export UNRAID_API_KEY="your-api-key"
uvx unraid-mcp

Local development

uv sync --dev
uv run unraid-mcp-server

Equivalent entrypoints:

uv run unraid-mcp
uv run python -m unraid_mcp

Docker

docker compose up -d

Claude Desktop

Newer Claude Desktop builds may reject the raw streamable-http URL config when the server runs in Docker. Connect through the mcp-remote proxy instead — see docs/mcp/CONNECT.md for the macOS/Linux and Windows config snippets.

Related MCP server: arrstack-mcp

Configuration

Create .env from .env.example:

just setup

Environment variables

Variable

Required

Default

Description

UNRAID_API_URL

Yes

GraphQL endpoint URL, e.g. https://tower.local/graphql

UNRAID_API_KEY

Yes

Unraid API key (see below)

UNRAID_MCP_TRANSPORT

No

streamable-http

Transport: streamable-http, stdio, or sse (deprecated)

UNRAID_MCP_HOST

No

127.0.0.1 bare metal; Docker sets 0.0.0.0

Bind address for HTTP transports

UNRAID_MCP_PORT

No

6970

Listen port for HTTP transports

UNRAID_MCP_MAX_RESPONSE_BYTES

No

40000

Max serialized tool-response size; over-cap responses return a parseable truncation marker

UNRAID_MCP_BEARER_TOKEN

Conditional

Static Bearer token for HTTP transports; auto-generated on first start if unset

UNRAID_MCP_DISABLE_HTTP_AUTH

No

false

Set true to skip Bearer auth (use behind a reverse proxy that handles auth)

UNRAID_MCP_TRUST_PROXY

Conditional

false

Required when disabling HTTP auth while binding a non-loopback interface

UNRAID_MCP_GOOGLE_CLIENT_ID

No

Google OAuth client ID; setting both client ID and secret replaces Bearer auth for HTTP transports

UNRAID_MCP_GOOGLE_CLIENT_SECRET

No

Google OAuth client secret

UNRAID_MCP_GOOGLE_BASE_URL

Conditional

Public server base URL, required when Google OAuth is enabled

UNRAID_MCP_GOOGLE_REQUIRED_SCOPES

No

openid + userinfo.email

Comma/space-separated OAuth scopes

UNRAID_MCP_GOOGLE_ALLOWED_EMAILS

Conditional

Verified Google emails allowed to use the MCP server

UNRAID_MCP_GOOGLE_ALLOWED_DOMAINS

Conditional

Verified Google email domains allowed to use the MCP server

UNRAID_MCP_GOOGLE_ALLOW_ANY_USER

No

false

Explicitly allow any verified Google account; only for private/trusted deployments

UNRAID_MCP_GOOGLE_REDIRECT_PATH

No

/auth/callback

OAuth callback path configured in Google Cloud

UNRAID_MCP_GOOGLE_JWT_SIGNING_KEY

Conditional

With the encryption key, enables restart-surviving encrypted token storage

UNRAID_MCP_GOOGLE_ENCRYPTION_KEY

Conditional

Fernet key for encrypted OAuth token storage

UNRAID_MCP_GOOGLE_STORAGE_DIR

No

~/.unraid-mcp/oauth-tokens

Directory for persisted encrypted OAuth tokens

UNRAID_VERIFY_SSL

No

true

Upstream Unraid API TLS verification; may also be a CA-bundle path

UNRAID_ALLOW_INSECURE_TLS

Conditional

false

Required second opt-in when UNRAID_VERIFY_SSL=false

UNRAID_MCP_LOG_LEVEL

No

INFO

Log verbosity: DEBUG, INFO, WARNING, ERROR, CRITICAL

UNRAID_MCP_LOG_FILE

No

unraid-mcp.log

Log filename under logs/ or /app/logs/ in Docker

UNRAID_AUTO_START_SUBSCRIPTIONS

No

true

Auto-start live WebSocket subscriptions on boot

UNRAID_MAX_RECONNECT_ATTEMPTS

No

10

Max WebSocket reconnect attempts

UNRAID_AUTOSTART_LOG_PATH

No

auto-detect

Log file path for the log-tail subscription

UNRAID_CREDENTIALS_DIR

No

~/.unraid-mcp

Override credentials directory

DOCKER_NETWORK

No

External Docker network to join; leave blank for default bridge

PGID

No

1000

Container process GID

PUID

No

1000

Container process UID

For the full reference, including OAuth persistence and .env loading order, see docs/mcp/ENV.md, docs/CONFIG.md, and docs/AUTHENTICATION.md.

How to find UNRAID_API_KEY

  1. Open the Unraid web UI.

  2. Go to Settings → Management Access → API Keys.

  3. Create a new key or copy an existing one.

  4. Paste the value into UNRAID_API_KEY.

UNRAID_API_KEY vs UNRAID_MCP_BEARER_TOKEN

These are two separate credentials with different purposes:

  • UNRAID_API_KEY — authenticates the MCP server to the Unraid GraphQL API. Every GraphQL request carries this key as a header. Obtained from the Unraid web UI.

  • UNRAID_MCP_BEARER_TOKEN — authenticates MCP clients (Claude Code, Claude Desktop, etc.) to this MCP server. Clients must send Authorization: Bearer <token> on every HTTP request. Generate with openssl rand -hex 32 or just gen-token.

UNRAID_MCP_DISABLE_HTTP_AUTH

Set this to true when a reverse proxy (nginx, Caddy, Traefik, SWAG) already handles authentication before requests reach the MCP server. Disabling the built-in check removes the Bearer token requirement at the MCP layer. Do not expose the server directly to untrusted networks with this flag enabled.

If auth is disabled and UNRAID_MCP_HOST binds a non-loopback interface, the server also requires UNRAID_MCP_TRUST_PROXY=true as an explicit assertion that a trusted fronting gateway enforces authentication.

Google OAuth for HTTP transports

Set both UNRAID_MCP_GOOGLE_CLIENT_ID and UNRAID_MCP_GOOGLE_CLIENT_SECRET to replace static Bearer auth with Google OAuth. OAuth requires UNRAID_MCP_GOOGLE_BASE_URL and at least one authorization allowlist entry (UNRAID_MCP_GOOGLE_ALLOWED_EMAILS or UNRAID_MCP_GOOGLE_ALLOWED_DOMAINS) unless UNRAID_MCP_GOOGLE_ALLOW_ANY_USER=true is explicitly set. Google OAuth and UNRAID_MCP_DISABLE_HTTP_AUTH=true are mutually exclusive.

Transport modes

  • streamable-http — default; exposes an HTTP endpoint, requires Bearer token unless auth is disabled

  • stdio — subprocess mode for Claude Code local plugin; no Bearer token needed

  • sse — legacy Server-Sent Events; deprecated but functional

Credential files are loaded in priority order: ~/.unraid-mcp/.env first, then project .env as a fallback.

Overview

The server translates MCP tool calls into Unraid GraphQL queries and mutations over HTTP and WebSocket. All operations share a single unraid tool routed by action + subaction. Live telemetry uses WebSocket subscriptions that stream real-time data from the Unraid API.

What this repository ships

unraid-mcp/
├── unraid_mcp/                  # server, GraphQL client, subscriptions, config, tool handlers
├── plugins/
│   └── unraid/                  # the distributable plugin/extension (one per client)
│       ├── .claude-plugin/      #   Claude Code plugin manifest (plugin.json) + README
│       ├── .codex-plugin/       #   Codex plugin manifest (plugin.json)
│       ├── .mcp.json            #   shared MCP server definition (Claude) — runs `uvx unraid-mcp`
│       ├── hooks/               #   SessionStart / ConfigChange hooks (hooks.json)
│       ├── scripts/             #   plugin-runtime hook scripts (plugin-setup.sh)
│       └── skills/unraid/       #   client-facing skill docs, references, and helpers
├── gemini-extension.json        # Gemini CLI extension manifest (repo root, for git-URL install)
├── .claude-plugin/
│   └── marketplace.json         # Claude Code marketplace manifest (lists the plugin above)
├── .agents/plugins/
│   └── marketplace.json         # Codex marketplace manifest
├── scripts/                     # repo-maintenance scripts (CI, version-sync, validation)
├── docs/                        # authentication, destructive-action, and publishing references
├── docker-compose.yaml, Dockerfile, entrypoint.sh   # container deployment
└── tests/                       # unit, safety, schema, HTTP-layer, and live coverage

Tools

The server registers a single unraid tool. Every operation is reached via unraid(action=..., subaction=...). Subscription diagnostics and the Markdown reference are themselves actions of that tool (subscriptions and help).

Tool index

Tool

Purpose

unraid

Unified action/subaction router for all operations (including help and subscriptions diagnostics)

unraid — action groups

All operations go through one tool. Pick an action, then a subaction within it.

system — 25 subactions

Server information, metrics, network, and UPS.

Subaction

Description

Required params

overview

OS, CPU, memory layout, versions, machine ID

array

Array state, capacity, disk health summary

network

Access URLs, HTTP/HTTPS ports, LAN/WAN IPs

registration

License type, key file, expiration

variables

Full Unraid variable set (timezone, shares, etc.)

metrics

Current CPU % and memory usage

network_metrics

Current network throughput metrics from metrics.network

services

Running services with name, online status, version

display

Current UI theme name

display_details

Direct display root metadata: case, theme, temperature display settings, thresholds, locale

config

Config validity and error state

online

Boolean reachability check

owner

Owner username, avatar, profile URL

settings

Unified settings key/value map

server

Single-call summary: hostname, uptime, Unraid version, array state

server_details

Direct server root details with owner and URLs; API key omitted

servers

All registered servers with LAN/WAN IPs and URLs

network_access_urls

Direct network.accessUrls entries with type, name, IPv4, and IPv6

flash

Flash drive vendor and product info

ups_devices

All UPS devices with battery and power metrics

ups_device

Single UPS device details

device_id

ups_config

UPS daemon configuration

server_time

Current server time, time zone, and NTP config

timezones

Available IANA time-zone options (capped)

network_interfaces

Extended network interface list with IPv4/IPv6 address details

health — 4 subactions

Connection and system health diagnostics.

Subaction

Description

Required params

check

Comprehensive health: API latency, array state, alerts, Docker container summary

test_connection

Ping the Unraid API and return latency in ms

diagnose

Subscription system status, error counts, reconnect state

setup

Report credential status and print plugin/.env setup instructions

array — 14 subactions

Parity checks and array disk operations. Destructive subactions marked with *.

Subaction

Description

Required params

Destructive

parity_status

Current parity check progress, speed, errors

parity_history

Past parity check results

assignable_disks

Physical disks not yet in the array (pairs with add_disk)

parity_start

Start a parity check

correct (bool)

parity_pause

Pause a running parity check

parity_resume

Resume a paused parity check

parity_cancel

Cancel a running parity check

start_array

Start the Unraid array

stop_array

Stop the Unraid array

confirm=True

*

add_disk

Add a disk to the array

disk_id; optional slot

remove_disk

Remove a disk from the array (array must be stopped)

disk_id, confirm=True

*

mount_disk

Mount an array disk

disk_id

unmount_disk

Unmount an array disk

disk_id

clear_disk_stats

Clear I/O statistics for a disk (irreversible)

disk_id, confirm=True

*

disk — 6 subactions

Shares, physical disks, log files, and flash backup. Destructive subactions marked with *.

Subaction

Description

Required params

Destructive

shares

All user shares with size, allocation settings, LUKS status

disks

Physical disk list (ID, device, name)

disk_details

Single disk: serial, size, temperature

disk_id

log_files

List available log files (name, path, size, modified)

logs

Read log file content with line range

log_path; optional tail_lines (default 100, max 10000)

flash_backup

Initiate rclone backup of the flash drive to a remote

remote_name, source_path (must start with /boot), destination_path, confirm=True

*

flash_backup details: Calls the Unraid initiateFlashBackup GraphQL mutation, which triggers an rclone copy from the flash drive to a configured rclone remote. The destination on the remote is overwritten if it exists. Returns { status, jobId }. To restore: use rclone to copy the backup back to the flash drive, or extract individual config files. Configure the rclone remote first via rclone/create_remote.

docker — 26 subactions

Container lifecycle, image updates, template/digest maintenance, organizer folders, and network inspection. Destructive subactions marked with *.

Subaction

Description

Required params

Destructive

list

All containers: ID, names, image, state, status, autoStart

details

Full container detail: ports, mounts, labels, network settings

container_id

logs

Not available via the Unraid GraphQL API — returns guidance to use docker logs on the host

container_id

ports

All host port bindings across running containers, sorted by (host_port, protocol).

start

Start a container

container_id

stop

Stop a container

container_id

restart

Stop then start a container (stop + start in sequence)

container_id

unpause

Unpause a paused container

container_id

remove_container

Remove a container (optionally its image via with_image)

container_id, confirm=True

*

update_container

Apply a pending image update to one container

container_id

update_containers

Apply image updates to several containers

container_ids

update_all_containers

Apply all pending container image updates

update_autostart

Set container autostart config

autostart_entries ([{id, autoStart, wait?}])

refresh_digests

Refresh image digests (recheck for updates)

sync_template_paths

Sync Docker template paths

reset_template_mappings

Reset template path mappings to defaults

confirm=True

*

create_folder

Create an organizer folder

organizer_input ({name, …})

create_folder_with_items

Create a folder containing items

organizer_input

rename_folder

Rename a folder

organizer_input ({folderId, newName})

set_folder_children

Set a folder's children

organizer_input ({childrenIds, …})

delete_entries

Delete organizer entries

organizer_input ({entryIds}), confirm=True

*

move_entries_to_folder

Move entries into a folder

organizer_input

move_items_to_position

Move items to a position

organizer_input

update_view_preferences

Update organizer view preferences

organizer_input ({prefs, …})

networks

All Docker networks: ID, name, driver, scope

network_details

Single network with IPv6, containers, options, labels

network_id

Container identifiers accept full ID, short ID prefix, exact name, or unambiguous name prefix. Container mutations require an exact name or full ID. Organizer subactions read their fields from the organizer_input dict.

vm — 9 subactions

Virtual machine lifecycle. Destructive subactions marked with *.

Subaction

Description

Required params

Destructive

list

All VMs: ID, name, state, UUID

details

Single VM details

vm_id

start

Start a VM

vm_id

stop

Gracefully stop a VM

vm_id

pause

Pause a running VM

vm_id

resume

Resume a paused VM

vm_id

reboot

Reboot a VM

vm_id

force_stop

Hard power-off a VM (data loss possible)

vm_id, confirm=True

*

reset

Hard reset a VM without graceful shutdown

vm_id, confirm=True

*

vm_id accepts UUID, prefixed ID, or VM name.

notification — 13 subactions

System notification CRUD. Destructive subactions marked with *.

Subaction

Description

Required params

Destructive

overview

Unread and archive counts by importance (INFO/WARNING/ALERT)

list

Paginated notification list

list_type (UNREAD or ARCHIVE, default UNREAD); optional importance, offset, limit

create

Create a notification

title (≤200), subject (≤500), description (≤2000), importance (INFO/WARNING/ALERT)

notify_if_unique

Create a notification only if an identical one does not already exist

title, subject, description, importance

archive

Archive a single notification

notification_id

mark_unread

Move an archived notification back to unread

notification_id

recalculate

Recalculate the overview counts

archive_all

Archive all unread notifications

optional importance to filter

archive_many

Archive specific notifications by ID

notification_ids (list)

unarchive_many

Unarchive specific notifications by ID

notification_ids (list)

unarchive_all

Move all archived notifications back to unread

optional importance to filter

delete

Permanently delete a single notification

notification_id, notification_type, confirm=True

*

delete_archived

Permanently delete all archived notifications

confirm=True

*

key — 13 subactions

API key and permission management. Destructive subactions marked with *.

Subaction

Description

Required params

Destructive

list

All API keys with roles and permissions

get

Single API key details

key_id

possible_roles

All assignable roles

possible_permissions

All grantable resource/action permissions

permissions_for_roles

Permissions implied by given roles

roles

preview_permissions

Effective permissions for roles and/or permissions

roles and/or permissions_input ([{resource, actions}])

auth_actions

All available auth actions

creation_form_schema

JSON-schema form for key creation

create

Create an API key

name; optional roles, permissions

update

Update name, roles, or permissions

key_id; optional name, roles, permissions

delete

Delete an API key (immediately revokes access)

key_id, confirm=True

*

add_role

Add a role to an existing key

key_id, roles (first element used)

remove_role

Remove a role from an existing key

key_id, roles (first element used)

plugin — 8 subactions

Unraid plugin management and async installs. Destructive subactions marked with *.

Subaction

Description

Required params

Destructive

list

All installed plugins with version and module flags

installed_unraid

Raw installed .plg filenames

install_operations

List async plugin-install operations

install_operation

Status of one install operation

operation_id

add

Install plugins by name

names (list); optional bundled, restart

remove

Uninstall plugins by name (irreversible without re-install)

names (list), confirm=True

*

install

Async-install a .plg URL — runs code as root (poll via install_operation)

url, confirm=True; optional plugin_name, forced

*

install_language

Async-install a language pack — runs code as root

url, confirm=True

*

rclone — 4 subactions

Cloud storage remote management. Destructive subactions marked with *.

Subaction

Description

Required params

Destructive

list_remotes

All configured rclone remotes with type and parameters

config_form

Config form schema for a provider type

optional provider_type

create_remote

Create a new rclone remote

name, provider_type, config_data (dict of string/number/bool; max 50 keys)

delete_remote

Delete a rclone remote config (does not delete remote data)

name, confirm=True

*

setting — 6 subactions

System settings, UPS, SSH, time, and server identity. Destructive subactions marked with *.

Subaction

Description

Required params

Destructive

update

Update system settings (JSON key/value input)

settings_input (dict; max 100 keys, scalar values only)

configure_ups

Overwrite UPS monitoring configuration

ups_config (dict), confirm=True

*

update_ssh

Update SSH daemon settings (can cut off shell access)

config_input ({enabled, port}), confirm=True

*

update_temperature

Update temperature sensor configuration

config_input

update_system_time

Update timezone / NTP / manual time — can invalidate TLS certs

config_input, confirm=True

*

update_server_identity

Update server name, comment, and model

name; optional comment, sys_model

connect — 8 subactions

Unraid Connect / remote-access state and control. Destructive subactions marked with *.

Subaction

Description

Required params

Destructive

remote_access

Current remote-access settings (type, forward, port)

cloud

Unraid Connect / cloud status (relay, minigraph, key validity)

status

Direct connect root status: dynamic remote access and settings schema; settings values omitted

update_api_settings

Update Connect API settings (affects internet reachability)

connect_input ({accessType?, forwardType?, port?}), confirm=True

*

sign_in

Sign the server in to Unraid Connect — registers with the cloud

connect_input ({apiKey, userInfo?}), confirm=True

*

sign_out

Sign the server out of Unraid Connect

confirm=True

*

setup_remote_access

Configure remote access — can expose the server to the internet

connect_input, confirm=True

*

enable_dynamic_remote_access

Toggle dynamic remote access

connect_input ({url, enabled}), confirm=True

*

customization — 6 subactions

UI theme, locale, and SSO state.

Subaction

Description

Required params

public_theme

Public-facing theme (also the server's current theme)

is_initial_setup

Whether this is a fresh install (isFreshInstall)

sso_enabled

Whether SSO is enabled

details

Direct customization root onboarding/language details; activation-code values omitted

set_theme

Set the active UI theme

theme_name

set_locale

Set the UI locale

locale

oidc — 5 subactions

OpenID Connect / SSO provider management.

Subaction

Description

Required params

providers

All OIDC providers with client ID, scopes, auth rules

provider

Single provider details

provider_id

configuration

OIDC configuration with default allowed origins

public_providers

Public provider list (button text, icon, style)

validate_session

Validate an OIDC session token

token

onboarding — 11 subactions

First-boot / onboarding state and the internal boot context. These operate on setup state and are rarely needed on a configured server; the dangerous ones are marked with *.

Subaction

Description

Required params

Destructive

internal_boot_context

Internal boot / first-boot context

complete

Mark onboarding complete

open

Open the onboarding flow

close

Close the onboarding flow

resume

Resume onboarding

bypass

Bypass onboarding

reset

Reset onboarding/setup state

confirm=True

*

set_override

Set an onboarding override

onboarding_input

clear_override

Clear the onboarding override

refresh_internal_boot_context

Recompute the internal boot context

create_internal_boot_pool

Create an internal boot pool — FORMATS devices, may REBOOT

onboarding_input, confirm=True

*

user — 1 subaction

Subaction

Description

Required params

me

Authenticated user: ID, name, description, roles

live — 17 subactions (WebSocket subscriptions)

The live action group reads from active WebSocket subscriptions to the Unraid GraphQL API. Instead of issuing HTTP queries, it opens a graphql-transport-ws connection and either waits for one snapshot or collects events over a window.

Two delivery modes:

  • Snapshot (SNAPSHOT_ACTIONS): opens a subscription and returns the first message received within timeout seconds. For event-driven subactions (parity_progress, ups_status, notifications_overview, notifications_warnings, owner, server_status, display), a timeout means no recent state change — not an error.

  • Collect (COLLECT_ACTIONS): opens a subscription and accumulates all events for collect_for seconds, then returns the full event list. Used for streaming data like log lines and notification feeds.

Subaction

Mode

Description

Required params

cpu

Snapshot

CPU utilization: total % and per-core breakdown

memory

Snapshot

Memory: total, used, free, swap, percentages

cpu_telemetry

Snapshot

CPU power draw and temperature

array_state

Snapshot

Array state, capacity, parity check status

parity_progress

Snapshot (event-driven)

Parity check progress, speed, errors

ups_status

Snapshot (event-driven)

UPS battery, charge, runtime, power load

notifications_overview

Snapshot (event-driven)

Notification counts by importance

notifications_warnings

Snapshot (event-driven)

Warnings/alerts feed (filtered)

owner

Snapshot (event-driven)

Owner profile changes

server_status

Snapshot (event-driven)

Server registration and connectivity

display

Snapshot (event-driven)

Theme/display changes

docker_container_stats

Snapshot

Per-container CPU/memory/IO stats

temperature

Snapshot

Temperature sensor readings

network_metrics

Snapshot

Network throughput metrics

log_tail

Collect

Stream log file lines

path (must start with /var/log/ or /boot/logs/)

notification_feed

Collect

Stream incoming notifications

plugin_install_updates

Collect

Stream plugin-install progress events

operation_id (required)

Optional parameters for live:

  • collect_for (float, default 5.0) — collection window in seconds for collect-mode subactions

  • timeout (float, default 10.0) — WebSocket receive timeout in seconds

subscriptions — 2 subactions (WebSocket diagnostics)

Diagnostics for the live subscription system. Useful when live subactions return no data.

Subaction

Description

Required params

diagnose

Full diagnostic dump: auto-start status, reconnect config, per-subscription state (active, last error, data received), error counts, and troubleshooting recommendations

test_query

Send a raw GraphQL subscription string directly over WebSocket to debug schema/field issues

subscription_query

test_query validates the query first — it must be a subscription operation targeting one of the whitelisted fields (logFile, containerStats, cpu, memory, array, network, docker, vm, systemMetricsTemperature, displaySubscription, notificationsWarningsAndAlerts, pluginInstallUpdates); mutation/query keywords are rejected.

unraid(action="subscriptions", subaction="diagnose")
unraid(action="subscriptions", subaction="test_query", subscription_query="subscription { cpu { used idle system } }")

help — the Markdown reference

unraid(action="help") returns this action/subaction reference as Markdown.

Destructive actions summary

All destructive actions require confirm=True. Omitting it or passing confirm=False raises a ToolError before any network request is made.

26 destructive subactions total; plugin install / install_language share a row below.

Action

Subaction

Notes

array

stop_array

Unmounts shares; stop containers and VMs first

array

remove_disk

Array must be stopped first

array

clear_disk_stats

I/O stats are permanently erased

vm

force_stop

Hard power-off; unsaved data may be lost

vm

reset

Hard reset; unsaved data may be lost

notification

delete

Permanent; requires notification_type

notification

delete_archived

Wipes all archived notifications

rclone

delete_remote

Removes config only; does not delete remote data

key

delete

Immediately revokes all clients using that key

disk

flash_backup

Overwrites destination; configure a dedicated remote

setting

configure_ups

Overwrites UPS daemon config

setting

update_ssh

Can cut off remote shell access (disable SSH / change port)

setting

update_system_time

Clock changes can invalidate TLS certs / break time-sensitive services

plugin

remove

Irreversible without re-install

plugin

install / install_language

Fetches and runs a .plg from a URL as root

connect

sign_in

Registers the server with the Unraid Connect cloud

connect

update_api_settings

Changes remote-access posture / internet reachability

docker

remove_container

Removes a container (and optionally its image)

docker

reset_template_mappings

Resets Docker template path mappings to defaults

docker

delete_entries

Deletes Docker organizer entries

connect

sign_out

Signs the server out of Unraid Connect

connect

setup_remote_access

Reconfigures remote access; can expose the server

connect

enable_dynamic_remote_access

Toggles dynamic remote access

onboarding

reset

Resets onboarding/setup state

onboarding

create_internal_boot_pool

Formats devices and may reboot the server

Tool parameters reference

Parameter

Type

Used by

action

str

all

subaction

str

all

confirm

bool (default False)

destructive subactions

device_id

str

system/ups_device

disk_id

str

array, disk

correct

bool

array/parity_start

slot

int

array/add_disk

log_path

str

disk/logs

tail_lines

int (default 100, max 10000)

disk/logs

remote_name

str

disk/flash_backup

source_path

str

disk/flash_backup

destination_path

str

disk/flash_backup

backup_options

dict

disk/flash_backup

container_id

str

docker mutations and details

container_ids

list[str]

docker/update_containers

with_image

bool (default False)

docker/remove_container

autostart_entries

list[dict]

docker/update_autostart

organizer_input

dict

docker organizer subactions

network_id

str

docker/network_details

vm_id

str

vm (all except list)

notification_id

str

notification/archive, mark_unread, delete

notification_ids

list[str]

notification/archive_many, unarchive_many

notification_type

str (UNREAD/ARCHIVE)

notification/delete

importance

str (INFO/WARNING/ALERT)

notification filter and create

list_type

str (UNREAD/ARCHIVE, default UNREAD)

notification/list

title

str (≤200)

notification/create

subject

str (≤500)

notification/create

description

str (≤2000)

notification/create

offset

int (default 0)

notification/list

limit

int (default 20)

notification/list

key_id

str

key subactions

name

str

key/create, key/update, rclone

roles

list[str]

key subactions

permissions

list[str]

key subactions

permissions_input

list[dict]

key/preview_permissions

names

list[str]

plugin/add, plugin/remove

bundled

bool (default False)

plugin/add, plugin/remove

restart

bool (default True)

plugin/add, plugin/remove

url

str

plugin/install, plugin/install_language

plugin_name

str

plugin/install

forced

bool (default False)

plugin/install

operation_id

str

plugin/install_operation

provider_type

str

rclone/config_form, rclone/create_remote

config_data

dict

rclone/create_remote

settings_input

dict

setting/update

ups_config

dict

setting/configure_ups

config_input

dict

setting/update_ssh, update_temperature, update_system_time

comment

str

setting/update_server_identity

sys_model

str

setting/update_server_identity

connect_input

dict

connect mutations

onboarding_input

dict

onboarding/set_override, create_internal_boot_pool

theme_name

str

customization/set_theme

locale

str

customization/set_locale

provider_id

str

oidc/provider

token

str

oidc/validate_session

path

str

live/log_tail

subscription_query

str

subscriptions/test_query

collect_for

float (default 5.0)

live collect-mode subactions

timeout

float (default 10.0)

live all subactions

Usage examples

System inspection

unraid(action="system", subaction="overview")
unraid(action="system", subaction="array")
unraid(action="live", subaction="cpu")
unraid(action="live", subaction="memory")
unraid(action="health", subaction="check")

Parity check workflow

unraid(action="array", subaction="parity_status")
unraid(action="array", subaction="parity_start", correct=True)   # correcting pass
unraid(action="array", subaction="parity_start", correct=False)  # read-only pass
unraid(action="live",  subaction="parity_progress", timeout=15.0)
unraid(action="array", subaction="parity_pause")
unraid(action="array", subaction="parity_resume")
unraid(action="array", subaction="parity_cancel")
unraid(action="array", subaction="parity_history")

Docker management

unraid(action="docker", subaction="list")
unraid(action="docker", subaction="start",   container_id="plex")
unraid(action="docker", subaction="stop",    container_id="plex")
unraid(action="docker", subaction="restart", container_id="plex")
unraid(action="docker", subaction="details", container_id="plex")
unraid(action="docker", subaction="networks")

VM operations

unraid(action="vm", subaction="list")
unraid(action="vm", subaction="start",      vm_id="windows11")
unraid(action="vm", subaction="stop",       vm_id="windows11")
unraid(action="vm", subaction="pause",      vm_id="windows11")
unraid(action="vm", subaction="resume",     vm_id="windows11")
unraid(action="vm", subaction="force_stop", vm_id="windows11", confirm=True)

Log tailing

unraid(action="live", subaction="log_tail",  path="/var/log/syslog", collect_for=5.0)
unraid(action="disk", subaction="logs",      log_path="/var/log/syslog", tail_lines=200)
unraid(action="disk", subaction="log_files")

Notifications

unraid(action="notification", subaction="overview")
unraid(action="notification", subaction="list", list_type="UNREAD", limit=10)
unraid(action="notification", subaction="list", list_type="UNREAD", importance="ALERT")
unraid(
    action="notification",
    subaction="create",
    title="Test",
    subject="Test notification",
    description="Created via MCP",
    importance="INFO",
)
unraid(action="live", subaction="notification_feed", collect_for=10.0)

Flash backup

unraid(action="rclone", subaction="list_remotes")
unraid(
    action="disk",
    subaction="flash_backup",
    remote_name="my-backup-remote",
    source_path="/boot",
    destination_path="/flash-backups/tower",
    confirm=True,  # overwrites destination
)

Development commands

Command

Effect

just dev

Start development server via uv run python -m unraid_mcp

just test

Run full test suite

just lint

Run ruff linter

just fmt

Run ruff formatter

just typecheck

Run the ty type checker (uv run ty check unraid_mcp/, matches CI)

just test-live

Run live integration tests (requires a running Unraid server)

just up

Start via Docker Compose

just down

Stop Docker Compose containers

just logs

Tail Docker Compose container logs

just health

Check /health endpoint

just gen-token

Generate a secure random Bearer token

just check-contract

Docker security, baked-env, and ignore-file checks

just setup

Create .env from .env.example if missing

just clean

Remove build artifacts and caches

Verification

just lint
just typecheck
just test

For a stdio MCP smoke test:

uv run unraid-mcp-server

For an HTTP health check after just up:

just health

The automated safety tests in tests/safety/ verify that every destructive action raises a ToolError without confirm=True and that no GraphQL request reaches the network layer in that case.

GraphQL schema overview

The server issues queries and mutations against the Unraid GraphQL API. Key query roots:

Root

Used by

info

system/overview, system/display, health check

array

system/array, array/*

vars

system/network, system/variables

metrics

system/metrics

services

system/services

display

system/display_details (safe direct root)

servers

system/servers, system/network

network

system/network_access_urls (safe direct root)

server

system/server_details (safe direct root; API key omitted)

registration

system/registration

online

system/online, health/test_connection

owner

system/owner

settings

system/settings

flash

system/flash

upsDevices / upsDeviceById

system/ups_devices, system/ups_device

upsConfiguration

system/ups_config

parityHistory

array/parity_history

disk / disks

disk/disk_details, disk/disks

shares

disk/shares

logFiles / logFile

disk/log_files, disk/logs

docker.containers / docker.networks

docker/*

vms

vm/*

notifications

notification/*

apiKeys / apiKey

key/*

plugins

plugin/list

rclone

rclone/*

connect

connect/status (safe direct root; settings values omitted), connect/*

customization

customization/details (safe direct root; activation-code values omitted), customization/*

oidcProviders / oidcConfiguration

oidc/*

me

user/me

Subscriptions use graphql-transport-ws over WebSocket (falling back to legacy graphql-ws). The WebSocket URL is derived from UNRAID_API_URL by swapping the scheme (httpws, httpswss).

Plugin

Category

Description

homelab-core

core

Core agents, commands, skills, and setup/health workflows for homelab management.

overseerr-mcp

media

Search movies and TV shows, submit requests, and monitor failed requests via Overseerr.

unifi-mcp

infrastructure

Monitor and manage UniFi devices, clients, firewall rules, and network health.

gotify-mcp

utilities

Send and manage push notifications via a self-hosted Gotify server.

swag-mcp

infrastructure

Create, edit, and manage SWAG nginx reverse proxy configurations.

synapse-mcp

infrastructure

Docker management (Flux) and SSH remote operations (Scout) across homelab hosts.

arcane-mcp

infrastructure

Manage Docker environments, containers, images, volumes, networks, and GitOps via Arcane.

syslog-mcp

infrastructure

Receive, index, and search syslog streams from all homelab hosts via SQLite FTS5.

plugin-lab

dev-tools

Scaffold, review, align, and deploy homelab MCP plugins with agents and canonical templates.

License

MIT

A
license - permissive license
-
quality - not tested
B
maintenance

Maintenance

Maintainers
76dResponse time
6dRelease cycle
14Releases (12mo)
Commit activity
Issues opened vs closed

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

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/jmagar/unraid-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server