docs: fix markdown lint, broken links, stale counts, and publishing guidance

- Fix broken ToC anchors in competitive-analysis.md (MD051)
- Add blank lines before code blocks in api-reference.md (MD031)
- Add language identifiers to directory tree code blocks in MARKETPLACE.md and skills/unraid/README.md (MD040)
- Fix size unit guidance conflict: clarify disk sizes are KB, memory is bytes
- Update stale "90 actions" references to "76 actions" across research docs
- Fix coverage table terminology and clarify 22% coverage calculation
- Recommend PyPI Trusted Publishing (OIDC) over API token secrets in PUBLISHING.md
- Update action count in .claude-plugin/README.md

Resolves review threads: PRRT_kwDOO6Hdxs5uvO2m, PRRT_kwDOO6Hdxs5uvO2o,
PRRT_kwDOO6Hdxs5uvO2r, PRRT_kwDOO6Hdxs5uvOcl, PRRT_kwDOO6Hdxs5uvOcr,
PRRT_kwDOO6Hdxs5uvKrq, PRRT_kwDOO6Hdxs5uvO2u, PRRT_kwDOO6Hdxs5uvO2w,
PRRT_kwDOO6Hdxs5uvO2z, PRRT_kwDOO6Hdxs5uu7zl
This commit is contained in:
Jacob Magar
2026-02-15 23:05:05 -05:00
parent fa99c32f6c
commit 4a694c0f32
7 changed files with 73 additions and 22 deletions

View File

@@ -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. Query and monitor Unraid servers via GraphQL API - array status, disk health, containers, VMs, system monitoring.
**Features:** **Features:**
- 10 tools with 90 actions (queries and mutations) - 10 tools with 76 actions (queries and mutations)
- Real-time system metrics - Real-time system metrics
- Disk health and temperature monitoring - Disk health and temperature monitoring
- Docker container management - Docker container management

View File

@@ -71,7 +71,7 @@ Users can also install from a specific commit or branch:
## Plugin Structure ## Plugin Structure
``` ```text
unraid-mcp/ unraid-mcp/
├── .claude-plugin/ # Marketplace manifest ├── .claude-plugin/ # Marketplace manifest
│ ├── marketplace.json │ ├── marketplace.json

View File

