Unraid MCP Server
Provides tools for monitoring Docker containers and networks on an Unraid server, including listing containers and accessing detailed information about specific containers.
Interfaces with Unraid's GraphQL API to facilitate all server interactions, handling authentication and providing consistent error reporting.
Allows querying information about the Plex media server container running on Unraid, mentioned as an example use case for container-specific details.
Enables interaction with an Unraid server through its GraphQL API, offering system monitoring, array status, Docker container management, VM management, disk information, notification management, share management, user management, and plugin monitoring capabilities.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Unraid MCP Serverlist all my Docker containers"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Unraid MCP
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.
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.
Related MCP server: Model Control Plane (MCP) Server
What this repository ships
unraid_mcp/— server, GraphQL client, WebSocket subscriptions, config, and tool handlersskills/unraid/— client-facing skill docsdocs/— authentication, destructive-action, and publishing references.claude-plugin/,.codex-plugin/,gemini-extension.json— client manifestsdocker-compose.yaml,Dockerfile,entrypoint.sh— container deploymenttests/— unit, safety, schema, HTTP-layer, and live coverage
Tools
Tool index
Tool | Purpose |
| Unified action/subaction router for all operations |
| Returns this reference as Markdown |
| Full diagnostic dump of the WebSocket subscription system |
| Probe a raw GraphQL subscription for schema/debug work |
unraid — action groups
All operations go through one tool. Pick an action, then a subaction within it.
system — 18 subactions
Server information, metrics, network, and UPS.
Subaction | Description | Required params |
| OS, CPU, memory layout, versions, machine ID | — |
| Array state, capacity, disk health summary | — |
| Access URLs, HTTP/HTTPS ports, LAN/WAN IPs | — |
| License type, key file, expiration | — |
| Full Unraid variable set (timezone, shares, etc.) | — |
| Live CPU % and memory usage | — |
| Running services with name, online status, version | — |
| Current UI theme name | — |
| Config validity and error state | — |
| Boolean reachability check | — |
| Owner username, avatar, profile URL | — |
| Unified settings key/value map | — |
| Single-call summary: hostname, uptime, Unraid version, array state | — |
| All registered servers with LAN/WAN IPs and URLs | — |
| Flash drive vendor and product info | — |
| All UPS devices with battery and power metrics | — |
| Single UPS device details |
|
| UPS daemon configuration | — |
health — 4 subactions
Connection and system health diagnostics.
Subaction | Description | Required params |
| Comprehensive health: API latency, array state, alerts, Docker container summary | — |
| Ping the Unraid API and return latency in ms | — |
| Subscription system status, error counts, reconnect state | — |
| Interactive credential setup (supports MCP elicitation) | — |
array — 13 subactions
Parity checks and array disk operations. Destructive subactions marked with *.
Subaction | Description | Required params | Destructive |
| Current parity check progress, speed, errors | — | — |
| Past parity check results | — | — |
| Start a parity check |
| — |
| Pause a running parity check | — | — |
| Resume a paused parity check | — | — |
| Cancel a running parity check | — | — |
| Start the Unraid array | — | — |
| Stop the Unraid array |
| * |
| Add a disk to the array |
| — |
| Remove a disk from the array (array must be stopped) |
| * |
| Mount an array disk |
| — |
| Unmount an array disk |
| — |
| Clear I/O statistics for a disk (irreversible) |
| * |
disk — 6 subactions
Shares, physical disks, log files, and flash backup. Destructive subactions marked with *.
Subaction | Description | Required params | Destructive |
| All user shares with size, allocation settings, LUKS status | — | — |
| Physical disk list (ID, device, name) | — | — |
| Single disk: serial, size, temperature |
| — |
| List available log files (name, path, size, modified) | — | — |
| Read log file content with line range |
| — |
| Initiate rclone backup of the flash drive to a remote |
| * |
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 — 7 subactions
Container lifecycle and network inspection. No destructive subactions.
Subaction | Description | Required params |
| All containers: ID, names, image, state, status, autoStart | — |
| Full container detail: ports, mounts, labels, network settings |
|
| Start a container |
|
| Stop a container |
|
| Stop then start a container (stop + start in sequence) |
|
| All Docker networks: ID, name, driver, scope | — |
| Single network with IPv6, containers, options, labels |
|
Container identifiers accept full ID, short ID prefix, exact name, or unambiguous name prefix. Mutations (start, stop, restart) require an exact name or full ID.
vm — 9 subactions
Virtual machine lifecycle. Destructive subactions marked with *.
Subaction | Description | Required params | Destructive |
| All VMs: ID, name, state, UUID | — | — |
| Single VM details |
| — |
| Start a VM |
| — |
| Gracefully stop a VM |
| — |
| Pause a running VM |
| — |
| Resume a paused VM |
| — |
| Reboot a VM |
| — |
| Hard power-off a VM (data loss possible) |
| * |
| Hard reset a VM without graceful shutdown |
| * |
vm_id accepts UUID, prefixed ID, or VM name.
notification — 12 subactions
System notification CRUD. Destructive subactions marked with *.
Subaction | Description | Required params | Destructive |
| Unread and archive counts by importance (INFO/WARNING/ALERT) | — | — |
| Paginated notification list |
| — |
| Create a notification |
| — |
| Archive a single notification |
| — |
| Move an archived notification back to unread |
| — |
| Recalculate the overview counts | — | — |
| Archive all unread notifications | optional | — |
| Archive specific notifications by ID |
| — |
| Unarchive specific notifications by ID |
| — |
| Move all archived notifications back to unread | optional | — |
| Permanently delete a single notification |
| * |
| Permanently delete all archived notifications |
| * |
key — 7 subactions
API key management. Destructive subactions marked with *.
Subaction | Description | Required params | Destructive |
| All API keys with roles and permissions | — | — |
| Single API key details |
| — |
| Create an API key |
| — |
| Update name, roles, or permissions |
| — |
| Delete an API key (immediately revokes access) |
| * |
| Add a role to an existing key |
| — |
| Remove a role from an existing key |
| — |
plugin — 3 subactions
Unraid plugin management. Destructive subactions marked with *.
Subaction | Description | Required params | Destructive |
| All installed plugins with version and module flags | — | — |
| Install plugins by name |
| — |
| Uninstall plugins by name (irreversible without re-install) |
| * |
rclone — 4 subactions
Cloud storage remote management. Destructive subactions marked with *.
Subaction | Description | Required params | Destructive |
| All configured rclone remotes with type and parameters | — | — |
| Config form schema for a provider type | optional | — |
| Create a new rclone remote |
| — |
| Delete a rclone remote config (does not delete remote data) |
| * |
setting — 2 subactions
System settings. Destructive subactions marked with *.
Subaction | Description | Required params | Destructive |
| Update system settings (JSON key/value input) |
| — |
| Overwrite UPS monitoring configuration |
| * |
customization — 5 subactions
UI theme and SSO state.
Subaction | Description | Required params |
| Full theme, partner info, and activation code | — |
| Public-facing theme and partner info (unauthenticated view) | — |
| Whether initial setup wizard has been completed | — |
| Whether SSO is enabled | — |
| Set the active UI theme |
|
oidc — 5 subactions
OpenID Connect / SSO provider management.
Subaction | Description | Required params |
| All OIDC providers with client ID, scopes, auth rules | — |
| Single provider details |
|
| OIDC configuration with default allowed origins | — |
| Public provider list (button text, icon, style) | — |
| Validate an OIDC session token |
|
user — 1 subaction
Subaction | Description | Required params |
| Authenticated user: ID, name, description, roles | — |
live — 11 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 withintimeoutseconds. For event-driven subactions (parity_progress,ups_status,notifications_overview,owner,server_status), a timeout means no recent state change — not an error.Collect (
COLLECT_ACTIONS): opens a subscription and accumulates all events forcollect_forseconds, then returns the full event list. Used for streaming data like log lines and notification feeds.
Subaction | Mode | Description | Required params |
| Snapshot | CPU utilization: total % and per-core breakdown | — |
| Snapshot | Memory: total, used, free, swap, percentages | — |
| Snapshot | CPU power draw and temperature | — |
| Snapshot | Array state, capacity, parity check status | — |
| Snapshot (event-driven) | Parity check progress, speed, errors | — |
| Snapshot (event-driven) | UPS battery, charge, runtime, power load | — |
| Snapshot (event-driven) | Notification counts by importance | — |
| Snapshot (event-driven) | Owner profile changes | — |
| Snapshot (event-driven) | Server registration and connectivity | — |
| Collect | Stream log file lines |
|
| Collect | Stream incoming notifications | — |
Optional parameters for live:
collect_for(float, default5.0) — collection window in seconds for collect-mode subactionstimeout(float, default10.0) — WebSocket receive timeout in seconds
diagnose_subscriptions
Returns a full diagnostic dump of the subscription system: auto-start status, reconnect configuration, per-subscription state (active, last error, data received), error counts, and troubleshooting recommendations. Useful when live subactions return no data.
test_subscription_query
Accepts a raw GraphQL subscription string and sends it directly over WebSocket. Validates the query first — must be a subscription operation targeting one of the whitelisted fields: logFile, containerStats, cpu, memory, array, network, docker, vm. Mutation and query keywords are rejected. Returns the first message received or a note that the subscription is waiting for events.
Destructive actions summary
All destructive actions require confirm=True. Omitting it or passing confirm=False raises a ToolError before any network request is made.
Action | Subaction | Notes |
|
| Unmounts shares; stop containers and VMs first |
|
| Array must be stopped first |
|
| I/O stats are permanently erased |
|
| Hard power-off; unsaved data may be lost |
|
| Hard reset; unsaved data may be lost |
|
| Permanent; requires |
|
| Wipes all archived notifications |
|
| Removes config only; does not delete remote data |
|
| Immediately revokes all clients using that key |
|
| Overwrites destination; configure a dedicated remote |
|
| Overwrites UPS daemon config |
|
| Irreversible without re-install |
Tool parameters reference
Parameter | Type | Used by |
| str | all |
| str | all |
| bool (default | destructive subactions |
| str |
|
| str |
|
| bool |
|
| int |
|
| str |
|
| int (default 100, max 10000) |
|
| str |
|
| str |
|
| str |
|
| dict |
|
| str |
|
| str |
|
| str |
|
| str |
|
| list[str] |
|
| str (UNREAD/ARCHIVE) |
|
| str (INFO/WARNING/ALERT) |
|
| str (UNREAD/ARCHIVE, default UNREAD) |
|
| str (≤200) |
|
| str (≤500) |
|
| str (≤2000) |
|
| int (default 0) |
|
| int (default 20) |
|
| str |
|
| str |
|
| list[str] |
|
| list[str] |
|
| list[str] |
|
| bool (default |
|
| bool (default |
|
| str |
|
| dict |
|
| dict |
|
| dict |
|
| str |
|
| str |
|
| str |
|
| str |
|
| float (default |
|
| float (default |
|
Installation
Marketplace
/plugin marketplace add jmagar/claude-homelab
/plugin install unraid-mcp @jmagar-claude-homelabLocal development
uv sync --dev
uv run unraid-mcp-serverEquivalent entrypoints:
uv run unraid-mcp
uv run python -m unraid_mcpDocker
docker compose up -dConfiguration
Create .env from .env.example:
just setupEnvironment variables
Variable | Required | Default | Description |
| Yes | — | GraphQL endpoint URL, e.g. |
| Yes | — | Unraid API key (see below) |
| No |
| Transport: |
| No |
| Bind address for HTTP transports |
| No |
| Listen port for HTTP transports |
| Conditional | — | Static Bearer token for HTTP transports; auto-generated on first start if unset |
| No |
| Set |
| No | — | External Docker network to join; leave blank for default bridge |
| No |
| Container process GID |
| No |
| Container process UID |
How to find UNRAID_API_KEY
Open the Unraid web UI.
Go to Settings → Management Access → API Keys.
Create a new key or copy an existing one.
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 sendAuthorization: Bearer <token>on every HTTP request. Generate withopenssl rand -hex 32orjust 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.
Transport modes
streamable-http— default; exposes an HTTP endpoint, requires Bearer token unless auth is disabledstdio— subprocess mode for Claude Code local plugin; no Bearer token neededsse— legacy Server-Sent Events; deprecated but functional
Credential files are loaded in priority order: ~/.unraid-mcp/.env first, then project .env as a fallback.
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 |
| Start development server via |
| Run full test suite |
| Run ruff linter |
| Run ruff formatter |
| Run pyright or mypy |
| Run live integration tests (requires a running Unraid server) |
| Start via Docker Compose |
| Stop Docker Compose containers |
| Tail Docker Compose container logs |
| Check |
| Generate a secure random Bearer token |
| Docker security, baked-env, and ignore-file checks |
| Create |
| Remove build artifacts and caches |
Verification
just lint
just typecheck
just testFor a stdio MCP smoke test:
uv run unraid-mcp-serverFor an HTTP health check after just up:
just healthThe 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 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 (http → ws, https → wss).
Related plugins
Plugin | Category | Description |
core | Core agents, commands, skills, and setup/health workflows for homelab management. | |
media | Search movies and TV shows, submit requests, and monitor failed requests via Overseerr. | |
infrastructure | Monitor and manage UniFi devices, clients, firewall rules, and network health. | |
utilities | Send and manage push notifications via a self-hosted Gotify server. | |
infrastructure | Create, edit, and manage SWAG nginx reverse proxy configurations. | |
infrastructure | Docker management (Flux) and SSH remote operations (Scout) across homelab hosts. | |
infrastructure | Manage Docker environments, containers, images, volumes, networks, and GitOps via Arcane. | |
infrastructure | Receive, index, and search syslog streams from all homelab hosts via SQLite FTS5. | |
dev-tools | Scaffold, review, align, and deploy homelab MCP plugins with agents and canonical templates. |
License
MIT
This server cannot be installed
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Appeared in Searches
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