diff --git a/.claude-plugin/README.md b/.claude-plugin/README.md index 41d36bf..00094ad 100644 --- a/.claude-plugin/README.md +++ b/.claude-plugin/README.md @@ -31,7 +31,7 @@ This directory contains the Claude Code marketplace configuration for the Unraid Query and monitor Unraid servers via GraphQL API - array status, disk health, containers, VMs, system monitoring. **Features:** -- 10 tools with 90 actions (queries and mutations) +- 10 tools with 76 actions (queries and mutations) - Real-time system metrics - Disk health and temperature monitoring - Docker container management diff --git a/docs/MARKETPLACE.md b/docs/MARKETPLACE.md index 324f862..72f5415 100644 --- a/docs/MARKETPLACE.md +++ b/docs/MARKETPLACE.md @@ -71,7 +71,7 @@ Users can also install from a specific commit or branch: ## Plugin Structure -``` +```text unraid-mcp/ ├── .claude-plugin/ # Marketplace manifest │ ├── marketplace.json diff --git a/docs/PUBLISHING.md b/docs/PUBLISHING.md index 4b374ff..95bf65f 100644 --- a/docs/PUBLISHING.md +++ b/docs/PUBLISHING.md @@ -161,7 +161,39 @@ UNRAID_API_URL=https://your-server uvx unraid-mcp-server ## Automation with GitHub Actions (Future) -Consider adding `.github/workflows/publish.yml`: +### Recommended: Trusted Publishing (OIDC) + +[PyPI Trusted Publishing](https://docs.pypi.org/trusted-publishers/) uses OpenID Connect (OIDC) to authenticate directly from GitHub Actions -- no stored API tokens or long-lived secrets required. This is PyPI's recommended approach. + +**Setup:** +1. Go to [pypi.org/manage/account/publishing/](https://pypi.org/manage/account/publishing/) +2. Add a "new pending publisher" with your GitHub repository details +3. Use the following workflow: + +```yaml +name: Publish to PyPI + +on: + release: + types: [published] + +jobs: + publish: + runs-on: ubuntu-latest + permissions: + id-token: write # Required for Trusted Publishing + steps: + - uses: actions/checkout@v4 + - uses: astral-sh/setup-uv@v4 + - name: Build package + run: uv run python -m build + - name: Publish to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 +``` + +### Alternative: API Token + +If Trusted Publishing is not an option, use a stored API token: ```yaml name: Publish to PyPI @@ -185,8 +217,6 @@ jobs: run: uv run twine upload dist/* ``` -> **Tip:** Consider using [PyPI Trusted Publishing](https://docs.pypi.org/trusted-publishers/) instead of API token secrets. Trusted Publishing uses OpenID Connect (OIDC) to authenticate directly from GitHub Actions without storing long-lived secrets. - ## Troubleshooting ### "File already exists" Error diff --git a/docs/research/competitive-analysis.md b/docs/research/competitive-analysis.md index 4853e4e..e0af098 100644 --- a/docs/research/competitive-analysis.md +++ b/docs/research/competitive-analysis.md @@ -1,7 +1,7 @@ # Competitive Analysis: Unraid Integration Projects > **Date:** 2026-02-07 -> **Purpose:** Identify features and capabilities that competing Unraid integration projects offer that our `unraid-mcp` server (10 tools, 90 actions, GraphQL-based) currently lacks. +> **Purpose:** Identify features and capabilities that competing Unraid integration projects offer that our `unraid-mcp` server (10 tools, 76 actions, GraphQL-based) currently lacks. ## Table of Contents @@ -11,8 +11,8 @@ - [2. domalab/unraid-api-client (Python library)](#2-domalabunraid-api-client) - [3. mcp-ssh-sre / unraid-ssh-mcp (SSH-based MCP)](#3-mcp-ssh-sre--unraid-ssh-mcp) - [4. PSUnraid (PowerShell module)](#4-psunraid) - - [5. ha-unraid (Home Assistant integration)](#5-ha-unraid) - - [6. chris-mc1/unraid_api (HA integration)](#6-chris-mc1unraid_api) + - [5. ha-unraid (Home Assistant integration)](#5-ha-unraid-home-assistant-integration) + - [6. chris-mc1/unraid_api (HA integration)](#6-chris-mc1unraid_api-ha-integration) - [Feature Matrix](#feature-matrix) - [Gap Analysis](#gap-analysis) - [Recommended Priorities](#recommended-priorities) @@ -22,7 +22,7 @@ ## Executive Summary -Our `unraid-mcp` server provides 10 MCP tools (90 actions) built on the official Unraid GraphQL API. After analyzing six competing projects, we identified several significant gaps: +Our `unraid-mcp` server provides 10 MCP tools (76 actions) built on the official Unraid GraphQL API. After analyzing six competing projects, we identified several significant gaps: **Critical gaps (high-value features we lack):** 1. **Array control operations** (start/stop array, parity check control, disk spin up/down) @@ -71,7 +71,7 @@ Our `unraid-mcp` server provides 10 MCP tools (90 actions) built on the official **Key differentiators from our project:** - Runs as an Unraid plugin directly on the server (no external dependency on GraphQL API) - Collects data directly from /proc, /sys, Docker SDK, and libvirt -- 59 REST endpoints vs our 10 MCP tools (90 actions) +- 59 REST endpoints vs our 10 MCP tools (76 actions) - 54 MCP tools with Resources and Prompts - Real-time WebSocket event streaming (9 event types, 5-60s intervals) - 41 Prometheus metrics for Grafana dashboards @@ -341,7 +341,7 @@ The project's documentation explicitly compares SSH vs API capabilities: ### Monitoring Features -| Feature | Our MCP (10 tools, 90 actions) | mgmt-agent (54 MCP tools) | unraid-api-client | mcp-ssh-sre (79 actions) | PSUnraid | ha-unraid | chris-mc1 | +| Feature | Our MCP (10 tools, 76 actions) | mgmt-agent (54 MCP tools) | unraid-api-client | mcp-ssh-sre (79 actions) | PSUnraid | ha-unraid | chris-mc1 | |---------|:---:|:---:|:---:|:---:|:---:|:---:|:---:| | System info (hostname, uptime) | Y | Y | Y | Y | Y | Y | N | | CPU usage | Y | Y | Y | Y | Y | Y | Y | @@ -458,7 +458,7 @@ The project's documentation explicitly compares SSH vs API capabilities: | Feature | Our MCP | mgmt-agent | unraid-api-client | mcp-ssh-sre | PSUnraid | ha-unraid | chris-mc1 | |---------|:---:|:---:|:---:|:---:|:---:|:---:|:---:| -| MCP tools | Y (10 tools, 90 actions) | Y (54) | N | Y (79 actions) | N | N | N | +| MCP tools | Y (10 tools, 76 actions) | Y (54) | N | Y (79 actions) | N | N | N | | MCP Resources | N | Y (5) | N | N | N | N | N | | MCP Prompts | N | Y (3) | N | N | N | N | N | | REST API | N | Y (59) | N | N | N | N | N | diff --git a/docs/research/feature-gap-analysis.md b/docs/research/feature-gap-analysis.md index 643fd65..aef3907 100644 --- a/docs/research/feature-gap-analysis.md +++ b/docs/research/feature-gap-analysis.md @@ -1,7 +1,7 @@ # Unraid API Feature Gap Analysis > **Date:** 2026-02-07 -> **Purpose:** Comprehensive inventory of every API capability that could become an MCP tool, cross-referenced against our current 10 tools (90 actions) to identify gaps. +> **Purpose:** Comprehensive inventory of every API capability that could become an MCP tool, cross-referenced against our current 10 tools (76 actions) to identify gaps. > **Sources:** 7 research documents (3,800+ lines), Unraid API source code analysis, community project reviews, official documentation crawl. --- @@ -497,7 +497,7 @@ GRAPHQL_PUBSUB_CHANNEL { ## F. API Capabilities NOT Currently in the MCP Server -The current MCP server has 10 tools (90 actions) after consolidation. The following capabilities are available in the Unraid API but NOT covered by any existing tool. +The current MCP server has 10 tools (76 actions) after consolidation. The following capabilities are available in the Unraid API but NOT covered by any existing tool. ### F.1 HIGH PRIORITY - New Tool Candidates @@ -658,14 +658,14 @@ The current MCP server has 10 tools (90 actions) after consolidation. The follow ### F.4 Summary: Coverage Statistics -| Category | Available in API | Covered by MCP | Gap | -|----------|-----------------|----------------|-----| +| Category | Available in API | Covered by MCP (actions) | Gap | +|----------|-----------------|--------------------------|-----| | **Queries** | ~30+ | 14 | ~16+ uncovered | | **Mutations** | ~50+ | 10 (start/stop Docker+VM, RClone CRUD) | ~40+ uncovered | | **Subscriptions** | ~30+ | 0 (2 diagnostic only) | ~30+ uncovered | -| **Total Operations** | ~110+ | 90 active (10 tools) | ~20+ uncovered | +| **Total** | ~110+ | ~24 unique API operations (76 actions across 10 tools) | ~86+ uncovered | -**Current coverage: approximately 22% of available API operations.** +**Current coverage: approximately 22% of available API operations** (24 of ~110 unique GraphQL queries/mutations/subscriptions). Note: the MCP server exposes 76 actions, but many actions map to the same underlying API operation with different parameters. --- @@ -691,7 +691,7 @@ Capabilities this project offers that we do NOT: | **Update Status** | Check for OS/plugin updates | NOT available via GraphQL API | | **Mover Control** | Invoke the mover tool | NOT available via GraphQL API (Issue #1873) | | **Disk Thresholds** | Warning/critical temp settings | Partially available via `ArrayDisk.warning`/`critical` | -| **54 MCP Tools** | Full MCP tool suite | We have 10 tools (90 actions) | +| **54 MCP Tools** | Full MCP tool suite | We have 10 tools (76 actions) | | **WebSocket Events** | Real-time event stream | We have diagnostic-only subscriptions | ### G.2 PSUnraid (PowerShell Module) @@ -828,7 +828,7 @@ Chose SSH over GraphQL API due to these gaps: | | **Low Priority Subtotal** | **18** | **92** | | | **GRAND TOTAL NEW TOOLS** | **66** | **92** | -**Current tools: 10 (90 actions) | Potential total: ~110+ operations | Remaining gap: ~20+ uncovered operations** +**Current tools: 10 (76 actions) | Potential total: ~110+ operations | Remaining gap: ~20+ uncovered operations** --- diff --git a/skills/unraid/README.md b/skills/unraid/README.md index c1a7942..65ea09e 100644 --- a/skills/unraid/README.md +++ b/skills/unraid/README.md @@ -8,7 +8,7 @@ This skill provides complete access to all 27 read-only Unraid GraphQL API endpo ### Files -``` +```text skills/unraid/ ├── SKILL.md # Main skill documentation ├── README.md # This file @@ -147,7 +147,7 @@ This skill activates when you mention: ## Notes -- All sizes are in **kilobytes** +- Disk/array sizes are in **kilobytes**; memory values (from `info.memory` and `metrics.memory`) are in **bytes** - Temperatures are in **Celsius** - Docker container logs are **not accessible** via API (use SSH) - Poll no faster than every **5 seconds** to avoid server load diff --git a/skills/unraid/references/api-reference.md b/skills/unraid/references/api-reference.md index 2436d59..dd452d0 100644 --- a/skills/unraid/references/api-reference.md +++ b/skills/unraid/references/api-reference.md @@ -50,6 +50,7 @@ curl -s -X POST "https://YOUR-UNRAID/graphql" \ ``` **Response:** + ```json { "data": { @@ -92,6 +93,7 @@ curl -s -X POST "https://YOUR-UNRAID/graphql" \ ``` **Response:** + ```json { "data": { @@ -128,6 +130,7 @@ curl -s -X POST "https://YOUR-UNRAID/graphql" \ ``` **Response:** + ```json { "data": { @@ -149,6 +152,7 @@ curl -s -X POST "https://YOUR-UNRAID/graphql" \ ``` **Response:** + ```json { "data": { @@ -174,6 +178,7 @@ curl -s -X POST "https://YOUR-UNRAID/graphql" \ ``` **Response (sample):** + ```json { "data": { @@ -223,6 +228,7 @@ curl -s -X POST "https://YOUR-UNRAID/graphql" \ ``` **Response (sample):** + ```json { "data": { @@ -261,6 +267,7 @@ curl -s -X POST "https://YOUR-UNRAID/graphql" \ ``` **Response:** + ```json { "data": { @@ -297,6 +304,7 @@ curl -s -X POST "https://YOUR-UNRAID/graphql" \ ``` **Response (when no containers):** + ```json { "data": { @@ -324,6 +332,7 @@ curl -s -X POST "https://YOUR-UNRAID/graphql" \ ``` **Response (when no VMs):** + ```json { "data": { @@ -349,6 +358,7 @@ curl -s -X POST "https://YOUR-UNRAID/graphql" \ ``` **Response (sample, 32 logs found):** + ```json { "data": { @@ -388,6 +398,7 @@ curl -s -X POST "https://YOUR-UNRAID/graphql" \ ``` **Response:** + ```json { "data": { @@ -429,6 +440,7 @@ curl -s -X POST "https://YOUR-UNRAID/graphql" \ ``` **Response:** + ```json { "data": { @@ -463,6 +475,7 @@ curl -s -X POST "https://YOUR-UNRAID/graphql" \ ``` **Response (sample):** + ```json { "data": { @@ -503,6 +516,7 @@ curl -s -X POST "https://YOUR-UNRAID/graphql" \ ``` **Response (when no UPS):** + ```json { "data": { @@ -542,6 +556,7 @@ curl -s -X POST "https://YOUR-UNRAID/graphql" \ ``` **Response:** + ```json { "data": { @@ -567,6 +582,7 @@ curl -s -X POST "https://YOUR-UNRAID/graphql" \ ``` **Response:** + ```json { "data": { @@ -606,6 +622,7 @@ curl -s -X POST "https://YOUR-UNRAID/graphql" \ ``` **Response (sample, 4 keys found):** + ```json { "data": { @@ -681,6 +698,7 @@ curl -s -X POST "https://YOUR-UNRAID/graphql" \ ``` **Response:** + ```json { "data": { @@ -712,6 +730,7 @@ curl -s -X POST "https://YOUR-UNRAID/graphql" \ ``` **Response:** + ```json { "data": { @@ -742,6 +761,7 @@ curl -s -X POST "https://YOUR-UNRAID/graphql" \ ``` **Response:** + ```json { "data": { @@ -816,6 +836,7 @@ curl -s -X POST "https://YOUR-UNRAID/graphql" \ ``` **Response (when no plugins):** + ```json { "data": {