Skip to content

jmagar/unraid-mcp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

177 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸš€ Unraid MCP Server

Python Version FastMCP License

A powerful MCP (Model Context Protocol) server that provides comprehensive tools to interact with an Unraid server's GraphQL API.

✨ Features

  • πŸ”§ 1 primary tool + 2 diagnostic tools, 107 subactions: Complete Unraid management through a consolidated MCP tool
  • πŸ—οΈ Modular Architecture: Clean, maintainable, and extensible codebase
  • ⚑ High Performance: Async/concurrent operations with optimized timeouts
  • πŸ”„ Real-time Data: WebSocket subscriptions for live metrics, logs, array state, and more
  • πŸ“Š Health Monitoring: Comprehensive system diagnostics and status
  • πŸ”’ Secure: Network-layer isolation
  • πŸ“ Rich Logging: Structured logging with rotation and multiple levels

πŸ“‹ Table of Contents


🎯 Claude Code Plugin

The easiest way to use Unraid MCP is through the Claude Code marketplace:

# Add the marketplace
/plugin marketplace add jmagar/unraid-mcp

# Install the Unraid skill
/plugin install unraid @unraid-mcp

This provides instant access to Unraid monitoring and management through Claude Code with:

  • 1 primary MCP tool (unraid) exposing 107 subactions via action + subaction routing, plus diagnose_subscriptions and test_subscription_query diagnostic tools
  • Real-time system metrics and health monitoring
  • Docker container and VM lifecycle management
  • Disk health monitoring and storage management

See .claude-plugin/README.md for detailed plugin documentation.

βš™οΈ Credential Setup

Credentials are stored in ~/.unraid-mcp/.env β€” one location that works for the Claude Code plugin and direct uv run invocations.

Option 1 β€” Interactive (Claude Code plugin, elicitation-supported clients):

unraid(action="health", subaction="setup")

The server prompts for your API URL and key, writes ~/.unraid-mcp/.env automatically (created with mode 700/600), and activates credentials without restart.

Option 2 β€” Manual:

mkdir -p ~/.unraid-mcp && chmod 700 ~/.unraid-mcp
cp .env.example ~/.unraid-mcp/.env && chmod 600 ~/.unraid-mcp/.env
# Edit ~/.unraid-mcp/.env with your values:
#   UNRAID_API_URL=https://10-1-0-2.xxx.myunraid.net:31337
#   UNRAID_API_KEY=your-key-from-unraid-settings

Finding your API key: Unraid β†’ Settings β†’ Management Access β†’ API Keys


πŸš€ Quick Start

Prerequisites

  • Python 3.12+ with uv for development
  • Unraid server with GraphQL API enabled

1. Clone Repository

git clone https://github.com/jmagar/unraid-mcp
cd unraid-mcp

2. Configure Environment

# Canonical credential location (all runtimes)
mkdir -p ~/.unraid-mcp && chmod 700 ~/.unraid-mcp
cp .env.example ~/.unraid-mcp/.env && chmod 600 ~/.unraid-mcp/.env
# Edit ~/.unraid-mcp/.env with your values

# For local development only
cp .env.example .env

3. Run for Development

# Install dependencies
uv sync

# Run development server
uv run unraid-mcp-server

πŸ“‚ Plugin Structure

This repository is a Claude Code plugin. Key components:

unraid-mcp/                      # ${CLAUDE_PLUGIN_ROOT}
β”œβ”€β”€ .claude-plugin/
β”‚   β”œβ”€β”€ marketplace.json         # Marketplace catalog
β”‚   └── plugin.json              # Plugin manifest
β”œβ”€β”€ unraid_mcp/                  # MCP server Python package
β”œβ”€β”€ skills/unraid/               # Skill and documentation
β”œβ”€β”€ pyproject.toml               # Dependencies and entry points
└── scripts/                     # Validation and helper scripts
  • MCP Server: 3 tools β€” unraid (107 subactions) + diagnose_subscriptions + test_subscription_query
  • Skill: /unraid skill for monitoring and queries
  • Entry Point: unraid-mcp-server defined in pyproject.toml

πŸ“¦ Installation

