mirror of
https://github.com/jmagar/unraid-mcp.git
synced 2026-03-23 12:39:24 -07:00
fix: address all 17 PR review comments
Resolves review threads: - PRRT_kwDOO6Hdxs50fewG (setup.py): non-eliciting clients now return True from elicit_reset_confirmation so they can reconfigure without being blocked - PRRT_kwDOO6Hdxs50fewM (test-tools.sh): add notification/recalculate smoke test - PRRT_kwDOO6Hdxs50fewP (test-tools.sh): add system/array smoke test - PRRT_kwDOO6Hdxs50fewT (resources.py): surface manager error state instead of reporting 'connecting' for permanently failed subscriptions - PRRT_kwDOO6Hdxs50feAj (resources.py): use is not None check for empty cached dicts - PRRT_kwDOO6Hdxs50fewY (integration tests): remove duplicate snapshot-registration tests already covered in test_resources.py - PRRT_kwDOO6Hdxs50fewe (test_resources.py): replace brittle import-detail test with behavior tests for connecting/error states - PRRT_kwDOO6Hdxs50fewh (test_customization.py): strengthen public_theme assertion - PRRT_kwDOO6Hdxs50fewk (test_customization.py): strengthen theme assertion - PRRT_kwDOO6Hdxs50fewo (__init__.py): correct subaction count ~88 -> ~107 - PRRT_kwDOO6Hdxs50fewx (test_oidc.py): assert providers list value directly - PRRT_kwDOO6Hdxs50fewz (unraid.py): remove unreachable raise after vm handler - PRRT_kwDOO6Hdxs50few2 (unraid.py): remove unreachable raise after docker handler - PRRT_kwDOO6Hdxs50fev8 (CLAUDE.md): replace legacy 15-tool table with unified unraid action/subaction table - PRRT_kwDOO6Hdxs50fev_ (test_oidc.py): assert providers + defaultAllowedOrigins - PRRT_kwDOO6Hdxs50feAz (CLAUDE.md): update tool categories to unified API shape - PRRT_kwDOO6Hdxs50feBE (CLAUDE.md/setup.py): update unraid_health refs to unraid(action=health, subaction=setup)
This commit is contained in:
@@ -1,210 +1,292 @@
|
||||
---
|
||||
name: unraid
|
||||
description: "Query and monitor Unraid servers via the GraphQL API. Use when the user asks to 'check Unraid', 'monitor Unraid', 'Unraid API', 'get Unraid status', 'check disk temperatures', 'read Unraid logs', 'list Unraid shares', 'Unraid array status', 'Unraid containers', 'Unraid VMs', or mentions Unraid system monitoring, disk health, parity checks, or server status."
|
||||
description: "This skill should be used when the user mentions Unraid, asks to check server health, monitor array or disk status, list or restart Docker containers, start or stop VMs, read system logs, check parity status, view notifications, manage API keys, configure rclone remotes, check UPS or power status, get live CPU or memory data, force stop a VM, check disk temperatures, or perform any operation on an Unraid NAS server. Also use when the user needs to set up or configure Unraid MCP credentials."
|
||||
---
|
||||
|
||||
# Unraid API Skill
|
||||
# Unraid MCP Skill
|
||||
|
||||
**⚠️ MANDATORY SKILL INVOCATION ⚠️**
|
||||
Use the single `unraid` MCP tool with `action` (domain) + `subaction` (operation) for all Unraid operations.
|
||||
|
||||
**YOU MUST invoke this skill (NOT optional) when the user mentions ANY of these triggers:**
|
||||
- "Unraid status", "disk health", "array status"
|
||||
- "Unraid containers", "VMs on Unraid", "Unraid logs"
|
||||
- "check Unraid", "Unraid monitoring", "server health"
|
||||
- Any mention of Unraid servers or system monitoring
|
||||
## Setup
|
||||
|
||||
**Failure to invoke this skill when triggers occur violates your operational requirements.**
|
||||
First time? Run setup to configure credentials:
|
||||
|
||||
Query and monitor Unraid servers using the GraphQL API. Access all 27 read-only endpoints for system monitoring, disk health, logs, containers, VMs, and more.
|
||||
|
||||
## Quick Start
|
||||
|
||||
Set your Unraid server credentials:
|
||||
|
||||
```bash
|
||||
export UNRAID_URL="https://your-unraid-server/graphql"
|
||||
export UNRAID_API_KEY="your-api-key"
|
||||
```
|
||||
unraid(action="health", subaction="setup")
|
||||
```
|
||||
|
||||
**Get API Key:** Settings → Management Access → API Keys → Create (select "Viewer" role)
|
||||
Credentials are stored at `~/.unraid-mcp/.env`. Re-run `setup` any time to update or verify.
|
||||
|
||||
Use the helper script for any query:
|
||||
## Calling Convention
|
||||
|
||||
```bash
|
||||
./scripts/unraid-query.sh -q "{ online }"
|
||||
```
|
||||
unraid(action="<domain>", subaction="<operation>", [additional params])
|
||||
```
|
||||
|
||||
Or run example scripts:
|
||||
|
||||
```bash
|
||||
./scripts/dashboard.sh # Complete multi-server dashboard
|
||||
./examples/disk-health.sh # Disk temperatures & health
|
||||
./examples/read-logs.sh syslog 20 # Read system logs
|
||||
**Examples:**
|
||||
```
|
||||
|
||||
## Core Concepts
|
||||
|
||||
### GraphQL API Structure
|
||||
|
||||
Unraid 7.2+ uses GraphQL (not REST). Key differences:
|
||||
- **Single endpoint:** `/graphql` for all queries
|
||||
- **Request exactly what you need:** Specify fields in query
|
||||
- **Strongly typed:** Use introspection to discover fields
|
||||
- **No container logs:** Docker container output logs not accessible
|
||||
|
||||
### Two Resources for Stats
|
||||
|
||||
- **`info`** - Static hardware specs (CPU model, cores, OS version)
|
||||
- **`metrics`** - Real-time usage (CPU %, memory %, current load)
|
||||
|
||||
Always use `metrics` for monitoring, `info` for specifications.
|
||||
|
||||
## Common Tasks
|
||||
|
||||
### System Monitoring
|
||||
|
||||
**Check if server is online:**
|
||||
```bash
|
||||
./scripts/unraid-query.sh -q "{ online }"
|
||||
```
|
||||
|
||||
**Get CPU and memory usage:**
|
||||
```bash
|
||||
./scripts/unraid-query.sh -q "{ metrics { cpu { percentTotal } memory { used total percentTotal } } }"
|
||||
```
|
||||
|
||||
**Complete dashboard:**
|
||||
```bash
|
||||
./scripts/dashboard.sh
|
||||
```
|
||||
|
||||
### Disk Management
|
||||
|
||||
**Check disk health and temperatures:**
|
||||
```bash
|
||||
./examples/disk-health.sh
|
||||
```
|
||||
|
||||
**Get array status:**
|
||||
```bash
|
||||
./scripts/unraid-query.sh -q "{ array { state parityCheckStatus { status progress errors } } }"
|
||||
```
|
||||
|
||||
**List all physical disks (including cache/USB):**
|
||||
```bash
|
||||
./scripts/unraid-query.sh -q "{ disks { name } }"
|
||||
```
|
||||
|
||||
### Storage Shares
|
||||
|
||||
**List network shares:**
|
||||
```bash
|
||||
./scripts/unraid-query.sh -q "{ shares { name comment } }"
|
||||
```
|
||||
|
||||
### Logs
|
||||
|
||||
**List available logs:**
|
||||
```bash
|
||||
./scripts/unraid-query.sh -q "{ logFiles { name size modifiedAt } }"
|
||||
```
|
||||
|
||||
**Read log content:**
|
||||
```bash
|
||||
./examples/read-logs.sh syslog 20
|
||||
```
|
||||
|
||||
### Containers & VMs
|
||||
|
||||
**List Docker containers:**
|
||||
```bash
|
||||
./scripts/unraid-query.sh -q "{ docker { containers { names image state status } } }"
|
||||
```
|
||||
|
||||
**List VMs:**
|
||||
```bash
|
||||
./scripts/unraid-query.sh -q "{ vms { domain { name state } } }"
|
||||
```
|
||||
|
||||
**Note:** Container output logs are NOT accessible via API. Use `docker logs` via SSH.
|
||||
|
||||
### Notifications
|
||||
|
||||
**Get notification counts:**
|
||||
```bash
|
||||
./scripts/unraid-query.sh -q "{ notifications { overview { unread { info warning alert total } } } }"
|
||||
```
|
||||
|
||||
## Helper Script Usage
|
||||
|
||||
The `scripts/unraid-query.sh` helper supports:
|
||||
|
||||
```bash
|
||||
# Basic usage
|
||||
./scripts/unraid-query.sh -u URL -k API_KEY -q "QUERY"
|
||||
|
||||
# Use environment variables
|
||||
export UNRAID_URL="https://unraid.local/graphql"
|
||||
export UNRAID_API_KEY="your-key"
|
||||
./scripts/unraid-query.sh -q "{ online }"
|
||||
|
||||
# Format options
|
||||
-f json # Raw JSON (default)
|
||||
-f pretty # Pretty-printed JSON
|
||||
-f raw # Just the data (no wrapper)
|
||||
```
|
||||
|
||||
## Additional Resources
|
||||
|
||||
### Reference Files
|
||||
|
||||
For detailed documentation, consult:
|
||||
- **`references/endpoints.md`** - Complete list of all 27 API endpoints
|
||||
- **`references/troubleshooting.md`** - Common errors and solutions
|
||||
- **`references/api-reference.md`** - Detailed field documentation
|
||||
|
||||
### Helper Scripts
|
||||
|
||||
- **`scripts/unraid-query.sh`** - Main GraphQL query tool
|
||||
- **`scripts/dashboard.sh`** - Automated multi-server inventory reporter
|
||||
|
||||
## Quick Command Reference
|
||||
|
||||
```bash
|
||||
# System status
|
||||
./scripts/unraid-query.sh -q "{ online metrics { cpu { percentTotal } } }"
|
||||
|
||||
# Disk health
|
||||
./examples/disk-health.sh
|
||||
|
||||
# Array status
|
||||
./scripts/unraid-query.sh -q "{ array { state } }"
|
||||
|
||||
# Read logs
|
||||
./examples/read-logs.sh syslog 20
|
||||
|
||||
# Complete dashboard
|
||||
./scripts/dashboard.sh
|
||||
|
||||
# List shares
|
||||
./scripts/unraid-query.sh -q "{ shares { name } }"
|
||||
|
||||
# List containers
|
||||
./scripts/unraid-query.sh -q "{ docker { containers { names state } } }"
|
||||
unraid(action="system", subaction="overview")
|
||||
unraid(action="docker", subaction="list")
|
||||
unraid(action="health", subaction="check")
|
||||
unraid(action="array", subaction="parity_status")
|
||||
unraid(action="disk", subaction="disks")
|
||||
unraid(action="vm", subaction="list")
|
||||
unraid(action="notification", subaction="overview")
|
||||
unraid(action="live", subaction="cpu")
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Agent Tool Usage Requirements
|
||||
## All Domains and Subactions
|
||||
|
||||
**CRITICAL:** When invoking scripts from this skill via the zsh-tool, **ALWAYS use `pty: true`**.
|
||||
### `system` — Server Information
|
||||
| Subaction | Description |
|
||||
|-----------|-------------|
|
||||
| `overview` | Complete system summary (recommended starting point) |
|
||||
| `server` | Hostname, version, uptime |
|
||||
| `servers` | All known Unraid servers |
|
||||
| `array` | Array status and disk list |
|
||||
| `network` | Network interfaces and config |
|
||||
| `registration` | License and registration status |
|
||||
| `variables` | Environment variables |
|
||||
| `metrics` | Real-time CPU, memory, I/O usage |
|
||||
| `services` | Running services status |
|
||||
| `display` | Display settings |
|
||||
| `config` | System configuration |
|
||||
| `online` | Quick online status check |
|
||||
| `owner` | Server owner information |
|
||||
| `settings` | User settings and preferences |
|
||||
| `flash` | USB flash drive details |
|
||||
| `ups_devices` | List all UPS devices |
|
||||
| `ups_device` | Single UPS device (requires `device_id`) |
|
||||
| `ups_config` | UPS configuration |
|
||||
|
||||
Without PTY mode, command output will not be visible even though commands execute successfully.
|
||||
### `health` — Diagnostics
|
||||
| Subaction | Description |
|
||||
|-----------|-------------|
|
||||
| `check` | Comprehensive health check — connectivity, array, disks, containers, VMs, resources |
|
||||
| `test_connection` | Test API connectivity and authentication |
|
||||
| `diagnose` | Detailed diagnostic report with troubleshooting recommendations |
|
||||
| `setup` | Configure credentials interactively (stores to `~/.unraid-mcp/.env`) |
|
||||
|
||||
**Correct invocation pattern:**
|
||||
```typescript
|
||||
<invoke name="mcp__plugin_zsh-tool_zsh-tool__zsh">
|
||||
<parameter name="command">./skills/SKILL_NAME/scripts/SCRIPT.sh [args]</parameter>
|
||||
<parameter name="pty">true</parameter>
|
||||
</invoke>
|
||||
### `array` — Array & Parity
|
||||
| Subaction | Description |
|
||||
|-----------|-------------|
|
||||
| `parity_status` | Current parity check progress and status |
|
||||
| `parity_history` | Historical parity check results |
|
||||
| `parity_start` | Start a parity check |
|
||||
| `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 array |
|
||||
| `stop_array` | ⚠️ Stop the array (requires `confirm=True`) |
|
||||
| `add_disk` | Add a disk to the array (requires `slot`, `id`) |
|
||||
| `remove_disk` | ⚠️ Remove a disk (requires `slot`, `confirm=True`) |
|
||||
| `mount_disk` | Mount a disk |
|
||||
| `unmount_disk` | Unmount a disk |
|
||||
| `clear_disk_stats` | ⚠️ Clear disk statistics (requires `confirm=True`) |
|
||||
|
||||
### `disk` — Storage & Logs
|
||||
| Subaction | Description |
|
||||
|-----------|-------------|
|
||||
| `shares` | List network shares |
|
||||
| `disks` | All physical disks with health and temperatures |
|
||||
| `disk_details` | Detailed info for a specific disk (requires `disk_id`) |
|
||||
| `log_files` | List available log files |
|
||||
| `logs` | Read log content (requires `path`; optional `lines`) |
|
||||
| `flash_backup` | ⚠️ Trigger a flash backup (requires `confirm=True`) |
|
||||
|
||||
### `docker` — Containers
|
||||
| Subaction | Description |
|
||||
|-----------|-------------|
|
||||
| `list` | All containers with status, image, state |
|
||||
| `details` | Single container details (requires container identifier) |
|
||||
| `start` | Start a container (requires container identifier) |
|
||||
| `stop` | Stop a container (requires container identifier) |
|
||||
| `restart` | Restart a container (requires container identifier) |
|
||||
| `networks` | List Docker networks |
|
||||
| `network_details` | Details for a specific network (requires `network_id`) |
|
||||
|
||||
**Container Identification:** Name, ID, or partial name (fuzzy match supported).
|
||||
|
||||
### `vm` — Virtual Machines
|
||||
| Subaction | Description |
|
||||
|-----------|-------------|
|
||||
| `list` | All VMs with state |
|
||||
| `details` | Single VM details (requires `vm_id`) |
|
||||
| `start` | Start a VM (requires `vm_id`) |
|
||||
| `stop` | Gracefully stop a VM (requires `vm_id`) |
|
||||
| `pause` | Pause a VM (requires `vm_id`) |
|
||||
| `resume` | Resume a paused VM (requires `vm_id`) |
|
||||
| `reboot` | Reboot a VM (requires `vm_id`) |
|
||||
| `force_stop` | ⚠️ Force stop a VM (requires `vm_id`, `confirm=True`) |
|
||||
| `reset` | ⚠️ Hard reset a VM (requires `vm_id`, `confirm=True`) |
|
||||
|
||||
### `notification` — Notifications
|
||||
| Subaction | Description |
|
||||
|-----------|-------------|
|
||||
| `overview` | Notification counts (unread, archived by type) |
|
||||
| `list` | List notifications (optional `filter`, `limit`, `offset`) |
|
||||
| `mark_unread` | Mark a notification as unread (requires `notification_id`) |
|
||||
| `create` | Create a notification (requires `title`, `subject`, `description`, `importance`) |
|
||||
| `archive` | Archive a notification (requires `notification_id`) |
|
||||
| `delete` | ⚠️ Delete a notification (requires `notification_id`, `notification_type`, `confirm=True`) |
|
||||
| `delete_archived` | ⚠️ Delete all archived (requires `confirm=True`) |
|
||||
| `archive_all` | Archive all unread notifications |
|
||||
| `archive_many` | Archive multiple (requires `ids` list) |
|
||||
| `unarchive_many` | Unarchive multiple (requires `ids` list) |
|
||||
| `unarchive_all` | Unarchive all archived notifications |
|
||||
| `recalculate` | Recalculate notification counts |
|
||||
|
||||
### `key` — API Keys
|
||||
| Subaction | Description |
|
||||
|-----------|-------------|
|
||||
| `list` | All API keys |
|
||||
| `get` | Single key details (requires `key_id`) |
|
||||
| `create` | Create a new key (requires `name`, `roles`) |
|
||||
| `update` | Update a key (requires `key_id`) |
|
||||
| `delete` | ⚠️ Delete a key (requires `key_id`, `confirm=True`) |
|
||||
| `add_role` | Add a role to a key (requires `key_id`, `role`) |
|
||||
| `remove_role` | Remove a role from a key (requires `key_id`, `role`) |
|
||||
|
||||
### `plugin` — Plugins
|
||||
| Subaction | Description |
|
||||
|-----------|-------------|
|
||||
| `list` | All installed plugins |
|
||||
| `add` | Install plugins (requires `names` — list of plugin names) |
|
||||
| `remove` | ⚠️ Uninstall plugins (requires `names` — list of plugin names, `confirm=True`) |
|
||||
|
||||
### `rclone` — Cloud Storage
|
||||
| Subaction | Description |
|
||||
|-----------|-------------|
|
||||
| `list_remotes` | List configured rclone remotes |
|
||||
| `config_form` | Get configuration form for a remote type |
|
||||
| `create_remote` | Create a new remote (requires `name`, `type`, `fields`) |
|
||||
| `delete_remote` | ⚠️ Delete a remote (requires `name`, `confirm=True`) |
|
||||
|
||||
### `setting` — System Settings
|
||||
| Subaction | Description |
|
||||
|-----------|-------------|
|
||||
| `update` | Update system settings (requires `settings` object) |
|
||||
| `configure_ups` | ⚠️ Configure UPS settings (requires `confirm=True`) |
|
||||
|
||||
### `customization` — Theme & Appearance
|
||||
| Subaction | Description |
|
||||
|-----------|-------------|
|
||||
| `theme` | Current theme settings |
|
||||
| `public_theme` | Public-facing theme |
|
||||
| `is_initial_setup` | Check if initial setup is complete |
|
||||
| `sso_enabled` | Check SSO status |
|
||||
| `set_theme` | Update theme (requires theme parameters) |
|
||||
|
||||
### `oidc` — SSO / OpenID Connect
|
||||
| Subaction | Description |
|
||||
|-----------|-------------|
|
||||
| `providers` | List configured OIDC providers |
|
||||
| `provider` | Single provider details (requires `provider_id`) |
|
||||
| `configuration` | OIDC configuration |
|
||||
| `public_providers` | Public-facing provider list |
|
||||
| `validate_session` | Validate current SSO session |
|
||||
|
||||
### `user` — Current User
|
||||
| Subaction | Description |
|
||||
|-----------|-------------|
|
||||
| `me` | Current authenticated user info |
|
||||
|
||||
### `live` — Real-Time Subscriptions
|
||||
These use persistent WebSocket connections. Returns a "connecting" placeholder on the first call — retry momentarily for live data.
|
||||
|
||||
| Subaction | Description |
|
||||
|-----------|-------------|
|
||||
| `cpu` | Live CPU utilization |
|
||||
| `memory` | Live memory usage |
|
||||
| `cpu_telemetry` | Detailed CPU telemetry |
|
||||
| `array_state` | Live array state changes |
|
||||
| `parity_progress` | Live parity check progress |
|
||||
| `ups_status` | Live UPS status |
|
||||
| `notifications_overview` | Live notification counts |
|
||||
| `owner` | Live owner info |
|
||||
| `server_status` | Live server status |
|
||||
| `log_tail` | Live log tail stream |
|
||||
| `notification_feed` | Live notification feed |
|
||||
|
||||
---
|
||||
|
||||
## Destructive Actions
|
||||
|
||||
All require `confirm=True` as an explicit parameter. Without it, the action is blocked and elicitation is triggered.
|
||||
|
||||
| Domain | Subaction | Risk |
|
||||
|--------|-----------|------|
|
||||
| `array` | `stop_array` | Stops array while containers/VMs may use shares |
|
||||
| `array` | `remove_disk` | Removes disk from array |
|
||||
| `array` | `clear_disk_stats` | Clears disk statistics permanently |
|
||||
| `vm` | `force_stop` | Hard kills VM without graceful shutdown |
|
||||
| `vm` | `reset` | Hard resets VM |
|
||||
| `notification` | `delete` | Permanently deletes a notification |
|
||||
| `notification` | `delete_archived` | Permanently deletes all archived notifications |
|
||||
| `rclone` | `delete_remote` | Removes a cloud storage remote |
|
||||
| `key` | `delete` | Permanently deletes an API key |
|
||||
| `disk` | `flash_backup` | Triggers flash backup operation |
|
||||
| `setting` | `configure_ups` | Modifies UPS configuration |
|
||||
| `plugin` | `remove` | Uninstalls a plugin |
|
||||
|
||||
---
|
||||
|
||||
## Common Workflows
|
||||
|
||||
### First-time setup
|
||||
```
|
||||
unraid(action="health", subaction="setup")
|
||||
unraid(action="health", subaction="check")
|
||||
```
|
||||
|
||||
### System health overview
|
||||
```
|
||||
unraid(action="system", subaction="overview")
|
||||
unraid(action="health", subaction="check")
|
||||
```
|
||||
|
||||
### Container management
|
||||
```
|
||||
unraid(action="docker", subaction="list")
|
||||
unraid(action="docker", subaction="details", container_id="plex")
|
||||
unraid(action="docker", subaction="restart", container_id="sonarr")
|
||||
```
|
||||
|
||||
### Array and disk status
|
||||
```
|
||||
unraid(action="array", subaction="parity_status")
|
||||
unraid(action="disk", subaction="disks")
|
||||
unraid(action="system", subaction="array")
|
||||
```
|
||||
|
||||
### Read logs
|
||||
```
|
||||
unraid(action="disk", subaction="log_files")
|
||||
unraid(action="disk", subaction="logs", path="syslog", lines=50)
|
||||
```
|
||||
|
||||
### Live monitoring
|
||||
```
|
||||
unraid(action="live", subaction="cpu")
|
||||
unraid(action="live", subaction="memory")
|
||||
unraid(action="live", subaction="array_state")
|
||||
```
|
||||
|
||||
### VM operations
|
||||
```
|
||||
unraid(action="vm", subaction="list")
|
||||
unraid(action="vm", subaction="start", vm_id="<id>")
|
||||
unraid(action="vm", subaction="force_stop", vm_id="<id>", confirm=True)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Notes
|
||||
|
||||
- **Rate limit:** 100 requests / 10 seconds
|
||||
- **Log path validation:** Only `/var/log/`, `/boot/logs/`, `/mnt/` prefixes accepted
|
||||
- **Container logs:** Docker container stdout/stderr are NOT accessible via API — use SSH + `docker logs`
|
||||
- **`arraySubscription`:** Known Unraid API bug — `live/array_state` may show "connecting" indefinitely
|
||||
- **Event-driven subs** (`notifications_overview`, `owner`, `server_status`, `ups_status`): Only populate cache on first real server event
|
||||
|
||||
Reference in New Issue
Block a user