🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

unraid-mcp

Package Overview
Dependencies
Maintainers
1
Versions
24
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

unraid-mcp

MCP Server for Unraid API - provides tools to interact with an Unraid server's GraphQL API

Source
pipPyPI
Version
2.9.0
Weekly downloads
2K
54.71%
Maintainers
1
Weekly downloads
 

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 agents/unraid-py/ 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 dinglebear-ai/unraid
/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 straight to the server via .mcp.json env, so no further setup is needed. To also persist them to ~/.unraid-mcp/.env (for running the server outside Claude Code), run uvx unraid-mcp setup plugin-hook — the plugin no longer ships hooks to do it for you.

Codex (plugin + marketplace)

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

codex plugin marketplace add dinglebear-ai/unraid
# 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/dinglebear-ai/unraid

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.

Configuration

Create .env from .env.example:

just setup

Environment variables

VariableRequiredDefaultDescription
UNRAID_API_URLYesGraphQL endpoint URL, e.g. https://tower.local/graphql
UNRAID_API_KEYYesUnraid API key (see below)
UNRAID_MCP_TRANSPORTNostreamable-httpTransport: streamable-http, stdio, or legacy sse (deprecated; removed in v3.0.0)
UNRAID_MCP_HOSTNo127.0.0.1 bare metal; Docker sets 0.0.0.0Bind address for HTTP transports
UNRAID_MCP_PORTNo6970Listen port for HTTP transports
UNRAID_MCP_MAX_RESPONSE_BYTESNo40000Max serialized tool-response size; over-cap responses return a parseable truncation marker
UNRAID_MCP_BEARER_TOKENConditionalStatic Bearer token for HTTP transports; auto-generated on first start if unset
UNRAID_MCP_DISABLE_HTTP_AUTHNofalseSet true to skip Bearer auth (use behind a reverse proxy that handles auth)
UNRAID_MCP_TRUST_PROXYConditionalfalseRequired when disabling HTTP auth while binding a non-loopback interface
UNRAID_MCP_GOOGLE_CLIENT_IDNoGoogle OAuth client ID; setting both client ID and secret enables OAuth for HTTP transports (required for claude.ai connectors). An explicitly set UNRAID_MCP_BEARER_TOKEN stays valid alongside OAuth
UNRAID_MCP_GOOGLE_CLIENT_SECRETNoGoogle OAuth client secret
UNRAID_MCP_GOOGLE_BASE_URLConditionalPublic server base URL, required when Google OAuth is enabled
UNRAID_MCP_GOOGLE_REQUIRED_SCOPESNoopenid + userinfo.emailComma/space-separated OAuth scopes
UNRAID_MCP_GOOGLE_ALLOWED_EMAILSConditionalVerified Google emails allowed to use the MCP server
UNRAID_MCP_GOOGLE_ALLOWED_DOMAINSConditionalVerified Google email domains allowed to use the MCP server
UNRAID_MCP_GOOGLE_ALLOW_ANY_USERNofalseExplicitly allow any verified Google account; only for private/trusted deployments
UNRAID_MCP_GOOGLE_REDIRECT_PATHNo/auth/callbackOAuth callback path configured in Google Cloud
UNRAID_MCP_GOOGLE_JWT_SIGNING_KEYConditionalWith the encryption key, enables restart-surviving encrypted token storage
UNRAID_MCP_GOOGLE_ENCRYPTION_KEYConditionalFernet key for encrypted OAuth token storage
UNRAID_MCP_GOOGLE_STORAGE_DIRNo~/.unraid-mcp/oauth-tokensDirectory for persisted encrypted OAuth tokens
UNRAID_VERIFY_SSLNotrueUpstream Unraid API TLS verification; may also be a CA-bundle path
UNRAID_ALLOW_INSECURE_TLSConditionalfalseRequired second opt-in when UNRAID_VERIFY_SSL=false
UNRAID_MCP_LOG_LEVELNoINFOLog verbosity: DEBUG, INFO, WARNING, ERROR, CRITICAL
UNRAID_MCP_LOG_FILENounraid-mcp.logLog filename under logs/ or /app/logs/ in Docker
UNRAID_AUTO_START_SUBSCRIPTIONSNotrueLazily initialize enabled subscriptions on first resource/diagnostic access
UNRAID_MAX_RECONNECT_ATTEMPTSNo10Max WebSocket reconnect attempts
UNRAID_AUTOSTART_LOG_PATHNoauto-detectLog file path for the lazily initialized log-tail subscription
UNRAID_MCP_ENABLE_RAW_SUBSCRIPTION_PROBENofalseDebug-only raw upstream frame in subscriptions/test_query; data-sensitive, never for shared deployments
UNRAID_SUBSCRIPTION_MAX_CONNECTIONSNo3Per-process concurrent subscription startup handshakes (1..32)
UNRAID_SUBSCRIPTION_STARTUP_STAGGER_SECONDSNo0.05Delay between startup launches (0..10 seconds)
UNRAID_SUBSCRIPTION_COLLECT_MAX_EVENTSNo100In-flight collection event ceiling (1..10000; limit may lower it)
UNRAID_SUBSCRIPTION_COLLECT_MAX_BYTESNo1048576In-flight serialized collection byte ceiling; response budget may lower it
UNRAID_SUBSCRIPTION_COLLECT_MAX_SECONDSNo30Maximum collect_for duration; configurable up to 300 seconds
UNRAID_SUBSCRIPTION_CACHE_MAX_AGE_SECONDSNo300Maximum usable cache age in seconds; configurable up to 86400
UNRAID_SUBSCRIPTION_TIMEOUT_MAX_SECONDSNo60Maximum per-call WebSocket timeout; configurable up to 300 seconds
UNRAID_CREDENTIALS_DIRNo~/.unraid-mcpOverride credentials directory
DOCKER_NETWORKNoExternal Docker network to join; leave blank for default bridge
PGIDNo1000Container process GID
PUIDNo1000Container 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

  • 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 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, emits a warning, and will be removed in v3.0.0. Migrate to streamable HTTP or place a compatibility proxy in front of it.

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/
├── src/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`
│       ├── scripts/             #   manual credential-setup script (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

ToolPurpose
unraidUnified 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.

SubactionDescriptionRequired params
overviewOS, CPU, memory layout, versions, machine ID
arrayArray state, capacity, disk health summary
networkAccess URLs, HTTP/HTTPS ports, LAN/WAN IPs
registrationLicense type, key file, expiration
variablesFull Unraid variable set (timezone, shares, etc.)
metricsCurrent CPU % and memory usage
network_metricsCurrent network throughput metrics from metrics.network
servicesRunning services with name, online status, version
displayCurrent UI theme name
display_detailsDirect display root metadata: case, theme, temperature display settings, thresholds, locale
configConfig validity and error state
onlineBoolean reachability check
ownerOwner username, avatar, profile URL
settingsUnified settings key/value map
serverSingle-call summary: hostname, uptime, Unraid version, array state
server_detailsDirect server root details with owner and URLs; API key omitted
serversAll registered servers with LAN/WAN IPs and URLs
network_access_urlsDirect network.accessUrls entries with type, name, IPv4, and IPv6
flashFlash drive vendor and product info
ups_devicesAll UPS devices with battery and power metrics
ups_deviceSingle UPS device detailsdevice_id
ups_configUPS daemon configuration
server_timeCurrent server time, time zone, and NTP config
timezonesAvailable IANA time-zone options (capped)
network_interfacesExtended network interface list with IPv4/IPv6 address details

health — 4 subactions

Connection and system health diagnostics.

SubactionDescriptionRequired params
checkComprehensive health: API latency, array state, alerts, Docker container summary
test_connectionPing the Unraid API and return latency in ms
diagnoseSubscription system status, error counts, reconnect state
setupReport credential status and print plugin/.env setup instructions

array — 14 subactions

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

SubactionDescriptionRequired paramsDestructive
parity_statusCurrent parity check progress, speed, errors
parity_historyPast parity check results
assignable_disksPhysical disks not yet in the array (pairs with add_disk)
parity_startStart a parity checkcorrect (bool)
parity_pausePause a running parity check
parity_resumeResume a paused parity check
parity_cancelCancel a running parity check
start_arrayStart the Unraid array
stop_arrayStop the Unraid arrayconfirm=True*
add_diskAdd a disk to the arraydisk_id; optional slot
remove_diskRemove a disk from the array (array must be stopped)disk_id, confirm=True*
mount_diskMount an array diskdisk_id
unmount_diskUnmount an array diskdisk_id
clear_disk_statsClear 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 *.

SubactionDescriptionRequired paramsDestructive
sharesAll user shares with size, allocation settings, LUKS status
disksPhysical disk list (ID, device, name)
disk_detailsSingle disk: serial, size, temperaturedisk_id
log_filesList available log files (name, path, size, modified)
logsRead log file content with line rangelog_path; optional tail_lines (default 100, max 10000)
flash_backupInitiate rclone backup of the flash drive to a remoteremote_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 — 27 subactions

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

SubactionDescriptionRequired paramsDestructive
listAll containers: ID, names, image, state, status, autoStart
detailsFull container detail: ports, mounts, labels, network settingscontainer_id
logsStructured container log lines with timestamps and a continuation cursorcontainer_id; optional tail_lines (default 100, max 10000)
check_updatesCurrent image-update status for every container
portsAll host port bindings across running containers, sorted by (host_port, protocol).
startStart a containercontainer_id
stopStop a containercontainer_id
restartStop then start a container (stop + start in sequence)container_id
unpauseUnpause a paused containercontainer_id
remove_containerRemove a container (optionally its image via with_image)container_id, confirm=True*
update_containerApply a pending image update to one containercontainer_id
update_containersApply image updates to several containerscontainer_ids
update_all_containersApply all pending container image updates
update_autostartSet container autostart configautostart_entries ([{id, autoStart, wait?}])
refresh_digestsRefresh image digests (recheck for updates)
sync_template_pathsSync Docker template paths
reset_template_mappingsReset template path mappings to defaultsconfirm=True*
create_folderCreate an organizer folderorganizer_input ({name, …})
create_folder_with_itemsCreate a folder containing itemsorganizer_input
rename_folderRename a folderorganizer_input ({folderId, newName})
set_folder_childrenSet a folder's childrenorganizer_input ({childrenIds, …})
delete_entriesDelete organizer entriesorganizer_input ({entryIds}), confirm=True*
move_entries_to_folderMove entries into a folderorganizer_input
move_items_to_positionMove items to a positionorganizer_input
update_view_preferencesUpdate organizer view preferencesorganizer_input ({prefs, …})
networksAll Docker networks: ID, name, driver, scope
network_detailsSingle network with IPv6, containers, options, labelsnetwork_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 *.

SubactionDescriptionRequired paramsDestructive
listAll VMs: ID, name, state, UUID
detailsSingle VM detailsvm_id
startStart a VMvm_id
stopGracefully stop a VMvm_id
pausePause a running VMvm_id
resumeResume a paused VMvm_id
rebootReboot a VMvm_id
force_stopHard power-off a VM (data loss possible)vm_id, confirm=True*
resetHard reset a VM without graceful shutdownvm_id, confirm=True*

vm_id accepts UUID, prefixed ID, or VM name.

notification — 13 subactions

System notification CRUD. Destructive subactions marked with *.

SubactionDescriptionRequired paramsDestructive
overviewUnread and archive counts by importance (INFO/WARNING/ALERT)
listPaginated notification listlist_type (UNREAD or ARCHIVE, default UNREAD); optional importance, offset, limit
createCreate a notificationtitle (≤200), subject (≤500), description (≤2000), importance (INFO/WARNING/ALERT)
notify_if_uniqueCreate a notification only if an identical one does not already existtitle, subject, description, importance
archiveArchive a single notificationnotification_id
mark_unreadMove an archived notification back to unreadnotification_id
recalculateRecalculate the overview counts
archive_allArchive all unread notificationsoptional importance to filter
archive_manyArchive specific notifications by IDnotification_ids (list)
unarchive_manyUnarchive specific notifications by IDnotification_ids (list)
unarchive_allMove all archived notifications back to unreadoptional importance to filter
deletePermanently delete a single notificationnotification_id, notification_type, confirm=True*
delete_archivedPermanently delete all archived notificationsconfirm=True*

key — 13 subactions

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

SubactionDescriptionRequired paramsDestructive
listAll API keys with roles and permissions
getSingle API key detailskey_id
possible_rolesAll assignable roles
possible_permissionsAll grantable resource/action permissions
permissions_for_rolesPermissions implied by given rolesroles
preview_permissionsEffective permissions for roles and/or permissionsroles and/or permissions_input ([{resource, actions}])
auth_actionsAll available auth actions
creation_form_schemaJSON-schema form for key creation
createCreate an API keyname; optional roles, permissions
updateUpdate name, roles, or permissionskey_id; optional name, roles, permissions
deleteDelete an API key (immediately revokes access)key_id, confirm=True*
add_roleAdd a role to an existing keykey_id, roles (first element used)
remove_roleRemove a role from an existing keykey_id, roles (first element used)

plugin — 8 subactions

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

SubactionDescriptionRequired paramsDestructive
listAll installed plugins with version and module flags
installed_unraidRaw installed .plg filenames
install_operationsList async plugin-install operations
install_operationStatus of one install operationoperation_id
addInstall plugins by namenames (list); optional bundled, restart
removeUninstall plugins by name (irreversible without re-install)names (list), confirm=True*
installAsync-install a .plg URL — runs code as root (poll via install_operation)url, confirm=True; optional plugin_name, forced*
install_languageAsync-install a language pack — runs code as rooturl, confirm=True*

rclone — 4 subactions

Cloud storage remote management. Destructive subactions marked with *.

SubactionDescriptionRequired paramsDestructive
list_remotesAll configured rclone remotes with type and parameters
config_formConfig form schema for a provider typeoptional provider_type
create_remoteCreate a new rclone remotename, provider_type, config_data (dict of string/number/bool; max 50 keys)
delete_remoteDelete 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 *.

SubactionDescriptionRequired paramsDestructive
updateUpdate system settings (JSON key/value input)settings_input (dict; max 100 keys, scalar values only)
configure_upsOverwrite UPS monitoring configurationups_config (dict), confirm=True*
update_sshUpdate SSH daemon settings (can cut off shell access)config_input ({enabled, port}), confirm=True*
update_temperatureUpdate temperature sensor configurationconfig_input
update_system_timeUpdate timezone / NTP / manual time — can invalidate TLS certsconfig_input, confirm=True*
update_server_identityUpdate server name, comment, and modelname; optional comment, sys_model

connect — 8 subactions

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

SubactionDescriptionRequired paramsDestructive
remote_accessCurrent remote-access settings (type, forward, port)
cloudUnraid Connect / cloud status (relay, minigraph, key validity)
statusDirect connect root status: dynamic remote access and settings schema; settings values omitted
update_api_settingsUpdate Connect API settings (affects internet reachability)connect_input ({accessType?, forwardType?, port?}), confirm=True*
sign_inSign the server in to Unraid Connect — registers with the cloudconnect_input ({apiKey, userInfo?}), confirm=True*
sign_outSign the server out of Unraid Connectconfirm=True*
setup_remote_accessConfigure remote access — can expose the server to the internetconnect_input, confirm=True*
enable_dynamic_remote_accessToggle dynamic remote accessconnect_input ({url, enabled}), confirm=True*

customization — 6 subactions

UI theme, locale, and SSO state.

SubactionDescriptionRequired params
public_themePublic-facing theme (also the server's current theme)
is_initial_setupWhether this is a fresh install (isFreshInstall)
sso_enabledWhether SSO is enabled
detailsDirect customization root onboarding/language details; activation-code values omitted
set_themeSet the active UI themetheme_name
set_localeSet the UI localelocale

oidc — 5 subactions

OpenID Connect / SSO provider management.

SubactionDescriptionRequired params
providersAll OIDC providers with client ID, scopes, auth rules
providerSingle provider detailsprovider_id
configurationOIDC configuration with default allowed origins
public_providersPublic provider list (button text, icon, style)
validate_sessionValidate an OIDC session tokentoken

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 *.

SubactionDescriptionRequired paramsDestructive
internal_boot_contextInternal boot / first-boot context
completeMark onboarding complete
openOpen the onboarding flow
closeClose the onboarding flow
resumeResume onboarding
bypassBypass onboarding
resetReset onboarding/setup stateconfirm=True*
set_overrideSet an onboarding overrideonboarding_input
clear_overrideClear the onboarding override
refresh_internal_boot_contextRecompute the internal boot context
create_internal_boot_poolCreate an internal boot pool — FORMATS devices, may REBOOTonboarding_input, confirm=True*

user — 1 subaction

SubactionDescriptionRequired params
meAuthenticated 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 retains events only until collect_for expires, the stream completes, or the effective event/byte budget is reached. The iterator closes immediately at a bound; retention is bounded while streaming, not only when the response is shaped.
SubactionModeDescriptionRequired params
cpuSnapshotCPU utilization: total % and per-core breakdown
memorySnapshotMemory: total, used, free, swap, percentages
cpu_telemetrySnapshotCPU power draw and temperature
array_stateSnapshotArray state, capacity, parity check status
parity_progressSnapshot (event-driven)Parity check progress, speed, errors
ups_statusSnapshot (event-driven)UPS battery, charge, runtime, power load
notifications_overviewSnapshot (event-driven)Notification counts by importance
notifications_warningsSnapshot (event-driven)Warnings/alerts feed (filtered)
ownerSnapshot (event-driven)Owner profile changes
server_statusSnapshot (event-driven)Server registration and connectivity
displaySnapshot (event-driven)Theme/display changes
docker_container_statsSnapshotPer-container CPU/memory/IO stats
temperatureSnapshotTemperature sensor readings
network_metricsSnapshotNetwork throughput metrics
log_tailCollectStream log file linespath (must start with /var/log/ or /boot/logs/)
notification_feedCollectStream incoming notifications
plugin_install_updatesCollectStream plugin-install progress eventsoperation_id (required)

Optional parameters for live:

  • collect_for (float, default 5.0) — greater than 0 and at most UNRAID_SUBSCRIPTION_COLLECT_MAX_SECONDS (default 30 seconds)
  • timeout (float, default 10.0) — greater than 0 and at most UNRAID_SUBSCRIPTION_TIMEOUT_MAX_SECONDS (default 60 seconds)

Collection retains at most min(positive limit, UNRAID_SUBSCRIPTION_COLLECT_MAX_EVENTS) events (default 100) and at most the smaller of UNRAID_SUBSCRIPTION_COLLECT_MAX_BYTES (default 1 MiB) and half the configured MCP response budget (20 KiB by default). Responses include page.returned, page.total, page.truncated, and a hint when response capping truncates results. These response fields are distinct from the earlier in-flight streaming limits.

subscriptions — 2 subactions (WebSocket diagnostics)

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

SubactionDescriptionRequired params
diagnoseFull diagnostic dump: auto-start status, reconnect config, per-subscription state (active, last error, data received), error counts, and troubleshooting recommendations
test_querySend a raw GraphQL subscription string directly over WebSocket to debug schema/field issuessubscription_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.

ActionSubactionNotes
arraystop_arrayUnmounts shares; stop containers and VMs first
arrayremove_diskArray must be stopped first
arrayclear_disk_statsI/O stats are permanently erased
vmforce_stopHard power-off; unsaved data may be lost
vmresetHard reset; unsaved data may be lost
notificationdeletePermanent; requires notification_type
notificationdelete_archivedWipes all archived notifications
rclonedelete_remoteRemoves config only; does not delete remote data
keydeleteImmediately revokes all clients using that key
diskflash_backupOverwrites destination; configure a dedicated remote
settingconfigure_upsOverwrites UPS daemon config
settingupdate_sshCan cut off remote shell access (disable SSH / change port)
settingupdate_system_timeClock changes can invalidate TLS certs / break time-sensitive services
pluginremoveIrreversible without re-install
plugininstall / install_languageFetches and runs a .plg from a URL as root
connectsign_inRegisters the server with the Unraid Connect cloud
connectupdate_api_settingsChanges remote-access posture / internet reachability
dockerremove_containerRemoves a container (and optionally its image)
dockerreset_template_mappingsResets Docker template path mappings to defaults
dockerdelete_entriesDeletes Docker organizer entries
connectsign_outSigns the server out of Unraid Connect
connectsetup_remote_accessReconfigures remote access; can expose the server
connectenable_dynamic_remote_accessToggles dynamic remote access
onboardingresetResets onboarding/setup state
onboardingcreate_internal_boot_poolFormats devices and may reboot the server

Tool parameters reference

ParameterTypeUsed by
actionstrall
subactionstrall
confirmbool (default False)destructive subactions
device_idstrsystem/ups_device
disk_idstrarray, disk
correctboolarray/parity_start
slotintarray/add_disk
log_pathstrdisk/logs
tail_linesint (default 100, max 10000)disk/logs, docker/logs
remote_namestrdisk/flash_backup
source_pathstrdisk/flash_backup
destination_pathstrdisk/flash_backup
backup_optionsdictdisk/flash_backup
container_idstrdocker mutations and details
container_idslist[str]docker/update_containers
with_imagebool (default False)docker/remove_container
autostart_entrieslist[dict]docker/update_autostart
organizer_inputdictdocker organizer subactions
network_idstrdocker/network_details
vm_idstrvm (all except list)
notification_idstrnotification/archive, mark_unread, delete
notification_idslist[str]notification/archive_many, unarchive_many
notification_typestr (UNREAD/ARCHIVE)notification/delete
importancestr (INFO/WARNING/ALERT)notification filter and create
list_typestr (UNREAD/ARCHIVE, default UNREAD)notification/list
titlestr (≤200)notification/create
subjectstr (≤500)notification/create
descriptionstr (≤2000)notification/create
offsetint (default 0)notification/list
limitint (default 20)notification/list
key_idstrkey subactions
namestrkey/create, key/update, rclone
roleslist[str]key subactions
permissionslist[str]key subactions
permissions_inputlist[dict]key/preview_permissions
nameslist[str]plugin/add, plugin/remove
bundledbool (default False)plugin/add, plugin/remove
restartbool (default True)plugin/add, plugin/remove
urlstrplugin/install, plugin/install_language
plugin_namestrplugin/install
forcedbool (default False)plugin/install
operation_idstrplugin/install_operation
provider_typestrrclone/config_form, rclone/create_remote
config_datadictrclone/create_remote
settings_inputdictsetting/update
ups_configdictsetting/configure_ups
config_inputdictsetting/update_ssh, update_temperature, update_system_time
commentstrsetting/update_server_identity
sys_modelstrsetting/update_server_identity
connect_inputdictconnect mutations
onboarding_inputdictonboarding/set_override, create_internal_boot_pool
theme_namestrcustomization/set_theme
localestrcustomization/set_locale
provider_idstroidc/provider
tokenstroidc/validate_session
pathstrlive/log_tail
subscription_querystrsubscriptions/test_query
collect_forfloat (default 5.0)live collect-mode subactions
timeoutfloat (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

CommandEffect
just devStart development server via uv run python -m unraid_mcp
just testRun full test suite
just lintRun ruff linter
just fmtRun ruff formatter
just typecheckRun the ty type checker (uv run ty check src/, matches CI)
just test-liveRun live integration tests (requires a running Unraid server)
just upStart via Docker Compose
just downStop Docker Compose containers
just logsTail Docker Compose container logs
just healthCheck /health endpoint
just gen-tokenGenerate a secure random Bearer token
just check-contractDocker security, baked-env, and ignore-file checks
just setupCreate .env from .env.example if missing
just cleanRemove 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:

RootUsed by
infosystem/overview, system/display, health check
arraysystem/array, array/*
varssystem/network, system/variables
metricssystem/metrics
servicessystem/services
displaysystem/display_details (safe direct root)
serverssystem/servers, system/network
networksystem/network_access_urls (safe direct root)
serversystem/server_details (safe direct root; API key omitted)
registrationsystem/registration
onlinesystem/online, health/test_connection
ownersystem/owner
settingssystem/settings
flashsystem/flash
upsDevices / upsDeviceByIdsystem/ups_devices, system/ups_device
upsConfigurationsystem/ups_config
parityHistoryarray/parity_history
disk / disksdisk/disk_details, disk/disks
sharesdisk/shares
logFiles / logFiledisk/log_files, disk/logs
docker.containers / docker.networksdocker/*
vmsvm/*
notificationsnotification/*
apiKeys / apiKeykey/*
pluginsplugin/list
rclonerclone/*
connectconnect/status (safe direct root; settings values omitted), connect/*
customizationcustomization/details (safe direct root; activation-code values omitted), customization/*
oidcProviders / oidcConfigurationoidc/*
meuser/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).

PluginCategoryDescription
homelab-corecoreCore agents, commands, skills, and setup/health workflows for homelab management.
overseerr-mcpmediaSearch movies and TV shows, submit requests, and monitor failed requests via Overseerr.
unifi-mcpinfrastructureMonitor and manage UniFi devices, clients, firewall rules, and network health.
gotify-mcputilitiesSend and manage push notifications via a self-hosted Gotify server.
swag-mcpinfrastructureCreate, edit, and manage SWAG nginx reverse proxy configurations.
synapse-mcpinfrastructureDocker management (Flux) and SSH remote operations (Scout) across homelab hosts.
arcane-mcpinfrastructureManage Docker environments, containers, images, volumes, networks, and GitOps via Arcane.
syslog-mcpinfrastructureReceive, index, and search syslog streams from all homelab hosts via SQLite FTS5.
plugin-labdev-toolsScaffold, review, align, and deploy homelab MCP plugins with agents and canonical templates.

License

MIT

Keywords

api

FAQs

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts