AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
MCP verified MIT Self-run

Unraid Mcp

mcp-jmagar-unraid-mcp · by jmagar

Query, monitor, and manage Unraid servers via GraphQL API through MCP tools. Supports system info, Docker, VMs, array/parity, notifications, plugins, rclone, and live telemetry.

No reviews yet
0 installs
20 views
0.0% view→install

Install

$ agentstack add mcp-jmagar-unraid-mcp

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access Used
  • Filesystem access No
  • Shell / process execution Used
  • Environment & secrets Used
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/mcp-jmagar-unraid-mcp)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
1mo ago

Declared compatibility

Claude CodeClaude DesktopCursorWindsurf

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Unraid Mcp? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Unraid MCP

[](https://pypi.org/project/unraid-mcp/) [](https://github.com/jmagar/unraid-mcp/pkgs/container/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.

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](docs/mcp/CONNECT.md#claude-desktop-via-mcp-remote-proxy) for the macOS/Linux and Windows config snippets.

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/mcp/ENV.md), [docs/CONFIG.md](docs/CONFIG.md), and [docs/AUTHENTICATION.md](docs/AUTHENTICATION.md).

How to find UNRAIDAPIKEY

  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.

UNRAIDAPIKEY vs UNRAIDMCPBEARER_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 on every HTTP request. Generate with openssl rand -hex 32 or just gen-token.

UNRAIDMCPDISABLEHTTPAUTH

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 Gra

Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.