πŸ”§ Development Installation

For development and testing:

# Clone repository
git clone https://github.com/jmagar/unraid-mcp
cd unraid-mcp

# Install dependencies with uv
uv sync

# Install development dependencies  
uv sync --group dev

# Configure environment
cp .env.example .env
# Edit .env with your settings

# Run development server
uv run unraid-mcp-server

βš™οΈ Configuration

Environment Variables

Credentials and settings go in ~/.unraid-mcp/.env (the canonical location loaded by all runtimes β€” plugin and direct uv run). See the Credential Setup section above for how to create it.

# Core API Configuration (Required)
UNRAID_API_URL=https://your-unraid-server-url/graphql
UNRAID_API_KEY=your_unraid_api_key

# MCP Server Settings
UNRAID_MCP_TRANSPORT=stdio  # stdio (default)
UNRAID_MCP_HOST=0.0.0.0
UNRAID_MCP_PORT=6970

# Logging Configuration
UNRAID_MCP_LOG_LEVEL=INFO  # DEBUG, INFO, WARNING, ERROR
UNRAID_MCP_LOG_FILE=unraid-mcp.log

# SSL/TLS Configuration
UNRAID_VERIFY_SSL=true  # true, false, or path to CA bundle

# Subscription Configuration
UNRAID_AUTO_START_SUBSCRIPTIONS=true  # Auto-start WebSocket subscriptions on startup (default: true)
UNRAID_MAX_RECONNECT_ATTEMPTS=10      # Max WebSocket reconnection attempts (default: 10)

# Optional: Auto-start log file subscription path
# Defaults to /var/log/syslog if it exists and this is unset
# UNRAID_AUTOSTART_LOG_PATH=/var/log/syslog

# Optional: Credentials directory override (default: ~/.unraid-mcp/)
# Useful for containers or non-standard home directory layouts
# UNRAID_CREDENTIALS_DIR=/custom/path/to/credentials

πŸ› οΈ Available Tools & Resources

The single unraid tool uses action (domain) + subaction (operation) routing to expose all operations via one MCP tool, minimizing context window usage. Destructive actions require confirm=True.

Primary Tool: 15 Domains, 107 Subactions

Call pattern: unraid(action="<domain>", subaction="<operation>")

action= Subactions Description
system overview, array, network, registration, variables, metrics, services, display, config, online, owner, settings, server, servers, flash, ups_devices, ups_device, ups_config Server info, metrics, network, UPS (18 subactions)
health check, test_connection, diagnose, setup Health checks, connection test, diagnostics, interactive setup (4 subactions)
array parity_status, parity_history, parity_start, parity_pause, parity_resume, parity_cancel, start_array, stop_array, add_disk, remove_disk, mount_disk, unmount_disk, clear_disk_stats Parity checks, array state, disk operations (13 subactions)
disk shares, disks, disk_details, log_files, logs, flash_backup Shares, physical disks, log files (6 subactions)
docker list, details, start, stop, restart, networks, network_details Container lifecycle and network inspection (7 subactions)
vm list, details, start, stop, pause, resume, force_stop, reboot, reset Virtual machine lifecycle (9 subactions)
notification overview, list, create, archive, mark_unread, delete, delete_archived, archive_all, archive_many, unarchive_many, unarchive_all, recalculate System notifications CRUD (12 subactions)
key list, get, create, update, delete, add_role, remove_role API key management (7 subactions)
plugin list, add, remove Plugin management (3 subactions)
rclone list_remotes, config_form, create_remote, delete_remote Cloud storage remote management (4 subactions)
setting update, configure_ups System settings and UPS config (2 subactions)
customization theme, public_theme, is_initial_setup, sso_enabled, set_theme Theme and UI customization (5 subactions)
oidc providers, provider, configuration, public_providers, validate_session OIDC/SSO provider management (5 subactions)
user me Current authenticated user (1 subaction)
live cpu, memory, cpu_telemetry, array_state, parity_progress, ups_status, notifications_overview, owner, server_status, log_tail, notification_feed Real-time WebSocket subscription snapshots (11 subactions)