@@ -161,7 +161,39 @@ UNRAID_API_URL=https://your-server uvx unraid-mcp-server
## Automation with GitHub Actions (Future) ## 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 ```yaml
name: Publish to PyPI name: Publish to PyPI
@@ -185,8 +217,6 @@ jobs:
run: uv run twine upload dist/* 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 ## Troubleshooting
### "File already exists" Error ### "File already exists" Error

View File

@@ -1,7 +1,7 @@
# Competitive Analysis: Unraid Integration Projects # Competitive Analysis: Unraid Integration Projects
> **Date:** 2026-02-07 > **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 ## Table of Contents
@@ -11,8 +11,8 @@
- [2. domalab/unraid-api-client (Python library)](#2-domalabunraid-api-client) - [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) - [3. mcp-ssh-sre / unraid-ssh-mcp (SSH-based MCP)](#3-mcp-ssh-sre--unraid-ssh-mcp)
- [4. PSUnraid (PowerShell module)](#4-psunraid) - [4. PSUnraid (PowerShell module)](#4-psunraid)
- [5. ha-unraid (Home Assistant integration)](#5-ha-unraid) - [5. ha-unraid (Home Assistant integration)](#5-ha-unraid-home-assistant-integration)
- [6. chris-mc1/unraid_api (HA integration)](#6-chris-mc1unraid_api) - [6. chris-mc1/unraid_api (HA integration)](#6-chris-mc1unraid_api-ha-integration)
- [Feature Matrix](#feature-matrix) - [Feature Matrix](#feature-matrix)
- [Gap Analysis](#gap-analysis) - [Gap Analysis](#gap-analysis)
- [Recommended Priorities](#recommended-priorities) - [Recommended Priorities](#recommended-priorities)
@@ -22,7 +22,7 @@
## Executive Summary ## 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):** **Critical gaps (high-value features we lack):**
1. **Array control operations** (start/stop array, parity check control, disk spin up/down) 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:** **Key differentiators from our project:**
- Runs as an Unraid plugin directly on the server (no external dependency on GraphQL API) - 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 - 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 - 54 MCP tools with Resources and Prompts
- Real-time WebSocket event streaming (9 event types, 5-60s intervals) - Real-time WebSocket event streaming (9 event types, 5-60s intervals)
- 41 Prometheus metrics for Grafana dashboards - 41 Prometheus metrics for Grafana dashboards
@@ -341,7 +341,7 @@ The project's documentation explicitly compares SSH vs API capabilities:
### Monitoring Features ### 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 | | System info (hostname, uptime) | Y | Y | Y | Y | Y | Y | N |
| CPU usage | Y | Y | Y | Y | Y | Y | Y | | 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 | | 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 Resources | N | Y (5) | N | N | N | N | N |
| MCP Prompts | N | Y (3) | 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 | | REST API | N | Y (59) | N | N | N | N | N |

View File

@@ -1,7 +1,7 @@
# Unraid API Feature Gap Analysis # Unraid API Feature Gap Analysis
> **Date:** 2026-02-07 > **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. > **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 ## 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 ### 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 ### 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 | | **Queries** | ~30+ | 14 | ~16+ uncovered |
| **Mutations** | ~50+ | 10 (start/stop Docker+VM, RClone CRUD) | ~40+ uncovered | | **Mutations** | ~50+ | 10 (start/stop Docker+VM, RClone CRUD) | ~40+ uncovered |
| **Subscriptions** | ~30+ | 0 (2 diagnostic only) | ~30+ 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 | | **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) | | **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` | | **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 | | **WebSocket Events** | Real-time event stream | We have diagnostic-only subscriptions |
### G.2 PSUnraid (PowerShell Module) ### G.2 PSUnraid (PowerShell Module)
@@ -828,7 +828,7 @@ Chose SSH over GraphQL API due to these gaps:
| | **Low Priority Subtotal** | **18** | **92** | | | **Low Priority Subtotal** | **18** | **92** |
| | **GRAND TOTAL NEW TOOLS** | **66** | **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**
--- ---

View File

@@ -8,7 +8,7 @@ This skill provides complete access to all 27 read-only Unraid GraphQL API endpo
### Files ### Files
``` ```text
skills/unraid/ skills/unraid/
├── SKILL.md # Main skill documentation ├── SKILL.md # Main skill documentation
├── README.md # This file ├── README.md # This file
@@ -147,7 +147,7 @@ This skill activates when you mention:
## Notes ## 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** - Temperatures are in **Celsius**
- Docker container logs are **not accessible** via API (use SSH) - Docker container logs are **not accessible** via API (use SSH)
- Poll no faster than every **5 seconds** to avoid server load - Poll no faster than every **5 seconds** to avoid server load

View File

@@ -50,6 +50,7 @@ curl -s -X POST "https://YOUR-UNRAID/graphql" \
``` ```
**Response:** **Response:**
```json ```json
{ {
"data": { "data": {
@@ -92,6 +93,7 @@ curl -s -X POST "https://YOUR-UNRAID/graphql" \
``` ```
**Response:** **Response:**
```json ```json
{ {
"data": { "data": {
@@ -128,6 +130,7 @@ curl -s -X POST "https://YOUR-UNRAID/graphql" \
``` ```
**Response:** **Response:**
```json ```json
{ {
"data": { "data": {
@@ -149,6 +152,7 @@ curl -s -X POST "https://YOUR-UNRAID/graphql" \
``` ```
**Response:** **Response:**
```json ```json
{ {
"data": { "data": {
@@ -174,6 +178,7 @@ curl -s -X POST "https://YOUR-UNRAID/graphql" \
``` ```
**Response (sample):** **Response (sample):**
```json ```json
{ {
"data": { "data": {
@@ -223,6 +228,7 @@ curl -s -X POST "https://YOUR-UNRAID/graphql" \
``` ```
**Response (sample):** **Response (sample):**
```json ```json
{ {
"data": { "data": {
@@ -261,6 +267,7 @@ curl -s -X POST "https://YOUR-UNRAID/graphql" \
``` ```
**Response:** **Response:**
```json ```json
{ {
"data": { "data": {
@@ -297,6 +304,7 @@ curl -s -X POST "https://YOUR-UNRAID/graphql" \
``` ```
**Response (when no containers):** **Response (when no containers):**
```json ```json
{ {
"data": { "data": {
@@ -324,6 +332,7 @@ curl -s -X POST "https://YOUR-UNRAID/graphql" \
``` ```
**Response (when no VMs):** **Response (when no VMs):**
```json ```json
{ {
"data": { "data": {
@@ -349,6 +358,7 @@ curl -s -X POST "https://YOUR-UNRAID/graphql" \
``` ```
**Response (sample, 32 logs found):** **Response (sample, 32 logs found):**
```json ```json
{ {
"data": { "data": {
@@ -388,6 +398,7 @@ curl -s -X POST "https://YOUR-UNRAID/graphql" \
``` ```
**Response:** **Response:**
```json ```json
{ {
"data": { "data": {
@@ -429,6 +440,7 @@ curl -s -X POST "https://YOUR-UNRAID/graphql" \
``` ```
**Response:** **Response:**
```json ```json
{ {
"data": { "data": {
@@ -463,6 +475,7 @@ curl -s -X POST "https://YOUR-UNRAID/graphql" \
``` ```
**Response (sample):** **Response (sample):**
```json ```json
{ {
"data": { "data": {
@@ -503,6 +516,7 @@ curl -s -X POST "https://YOUR-UNRAID/graphql" \
``` ```
**Response (when no UPS):** **Response (when no UPS):**
```json ```json
{ {
"data": { "data": {
@@ -542,6 +556,7 @@ curl -s -X POST "https://YOUR-UNRAID/graphql" \
``` ```
**Response:** **Response:**
```json ```json
{ {
"data": { "data": {
@@ -567,6 +582,7 @@ curl -s -X POST "https://YOUR-UNRAID/graphql" \
``` ```
**Response:** **Response:**
```json ```json
{ {
"data": { "data": {
@@ -606,6 +622,7 @@ curl -s -X POST "https://YOUR-UNRAID/graphql" \
``` ```
**Response (sample, 4 keys found):** **Response (sample, 4 keys found):**
```json ```json
{ {
"data": { "data": {
@@ -681,6 +698,7 @@ curl -s -X POST "https://YOUR-UNRAID/graphql" \
``` ```
**Response:** **Response:**
```json ```json
{ {
"data": { "data": {
@@ -712,6 +730,7 @@ curl -s -X POST "https://YOUR-UNRAID/graphql" \
``` ```
**Response:** **Response:**
```json ```json
{ {
"data": { "data": {
@@ -742,6 +761,7 @@ curl -s -X POST "https://YOUR-UNRAID/graphql" \
``` ```
**Response:** **Response:**
```json ```json
{ {
"data": { "data": {
@@ -816,6 +836,7 @@ curl -s -X POST "https://YOUR-UNRAID/graphql" \
``` ```
**Response (when no plugins):** **Response (when no plugins):**
```json ```json
{ {
"data": { "data": {