This commit is contained in:
Jacob Magar
2025-08-12 11:35:00 -04:00
parent 8fbec924cd
commit 493a376640
34 changed files with 525 additions and 1564 deletions

View File

@@ -5,7 +5,7 @@ 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, Dict, List, Optional
from typing import Any
from fastmcp import FastMCP
@@ -14,15 +14,15 @@ from ..core.client import make_graphql_request
from ..core.exceptions import ToolError
def register_rclone_tools(mcp: FastMCP):
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]]:
async def list_rclone_remotes() -> list[dict[str, Any]]:
"""Retrieves all configured RClone remotes with their configuration details."""
try:
query = """
@@ -37,25 +37,25 @@ def register_rclone_tools(mcp: FastMCP):
}
}
"""
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 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)}")
raise ToolError(f"Failed to list RClone remotes: {str(e)}") from e
@mcp.tool()
async def get_rclone_config_form(provider_type: Optional[str] = None) -> Dict[str, Any]:
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')
"""
@@ -71,29 +71,29 @@ def register_rclone_tools(mcp: FastMCP):
}
}
"""
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 form_data
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)}")
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]:
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')
@@ -111,7 +111,7 @@ def register_rclone_tools(mcp: FastMCP):
}
}
"""
variables = {
"input": {
"name": name,
@@ -119,9 +119,9 @@ def register_rclone_tools(mcp: FastMCP):
"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}")
@@ -130,18 +130,18 @@ def register_rclone_tools(mcp: FastMCP):
"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)}")
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]:
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
"""
@@ -153,26 +153,26 @@ def register_rclone_tools(mcp: FastMCP):
}
}
"""
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)}")
raise ToolError(f"Failed to delete RClone remote {name}: {str(e)}") from e
logger.info("RClone tools registered successfully")
logger.info("RClone tools registered successfully")