Destructive Actions (require confirm=True)

  • array: stop_array, remove_disk, clear_disk_stats
  • vm: force_stop, reset
  • notification: delete, delete_archived
  • rclone: delete_remote
  • key: delete
  • disk: flash_backup
  • setting: configure_ups
  • plugin: remove

MCP Resources (Real-time Cached Data)

The server exposes two classes of MCP resources backed by persistent WebSocket connections:

unraid://live/* β€” 9 snapshot resources (auto-started, always-cached):

  • unraid://live/cpu β€” CPU utilization
  • unraid://live/memory β€” Memory usage
  • unraid://live/cpu_telemetry β€” Detailed CPU telemetry
  • unraid://live/array_state β€” Array state changes
  • unraid://live/parity_progress β€” Parity check progress
  • unraid://live/ups_status β€” UPS status
  • unraid://live/notifications_overview β€” Notification counts
  • unraid://live/owner β€” Owner info changes
  • unraid://live/server_status β€” Server status changes

unraid://logs/stream β€” Live log file tail (path controlled by UNRAID_AUTOSTART_LOG_PATH)

Note: Resources return cached data from persistent WebSocket subscriptions. A {"status": "connecting"} placeholder is returned while the subscription initializes β€” retry in a moment.

log_tail is accessible as a tool subaction (unraid(action="live", subaction="log_tail", path="/var/log/syslog")) and requires a path; notification_feed is also available as a tool subaction but uses a transient one-shot subscription and accepts optional parameters. Neither is registered as an MCP resource.

Security note: The disk/logs and live/log_tail subactions allow reading files under /var/log/ and /boot/logs/ on the Unraid server. Authenticated MCP clients can stream any log file within these directories.


πŸ”§ Development

Project Structure

unraid-mcp/
β”œβ”€β”€ unraid_mcp/               # Main package
β”‚   β”œβ”€β”€ main.py               # Entry point
β”‚   β”œβ”€β”€ server.py             # FastMCP server setup
β”‚   β”œβ”€β”€ version.py            # Version management (importlib.metadata)
β”‚   β”œβ”€β”€ config/               # Configuration management
β”‚   β”‚   β”œβ”€β”€ settings.py       # Environment & settings
β”‚   β”‚   └── logging.py        # Logging setup
β”‚   β”œβ”€β”€ core/                 # Core infrastructure
β”‚   β”‚   β”œβ”€β”€ client.py         # GraphQL client
β”‚   β”‚   β”œβ”€β”€ exceptions.py     # Custom exceptions
β”‚   β”‚   β”œβ”€β”€ guards.py         # Destructive action guards
β”‚   β”‚   β”œβ”€β”€ setup.py          # Interactive credential setup
β”‚   β”‚   β”œβ”€β”€ types.py          # Shared data types
β”‚   β”‚   └── utils.py          # Utility functions
β”‚   β”œβ”€β”€ subscriptions/        # Real-time subscriptions
β”‚   β”‚   β”œβ”€β”€ manager.py        # Persistent WebSocket manager
β”‚   β”‚   β”œβ”€β”€ resources.py      # MCP resources (unraid://live/*)
β”‚   β”‚   β”œβ”€β”€ snapshot.py       # Transient subscribe_once helpers
β”‚   β”‚   β”œβ”€β”€ queries.py        # Subscription query constants
β”‚   β”‚   β”œβ”€β”€ diagnostics.py    # Diagnostic tools
β”‚   β”‚   └── utils.py          # Subscription utility functions
β”‚   └── tools/                # Consolidated tools (unraid: 107 subactions + 2 diagnostic tools)
β”‚       └── unraid.py         # All 15 domains in one file
β”œβ”€β”€ tests/                    # Test suite
β”‚   β”œβ”€β”€ conftest.py           # Shared fixtures
β”‚   β”œβ”€β”€ test_*.py             # Unit tests (per domain)
β”‚   β”œβ”€β”€ http_layer/           # httpx-level request tests
β”‚   β”œβ”€β”€ integration/          # WebSocket lifecycle tests
β”‚   β”œβ”€β”€ safety/               # Destructive action guard tests
β”‚   └── schema/               # GraphQL query validation
β”œβ”€β”€ docs/                     # Documentation & API references
β”œβ”€β”€ scripts/                  # Build and utility scripts
β”œβ”€β”€ skills/unraid/            # Claude skill assets
β”œβ”€β”€ .claude-plugin/           # Plugin manifest & marketplace config
β”œβ”€β”€ .env.example              # Environment template
β”œβ”€β”€ pyproject.toml            # Project config & dependencies
└── logs/                     # Log files (auto-created, gitignored)

