mirror of
https://github.com/jmagar/unraid-mcp.git
synced 2026-03-02 00:04:45 -08:00
179 lines
6.1 KiB
Python
179 lines
6.1 KiB
Python
"""RClone cloud storage remote management tools.
|
|
|
|
This module provides tools for managing RClone remotes including listing existing
|
|
remotes, getting configuration forms, creating new remotes, and deleting remotes
|
|
for various cloud storage providers (S3, Google Drive, Dropbox, FTP, etc.).
|
|
"""
|
|
|
|
from typing import Any
|
|
|
|
from fastmcp import FastMCP
|
|
|
|
from ..config.logging import logger
|
|
from ..core.client import make_graphql_request
|
|
from ..core.exceptions import ToolError
|
|
|
|
|
|
def register_rclone_tools(mcp: FastMCP) -> None:
|
|
"""Register all RClone tools with the FastMCP instance.
|
|
|
|
Args:
|
|
mcp: FastMCP instance to register tools with
|
|
"""
|
|
|
|
@mcp.tool()
|
|
async def list_rclone_remotes() -> list[dict[str, Any]]:
|
|
"""Retrieves all configured RClone remotes with their configuration details."""
|
|
try:
|
|
query = """
|
|
query ListRCloneRemotes {
|
|
rclone {
|
|
remotes {
|
|
name
|
|
type
|
|
parameters
|
|
config
|
|
}
|
|
}
|
|
}
|
|
"""
|
|
|
|
response_data = await make_graphql_request(query)
|
|
|
|
if "rclone" in response_data and "remotes" in response_data["rclone"]:
|
|
remotes = response_data["rclone"]["remotes"]
|
|
logger.info(f"Retrieved {len(remotes)} RClone remotes")
|
|
return list(remotes) if isinstance(remotes, list) else []
|
|
|
|
return []
|
|
|
|
except Exception as e:
|
|
logger.error(f"Failed to list RClone remotes: {str(e)}")
|
|
raise ToolError(f"Failed to list RClone remotes: {str(e)}") from e
|
|
|
|
@mcp.tool()
|
|
async def get_rclone_config_form(provider_type: str | None = None) -> dict[str, Any]:
|
|
"""
|
|
Get RClone configuration form schema for setting up new remotes.
|
|
|
|
Args:
|
|
provider_type: Optional provider type to get specific form (e.g., 's3', 'drive', 'dropbox')
|
|
"""
|
|
try:
|
|
query = """
|
|
query GetRCloneConfigForm($formOptions: RCloneConfigFormInput) {
|
|
rclone {
|
|
configForm(formOptions: $formOptions) {
|
|
id
|
|
dataSchema
|
|
uiSchema
|
|
}
|
|
}
|
|
}
|
|
"""
|
|
|
|
variables = {}
|
|
if provider_type:
|
|
variables["formOptions"] = {"providerType": provider_type}
|
|
|
|
response_data = await make_graphql_request(query, variables)
|
|
|
|
if "rclone" in response_data and "configForm" in response_data["rclone"]:
|
|
form_data = response_data["rclone"]["configForm"]
|
|
logger.info(f"Retrieved RClone config form for {provider_type or 'general'}")
|
|
return dict(form_data) if isinstance(form_data, dict) else {}
|
|
|
|
raise ToolError("No RClone config form data received")
|
|
|
|
except Exception as e:
|
|
logger.error(f"Failed to get RClone config form: {str(e)}")
|
|
raise ToolError(f"Failed to get RClone config form: {str(e)}") from e
|
|
|
|
@mcp.tool()
|
|
async def create_rclone_remote(name: str, provider_type: str, config_data: dict[str, Any]) -> dict[str, Any]:
|
|
"""
|
|
Create a new RClone remote with the specified configuration.
|
|
|
|
Args:
|
|
name: Name for the new remote
|
|
provider_type: Type of provider (e.g., 's3', 'drive', 'dropbox', 'ftp')
|
|
config_data: Configuration parameters specific to the provider type
|
|
"""
|
|
try:
|
|
mutation = """
|
|
mutation CreateRCloneRemote($input: CreateRCloneRemoteInput!) {
|
|
rclone {
|
|
createRCloneRemote(input: $input) {
|
|
name
|
|
type
|
|
parameters
|
|
}
|
|
}
|
|
}
|
|
"""
|
|
|
|
variables = {
|
|
"input": {
|
|
"name": name,
|
|
"type": provider_type,
|
|
"config": config_data
|
|
}
|
|
}
|
|
|
|
response_data = await make_graphql_request(mutation, variables)
|
|
|
|
if "rclone" in response_data and "createRCloneRemote" in response_data["rclone"]:
|
|
remote_info = response_data["rclone"]["createRCloneRemote"]
|
|
logger.info(f"Successfully created RClone remote: {name}")
|
|
return {
|
|
"success": True,
|
|
"message": f"RClone remote '{name}' created successfully",
|
|
"remote": remote_info
|
|
}
|
|
|
|
raise ToolError("Failed to create RClone remote")
|
|
|
|
except Exception as e:
|
|
logger.error(f"Failed to create RClone remote {name}: {str(e)}")
|
|
raise ToolError(f"Failed to create RClone remote {name}: {str(e)}") from e
|
|
|
|
@mcp.tool()
|
|
async def delete_rclone_remote(name: str) -> dict[str, Any]:
|
|
"""
|
|
Delete an existing RClone remote by name.
|
|
|
|
Args:
|
|
name: Name of the remote to delete
|
|
"""
|
|
try:
|
|
mutation = """
|
|
mutation DeleteRCloneRemote($input: DeleteRCloneRemoteInput!) {
|
|
rclone {
|
|
deleteRCloneRemote(input: $input)
|
|
}
|
|
}
|
|
"""
|
|
|
|
variables = {
|
|
"input": {
|
|
"name": name
|
|
}
|
|
}
|
|
|
|
response_data = await make_graphql_request(mutation, variables)
|
|
|
|
if "rclone" in response_data and response_data["rclone"]["deleteRCloneRemote"]:
|
|
logger.info(f"Successfully deleted RClone remote: {name}")
|
|
return {
|
|
"success": True,
|
|
"message": f"RClone remote '{name}' deleted successfully"
|
|
}
|
|
|
|
raise ToolError(f"Failed to delete RClone remote '{name}'")
|
|
|
|
except Exception as e:
|
|
logger.error(f"Failed to delete RClone remote {name}: {str(e)}")
|
|
raise ToolError(f"Failed to delete RClone remote {name}: {str(e)}") from e
|
|
|
|
logger.info("RClone tools registered successfully")
|