From 3acdfa3b2baad866c490898367570eee5d8a09d8 Mon Sep 17 00:00:00 2001 From: Simon Diesenreiter Date: Sat, 21 Feb 2026 14:34:25 +0100 Subject: [PATCH] =?UTF-8?q?release:=20version=200.0.2=20=F0=9F=9A=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- HISTORY.md | 459 +++++++++++++++++++++++++++++++++++++++++++++++++++++ VERSION | 2 +- 2 files changed, 460 insertions(+), 1 deletion(-) create mode 100644 HISTORY.md diff --git a/HISTORY.md b/HISTORY.md new file mode 100644 index 0000000..30a4898 --- /dev/null +++ b/HISTORY.md @@ -0,0 +1,459 @@ +Changelog +========= + + +(unreleased) +------------ + +Fix +~~~ +- Set scripts as executable, refs NOISSUE. [Simon Diesenreiter] +- Initial test release. [Simon Diesenreiter] + + +0.0.1 (2026-02-21) +------------------ + +Fix +~~~ +- Use CLAUDE_PLUGIN_ROOT for portable MCP server configuration. [Jacob + Magar] + + Update .mcp.json to use environment variable + for the --directory argument, ensuring the MCP server works correctly + regardless of where the plugin is installed. + + This follows Claude Code plugin best practices for MCP server bundling. +- Correct marketplace.json source field format. [Jacob Magar] + + Change source from absolute GitHub URL to relative path "./" + This follows Claude Code marketplace convention where source paths + are relative to the cloned repository root, not external URLs. + + Matches pattern from working examples like claude-homelab marketplace. +- Upgrade fastmcp and mcp to resolve remaining security vulnerabilities. + [Claude] + + Security Updates: + - fastmcp 2.12.5 → 2.14.5 (fixes CVE-2025-66416, command injection, XSS, auth takeover) + - mcp 1.16.0 → 1.26.0 (enables DNS rebinding protection, addresses CVE requirements) + - websockets 13.1 → 16.0 (required dependency for fastmcp 2.14.5) + + Dependency Changes: + + beartype 0.22.9 + + cachetools 7.0.1 + + cloudpickle 3.1.2 + + croniter 6.0.0 + + diskcache 5.6.3 + + fakeredis 2.34.0 + + importlib-metadata 8.7.1 + + jsonref 1.1.1 + + lupa 2.6 + + opentelemetry-api 1.39.1 + + pathvalidate 3.3.1 + + platformdirs 4.9.2 + + prometheus-client 0.24.1 + + py-key-value-aio 0.3.0 + + py-key-value-shared 0.3.0 + + pydocket 0.17.7 + + pyjwt 2.11.0 + + python-dateutil 2.9.0.post0 + + python-json-logger 4.0.0 + + redis 7.2.0 + + shellingham 1.5.4 + + sortedcontainers 2.4.0 + + typer 0.23.2 + + zipp 3.23.0 + + Removed Dependencies: + - isodate 0.7.2 + - lazy-object-proxy 1.12.0 + - markupsafe 3.0.3 + - openapi-core 0.22.0 + - openapi-schema-validator 0.6.3 + - openapi-spec-validator 0.7.2 + - rfc3339-validator 0.1.4 + - werkzeug 3.1.5 + + Testing: + - All 493 tests pass + - Type checking passes (ty check) + - Linting passes (ruff check) + + This completes the resolution of GitHub Dependabot security alerts. + Addresses the remaining 5 high/medium severity vulnerabilities in fastmcp and mcp packages. +- Correct marketplace.json source field and improve async operations. + [Jacob Magar] + + - Fix marketplace.json: change source from relative path to GitHub URL + (was "skills/unraid", now "https://github.com/jmagar/unraid-mcp") + This resolves the "Invalid input" schema validation error when adding + the marketplace to Claude Code + + - Refactor subscriptions autostart to use anyio.Path for async file checks + (replaces blocking pathlib.Path.exists() with async anyio.Path.exists()) + + - Update dependencies: anyio 4.11.0→4.12.1, attrs 25.3.0→25.4.0 +- Correct marketplace.json format for Claude Code compatibility. + [Claude] + + - Rename marketplace from "unraid-mcp" to "jmagar-unraid-mcp" to match expected directory structure + - Wrap description, version, homepage, and repository in metadata object per standard format + - Fixes "Marketplace file not found" error when adding marketplace to Claude Code + + Resolves marketplace installation issues by aligning with format used by other Claude Code marketplaces. +- Address PR comment #38 - remove duplicate User-Agent header. [Jacob + Magar] + + Resolves review thread PRRT_kwDOO6Hdxs5uu7z7 + - Removed redundant User-Agent header from per-request headers in make_graphql_request() + - User-Agent is already set as default header on the shared HTTP client + - httpx merges per-request headers with client defaults, so client-level default is sufficient +- Harden read-logs.sh against GraphQL injection and path traversal. + [Jacob Magar] + + - Remove slashes from LOG_NAME regex to block path traversal (e.g. + ../../etc/passwd). Only alphanumeric, dots, hyphens, underscores allowed. + - Cap LINES to 1-10000 range to prevent resource exhaustion. + - Add query script existence check before execution. + - Add query failure, empty response, and invalid JSON guards. + + Resolves review thread PRRT_kwDOO6Hdxs5uvKrj +- Address 5 critical and major PR review issues. [Jacob Magar] + + - Remove set -e from validate-marketplace.sh to prevent early exit on + check failures, allowing the summary to always be displayed (PRRT_kwDOO6Hdxs5uvKrc) + - Fix marketplace.json source path to point to skills/unraid instead of + ./ for correct plugin directory resolution (PRRT_kwDOO6Hdxs5uvKrg) + - Fix misleading trap registration comment in unraid-api-crawl.md and + add auth note to Apollo Studio URL (PRRT_kwDOO6Hdxs5uvO2t) + - Extract duplicated cleanup-with-error-handling in main.py into + _run_shutdown_cleanup() helper (PRRT_kwDOO6Hdxs5uvO3A) + - Add input validation to read-logs.sh to prevent GraphQL injection + via LOG_NAME and LINES parameters (PRRT_kwDOO6Hdxs5uvKrj) +- Address PR review comments on test suite. [Jacob Magar] + + - Rename test_start_http_401_unauthorized to test_list_http_401_unauthorized + to match the actual action="list" being tested (threads #19, #23) + - Use consistent PrefixedID format ("a"*64+":local") in test_start_container + instead of "abc123def456"*4 concatenation (thread #37) + - Refactor container_actions_require_id to use @pytest.mark.parametrize + so each action runs independently (thread #18) + - Fix docstring claiming ToolError for test that asserts success in + test_stop_mutation_returns_null (thread #26) + - Fix inaccurate comment about `in` operator checking truthiness; + it checks key existence (thread #25) + - Add edge case tests for temperature=0, temperature=null, and + logFile=null in test_storage.py (thread #31) + + Resolves review threads: PRRT_kwDOO6Hdxs5uvO2-, PRRT_kwDOO6Hdxs5uvOcf, + PRRT_kwDOO6Hdxs5uu7zx, PRRT_kwDOO6Hdxs5uvO28, PRRT_kwDOO6Hdxs5uvOcp, + PRRT_kwDOO6Hdxs5uvOcn, PRRT_kwDOO6Hdxs5uvKr3 +- Harden shell scripts with error handling and null guards. [Jacob + Magar] + + - dashboard.sh: Add // [] jq null guard on .data.array.disks[] (L176-177) + Resolves review thread PRRT_kwDOO6Hdxs5uvO21 + + - dashboard.sh: Default NAME to server key when env var unset (L221) + Resolves review thread PRRT_kwDOO6Hdxs5uvO22 + + - unraid-query.sh: Check curl exit code, empty response, and JSON validity + before piping to jq (L112-129) + Resolves review thread PRRT_kwDOO6Hdxs5uvO24 + + - disk-health.sh: Guard against missing query script and invalid responses + Resolves review thread PRRT_kwDOO6Hdxs5uvKrh +- Address 54 MEDIUM/LOW priority PR review issues. [Jacob Magar] + + Comprehensive fixes across Python code, shell scripts, and documentation + addressing all remaining MEDIUM and LOW priority review comments. + + Python Code Fixes (27 fixes): + - tools/info.py: Simplified dispatch with lookup tables, defensive guards, + CPU fallback formatting, !s conversion flags, module-level sync assertion + - tools/docker.py: Case-insensitive container ID regex, keyword-only confirm, + module-level ALL_ACTIONS constant + - tools/virtualization.py: Normalized single-VM dict responses, unified + list/details queries + - core/client.py: Fixed HTTP client singleton race condition, compound key + substring matching for sensitive data redaction + - subscriptions/: Extracted SSL context creation to shared helper in utils.py, + replaced deprecated ssl._create_unverified_context API + - tools/array.py: Renamed parity_history to parity_status, hoisted ALL_ACTIONS + - tools/storage.py: Fixed dict(None) risks, temperature 0 falsiness bug + - tools/notifications.py, keys.py, rclone.py: Fixed dict(None) TypeError risks + - tests/: Fixed generator type annotations, added coverage for compound keys + + Shell Script Fixes (13 fixes): + - dashboard.sh: Dynamic server discovery, conditional debug output, null-safe + jq, notification count guard order, removed unused variables + - unraid-query.sh: Proper JSON escaping via jq, --ignore-errors and --insecure + CLI flags, TLS verification now on by default + - validate-marketplace.sh: Removed unused YELLOW variable, defensive jq, + simplified repository URL output + + Documentation Fixes (24+ fixes): + - Version consistency: Updated all references to v0.2.0 across pyproject.toml, + plugin.json, marketplace.json, MARKETPLACE.md, __init__.py, README files + - Tool count updates: Changed all "26 tools" references to "10 tools, 90 actions" + - Markdown lint: Fixed MD022, MD031, MD047 issues across multiple files + - Research docs: Fixed auth headers, removed web artifacts, corrected stale info + - Skills docs: Fixed query examples, endpoint counts, env var references + + All 227 tests pass, ruff and ty checks clean. +- Update Subprotocol import and SSL handling in WebSocket modules. + [Jacob Magar] + + - Change Subprotocol import from deprecated websockets.legacy.protocol + to websockets.typing (canonical location in websockets 13.x) + - Fix SSL context handling in diagnostics.py to properly build + ssl.SSLContext objects, matching the pattern in manager.py + (previously passed UNRAID_VERIFY_SSL directly which breaks + when it's a CA bundle path string) +- Resolve ruff lint issues in storage tool and tests. [Jacob Magar] + + - Move _ALLOWED_LOG_PREFIXES to module level (N806: constant naming) + - Use f-string conversion flag {e!s} instead of {str(e)} (RUF010) + - Fix import block sorting in both files (I001) +- Address 18 CRITICAL+HIGH PR review comments. [Jacob Magar, config- + fixer, docker-fixer, info-fixer, keys-rclone-fixer, storage-fixer, + users-fixer, vm-fixer, websocket-fixer] + + **Critical Fixes (7 issues):** + - Fix GraphQL schema field names in users tool (role→roles, remove email) + - Fix GraphQL mutation signatures (addUserInput, deleteUser input) + - Fix dict(None) TypeError guards in users tool (use `or {}` pattern) + - Fix FastAPI version constraint (0.116.1→0.115.0) + - Fix WebSocket SSL context handling (support CA bundles, bool, and None) + - Fix critical disk threshold treated as warning (split counters) + + **High Priority Fixes (11 issues):** + - Fix Docker update/remove action response field mapping + - Fix path traversal vulnerability in log validation (normalize paths) + - Fix deleteApiKeys validation (check response before success) + - Fix rclone create_remote validation (check response) + - Fix keys input_data type annotation (dict[str, Any]) + - Fix VM domain/domains fallback restoration + + **Changes by file:** + - unraid_mcp/tools/docker.py: Response field mapping + - unraid_mcp/tools/info.py: Split critical/warning counters + - unraid_mcp/tools/storage.py: Path normalization for traversal protection + - unraid_mcp/tools/users.py: GraphQL schema + null handling + - unraid_mcp/tools/keys.py: Validation + type annotations + - unraid_mcp/tools/rclone.py: Response validation + - unraid_mcp/tools/virtualization.py: Domain fallback + - unraid_mcp/subscriptions/manager.py: SSL context creation + - pyproject.toml: FastAPI version fix + - tests/*: New tests for all fixes + + **Review threads resolved:** + PRRT_kwDOO6Hdxs5uu70L, PRRT_kwDOO6Hdxs5uu70O, PRRT_kwDOO6Hdxs5uu70V, + PRRT_kwDOO6Hdxs5uu70e, PRRT_kwDOO6Hdxs5uu70i, PRRT_kwDOO6Hdxs5uu7zn, + PRRT_kwDOO6Hdxs5uu7z_, PRRT_kwDOO6Hdxs5uu7sI, PRRT_kwDOO6Hdxs5uu7sJ, + PRRT_kwDOO6Hdxs5uu7sK, PRRT_kwDOO6Hdxs5uu7Tk, PRRT_kwDOO6Hdxs5uu7Tn, + PRRT_kwDOO6Hdxs5uu7Tr, PRRT_kwDOO6Hdxs5uu7Ts, PRRT_kwDOO6Hdxs5uu7Tu, + PRRT_kwDOO6Hdxs5uu7Tv, PRRT_kwDOO6Hdxs5uu7Tw, PRRT_kwDOO6Hdxs5uu7Tx + + All tests passing. +- Add type annotation to resolve mypy Literal narrowing error. [Jacob + Magar] + +Other +~~~~~ +- Ci: add Homelab CI framework. [Simon Diesenreiter] +- Refactor: move MCP server config inline to plugin.json. [Jacob Magar] + + Move MCP server configuration from standalone .mcp.json to inline + definition in plugin.json. This consolidates all plugin metadata + in a single location. + + - Add type: stdio and env fields to inline config + - Remove redundant .mcp.json file + - Maintains same functionality with cleaner structure +- Feat: add MCP server configuration for Claude Code plugin integration. + [Jacob Magar] + + Add .mcp.json to configure the Unraid MCP server as a stdio-based MCP + server for Claude Code plugin integration. This allows Claude Code to + automatically start and connect to the server when the plugin is loaded. + + - Type: stdio (standard input/output communication) + - Command: uv run unraid-mcp-server + - Forces stdio transport mode via UNRAID_MCP_TRANSPORT env var +- Docs: fix markdown lint, broken links, stale counts, and publishing + guidance. [Jacob Magar] + + - 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 +- Feat: enhance test suite with 275 new tests across 4 validation + categories. [Claude, Jacob Magar] + + Add comprehensive test coverage beyond unit tests: + - Schema validation (93 tests): Validate all GraphQL queries/mutations against extracted Unraid API schema + - HTTP layer (88 tests): Test request construction, timeouts, and error handling at httpx level + - Subscriptions (55 tests): WebSocket lifecycle, reconnection, and protocol validation + - Safety audit (39 tests): Enforce destructive action confirmation requirements + + Total test count increased from 210 to 485 (130% increase), all passing in 5.91s. + + New dependencies: + - graphql-core>=3.2.0 for schema validation + - respx>=0.22.0 for HTTP layer mocking + + Files created: + - docs/unraid-schema.graphql (150-type GraphQL schema) + - tests/schema/test_query_validation.py + - tests/http_layer/test_request_construction.py + - tests/integration/test_subscriptions.py + - tests/safety/test_destructive_guards.py +- Feat: harden API safety and expand command docs with full test + coverage. [Jacob Magar] +- Refactor: move plugin manifest to repository root per Claude Code best + practices. [Jacob Magar] + + - Move plugin.json from skills/unraid/.claude-plugin/ to .claude-plugin/ + - Update validation script to use correct plugin manifest path + - Add plugin structure section to root README.md + - Add installation instructions to skills/unraid/README.md + - Aligns with Claude Code's expectation for source: './' in marketplace.json +- Chore: enhance project metadata, tooling, and documentation. [Claude, + Jacob Magar] + + **Project Configuration:** + - Enhance pyproject.toml with comprehensive metadata, keywords, and classifiers + - Add LICENSE file (MIT) for proper open-source distribution + - Add PUBLISHING.md with comprehensive publishing guidelines + - Update .gitignore to exclude tool artifacts (.cache, .pytest_cache, .ruff_cache, .ty_cache) + - Ignore documentation working directories (.docs, .full-review, docs/plans, docs/sessions) + + **Documentation:** + - Add extensive Unraid API research documentation + - API source code analysis and resolver mapping + - Competitive analysis and feature gap assessment + - Release notes analysis (7.0.0, 7.1.0, 7.2.0) + - Connect platform overview and remote access documentation + - Document known API patterns, limitations, and edge cases + + **Testing & Code Quality:** + - Expand test coverage across all tool modules + - Add destructive action confirmation tests + - Improve test assertions and error case validation + - Refine type annotations for better static analysis + + **Tool Improvements:** + - Enhance error handling consistency across all tools + - Improve type safety with explicit type annotations + - Refine GraphQL query construction patterns + - Better handling of optional parameters and edge cases + + This commit prepares the project for v0.2.0 release with improved + metadata, comprehensive documentation, and enhanced code quality. +- Feat: consolidate 26 tools into 10 tools with 90 actions. [Jacob + Magar] + + Refactor the entire tool layer to use the consolidated action pattern + (action: Literal[...] with QUERIES/MUTATIONS dicts). This reduces LLM + context from ~12k to ~5k tokens while adding ~60 new API capabilities. + + New tools: unraid_info (19 actions), unraid_array (12), unraid_notifications (9), + unraid_users (8), unraid_keys (5). Rewritten: unraid_docker (15), unraid_vm (9), + unraid_storage (6), unraid_rclone (4), unraid_health (3). + + Includes 129 tests across 10 test files, code review fixes for 16 issues + (severity ordering, PrefixedID regex, sensitive var redaction, etc.). + + Removes tools/system.py (replaced by tools/info.py). Version bumped to 0.2.0. +- Chore: update .gitignore. [Jacob Magar] +- Move pid and log files to /tmp directory. [Claude, Jacob Magar] + + - Update dev.sh to use /tmp for LOG_DIR instead of PROJECT_DIR/logs + - Update settings.py to use /tmp for LOGS_DIR instead of PROJECT_ROOT/logs + - This change moves both pid files and log files to the temporary directory + + 🤖 Generated with [Claude Code](https://claude.ai/code) +- Remove env_file from docker-compose and use explicit environment + variables. [Claude, Jacob Magar] + + - Remove env_file directive from docker-compose.yml to eliminate .env file dependency + - Add explicit environment variable declarations with default values using ${VAR:-default} syntax + - Update port mapping to use UNRAID_MCP_PORT environment variable for both host and container + - Include all 11 environment variables used by the application with proper defaults + - Update README.md Docker deployment instructions to use export commands instead of .env files + - Update manual Docker run command to use -e flags instead of --env-file + + This makes Docker deployment self-contained and follows container best practices. + + 🤖 Generated with [Claude Code](https://claude.ai/code) +- Replace log rotation with 10MB overwrite behavior. [Claude, Jacob + Magar] + + - Create OverwriteFileHandler class that caps log files at 10MB and overwrites instead of rotating + - Remove RotatingFileHandler dependency and backup file creation + - Add reset marker logging when file limit is reached for troubleshooting + - Update all logger configurations (main, FastMCP, and root loggers) + - Increase file size limit from 5MB to 10MB as requested + - Maintain existing Rich console formatting and error handling + + 🤖 Generated with [Claude Code](https://claude.ai/code) +- Align documentation and Docker configuration with current + implementation. [Claude, Jacob Magar] + + - Fix README.md: Make Docker deployment recommended, remove duplicate installation section + - Fix Dockerfile: Copy correct source files (unraid_mcp/, uv.lock, README.md) instead of non-existent unraid_mcp_server.py + - Update docker-compose.yml: Enable build configuration and use .env instead of .env.local + - Add missing environment variables to .env.example and .env: UNRAID_AUTO_START_SUBSCRIPTIONS, UNRAID_MAX_RECONNECT_ATTEMPTS + - Fix CLAUDE.md: Correct environment hierarchy documentation (../env.local → ../.env.local) + - Remove unused unraid-schema.json file + + 🤖 Generated with [Claude Code](https://claude.ai/code) +- Lintfree. [Jacob Magar] +- Add Claude Code agent configuration and GraphQL introspection. + [Claude, Jacob Magar] + + - Added KFC (Kent Feature Creator) spec workflow agents for requirements, design, tasks, testing, implementation and evaluation + - Added Claude Code settings configuration for agent workflows + - Added GraphQL introspection query and schema files for Unraid API exploration + - Updated development script with additional debugging and schema inspection capabilities + - Enhanced logging configuration with structured formatting + - Updated pyproject.toml dependencies and uv.lock + + 🤖 Generated with [Claude Code](https://claude.ai/code) +- Remove unused MCP resources and update documentation. [Claude, Jacob + Magar] + + - Remove array_status, system_info, notifications_overview, and parity_status resources + - Keep only logs_stream resource (unraid://logs/stream) which is working properly + - Update README.md with current resource documentation and modern docker compose syntax + - Fix import path issues that were causing subscription errors + - Update environment configuration examples + - Clean up subscription manager to only include working log streaming + + 🤖 Generated with [Claude Code](https://claude.ai/code) +- Migrate to uv and FastMCP architecture with comprehensive tooling. + [Claude, Jacob Magar] + + - Replace pip/requirements.txt with uv and pyproject.toml + - Restructure as single-file MCP server using FastMCP + - Add comprehensive Unraid management tools (containers, VMs, storage, logs) + - Implement multiple transport support (streamable-http, SSE, stdio) + - Add robust error handling and timeout management + - Include project documentation and API feature tracking + - Remove outdated cline documentation structure + + 🤖 Generated with [Claude Code](https://claude.ai/code) +- Update docker-compose.yml. [Jacob Magar] + + diff --git a/VERSION b/VERSION index 8a9ecc2..4e379d2 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.0.1 \ No newline at end of file +0.0.2