Code Quality Commands

# Lint and format code
uv run ruff check unraid_mcp/
uv run ruff format unraid_mcp/

# Type checking
uv run ty check unraid_mcp/

# Run tests
uv run pytest

Integration Smoke-Tests (mcporter)

Live integration tests that exercise all non-destructive actions via mcporter.

# stdio β€” no running server needed (good for CI)
./tests/mcporter/test-tools.sh [--parallel] [--timeout-ms N] [--verbose]

Destructive actions are always skipped. For safe testing strategies and exact mcporter commands per destructive action, see docs/DESTRUCTIVE_ACTIONS.md.

API Schema Docs Automation

# Regenerate complete GraphQL schema reference from live introspection
set -a; source .env; set +a
uv run python scripts/generate_unraid_api_reference.py

This updates docs/UNRAID_API_COMPLETE_REFERENCE.md with all operations, directives, and types visible to your API key.

Optional cron example (daily at 03:15):

15 3 * * * cd /path/to/unraid-mcp && /usr/bin/env bash -lc 'set -a; source .env; set +a; uv run python scripts/generate_unraid_api_reference.py && git add docs/UNRAID_API_COMPLETE_REFERENCE.md && git commit -m "docs: refresh unraid graphql schema"'

Development Workflow

# Start development server
uv run unraid-mcp-server

# Or run via module directly
uv run -m unraid_mcp.main

# Run via named config files
fastmcp run fastmcp.stdio.json  # stdio transport

Ad-hoc Tool Testing (fastmcp CLI)

# Call without a running server (stdio config)
fastmcp list fastmcp.stdio.json
fastmcp call fastmcp.stdio.json unraid action=health subaction=check

πŸ—οΈ Architecture

Core Principles

  • Modular Design: Separate concerns across focused modules
  • Async First: All operations are non-blocking and concurrent-safe
  • Error Resilience: Comprehensive error handling with graceful degradation
  • Configuration Driven: Environment-based configuration with validation
  • Observability: Structured logging and health monitoring

Key Components

Component Purpose
FastMCP Server MCP protocol implementation and tool registration
GraphQL Client Async HTTP client with timeout management
Subscription Manager WebSocket connections for real-time data
Tool Modules Domain-specific business logic (Docker, VMs, etc.)
Configuration System Environment loading and validation
Logging Framework Structured logging with file rotation

πŸ› Troubleshooting

Common Issues

πŸ”₯ Port Already in Use

# Kill existing process on port 6970, then restart
lsof -ti :6970 | xargs kill -9 2>/dev/null; uv run unraid-mcp-server

πŸ”§ Connection Refused

# Check Unraid API configuration
curl -k "${UNRAID_API_URL}" -H "X-API-Key: ${UNRAID_API_KEY}"

πŸ“ Import Errors

# Reinstall dependencies
uv sync --reinstall

πŸ” Debug Mode

# Enable debug logging
export UNRAID_MCP_LOG_LEVEL=DEBUG
uv run unraid-mcp-server

Health Check

# Use the built-in health check tool via MCP client
# or check logs at: logs/unraid-mcp.log

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.


🀝 Contributing

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/amazing-feature
  3. Run tests: uv run pytest
  4. Commit changes: git commit -m 'Add amazing feature'
  5. Push to branch: git push origin feature/amazing-feature
  6. Open a Pull Request

πŸ“ž Support

  • πŸ“š Documentation: Check inline code documentation
  • πŸ› Issues: GitHub Issues
  • πŸ’¬ Discussions: Use GitHub Discussions for questions

Built with ❀️ for the Unraid community

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors