mirror of
https://github.com/jmagar/unraid-mcp.git
synced 2026-03-02 00:04:45 -08:00
fix: correct marketplace.json source field and improve async operations
- 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
This commit is contained in:
@@ -13,7 +13,7 @@
|
|||||||
"plugins": [
|
"plugins": [
|
||||||
{
|
{
|
||||||
"name": "unraid",
|
"name": "unraid",
|
||||||
"source": "skills/unraid",
|
"source": "https://github.com/jmagar/unraid-mcp",
|
||||||
"description": "Query and monitor Unraid servers via GraphQL API - array status, disk health, containers, VMs, system monitoring",
|
"description": "Query and monitor Unraid servers via GraphQL API - array status, disk health, containers, VMs, system monitoring",
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"tags": ["unraid", "monitoring", "homelab", "graphql", "docker", "virtualization"],
|
"tags": ["unraid", "monitoring", "homelab", "graphql", "docker", "virtualization"],
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ and the MCP protocol, providing fallback queries when subscription data is unava
|
|||||||
|
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
|
import anyio
|
||||||
from fastmcp import FastMCP
|
from fastmcp import FastMCP
|
||||||
|
|
||||||
from ..config.logging import logger
|
from ..config.logging import logger
|
||||||
@@ -50,7 +50,7 @@ async def autostart_subscriptions() -> None:
|
|||||||
if log_path is None:
|
if log_path is None:
|
||||||
# Default to syslog if available
|
# Default to syslog if available
|
||||||
default_path = "/var/log/syslog"
|
default_path = "/var/log/syslog"
|
||||||
if Path(default_path).exists():
|
if await anyio.Path(default_path).exists():
|
||||||
log_path = default_path
|
log_path = default_path
|
||||||
logger.info(f"[AUTOSTART] Using default log path: {default_path}")
|
logger.info(f"[AUTOSTART] Using default log path: {default_path}")
|
||||||
|
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ Provides the `unraid_storage` tool with 6 actions for shares, physical disks,
|
|||||||
unassigned devices, log files, and log content retrieval.
|
unassigned devices, log files, and log content retrieval.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from pathlib import Path
|
|
||||||
from typing import Any, Literal
|
from typing import Any, Literal
|
||||||
|
|
||||||
|
import anyio
|
||||||
from fastmcp import FastMCP
|
from fastmcp import FastMCP
|
||||||
|
|
||||||
from ..config.logging import logger
|
from ..config.logging import logger
|
||||||
@@ -111,7 +111,7 @@ def register_storage_tool(mcp: FastMCP) -> None:
|
|||||||
if not log_path:
|
if not log_path:
|
||||||
raise ToolError("log_path is required for 'logs' action")
|
raise ToolError("log_path is required for 'logs' action")
|
||||||
# Resolve path to prevent traversal attacks (e.g. /var/log/../../etc/shadow)
|
# Resolve path to prevent traversal attacks (e.g. /var/log/../../etc/shadow)
|
||||||
normalized = str(Path(log_path).resolve())
|
normalized = str(await anyio.Path(log_path).resolve())
|
||||||
if not any(normalized.startswith(p) for p in _ALLOWED_LOG_PREFIXES):
|
if not any(normalized.startswith(p) for p in _ALLOWED_LOG_PREFIXES):
|
||||||
raise ToolError(
|
raise ToolError(
|
||||||
f"log_path must start with one of: {', '.join(_ALLOWED_LOG_PREFIXES)}. "
|
f"log_path must start with one of: {', '.join(_ALLOWED_LOG_PREFIXES)}. "
|
||||||
|
|||||||
Reference in New Issue
Block a user