Skip to main content
Glama
zhongweili
by zhongweili

Maintenance and cleanup operations

maintenance
Read-only

Perform maintenance operations to manage storage and database health, including cleaning expired files, checking quotas, and resolving inconsistencies.

Instructions

Perform maintenance operations following workflows.md patterns.

Available operations:

  • cleanup_expired: Remove expired Files API entries from database

  • cleanup_local: Clean old local files based on age/LRU

  • check_quota: Check Files API storage usage vs. ~20GB budget

  • database_hygiene: Clean up database inconsistencies

  • full_cleanup: Run all cleanup operations in sequence

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
operationYesMaintenance operation to perform: 'cleanup_expired', 'cleanup_local', 'check_quota', 'database_hygiene', 'full_cleanup'
dry_runNoIf true, only report what would be done without making changes
max_age_hoursNoFor local cleanup: maximum age in hours (default: 168 = 1 week)
keep_countNoFor local cleanup: minimum number of recent files to keep

Implementation Reference

  • Core handler for the 'maintenance' tool: decorated with @server.tool(), defines input schema, dispatches to MaintenanceService based on 'operation' param, formats markdown summaries, returns structured ToolResult.
    @server.tool(
        annotations={
            "title": "Maintenance and cleanup operations",
            "readOnlyHint": True,
            "openWorldHint": True,
        }
    )
    def maintenance(
        operation: Annotated[
            str,
            Field(
                description="Maintenance operation to perform: "
                "'cleanup_expired', 'cleanup_local', 'check_quota', 'database_hygiene', 'full_cleanup'"
            ),
        ],
        dry_run: Annotated[
            bool,
            Field(description="If true, only report what would be done without making changes"),
        ] = True,
        max_age_hours: Annotated[
            Optional[int],
            Field(
                description="For local cleanup: maximum age in hours (default: 168 = 1 week)",
                ge=1,
                le=8760,
            ),
        ] = None,
        keep_count: Annotated[
            Optional[int],
            Field(
                description="For local cleanup: minimum number of recent files to keep",
                ge=1,
                le=1000,
            ),
        ] = None,
        ctx: Context = None,
    ) -> ToolResult:
        """
        Perform maintenance operations following workflows.md patterns.
    
        Available operations:
        - cleanup_expired: Remove expired Files API entries from database
        - cleanup_local: Clean old local files based on age/LRU
        - check_quota: Check Files API storage usage vs. ~20GB budget
        - database_hygiene: Clean up database inconsistencies
        - full_cleanup: Run all cleanup operations in sequence
        """
        logger = logging.getLogger(__name__)
    
        try:
            logger.info(f"Maintenance operation: {operation}, dry_run={dry_run}")
    
            # Get services (would be injected in real implementation)
            maintenance_service = _get_maintenance_service()
    
            # Validate operation
            valid_operations = [
                "cleanup_expired",
                "cleanup_local",
                "check_quota",
                "database_hygiene",
                "full_cleanup",
            ]
    
            if operation not in valid_operations:
                raise ValidationError(
                    f"Invalid operation. Must be one of: {', '.join(valid_operations)}"
                )
    
            # Execute maintenance operation
            if operation == "cleanup_expired":
                result = maintenance_service.cleanup_expired_files(dry_run=dry_run)
                summary = _format_expired_cleanup_summary(result, dry_run)
    
            elif operation == "cleanup_local":
                result = maintenance_service.cleanup_local_files(
                    dry_run=dry_run,
                    max_age_hours=max_age_hours or 168,  # 1 week default
                    keep_count=keep_count or 10,  # Keep at least 10 recent files
                )
                summary = _format_local_cleanup_summary(result, dry_run)
    
            elif operation == "check_quota":
                result = maintenance_service.check_storage_quota()
                summary = _format_quota_summary(result)
    
            elif operation == "database_hygiene":
                result = maintenance_service.database_hygiene(dry_run=dry_run)
                summary = _format_database_hygiene_summary(result, dry_run)
    
            elif operation == "full_cleanup":
                result = maintenance_service.full_maintenance_cycle(
                    dry_run=dry_run, max_age_hours=max_age_hours or 168, keep_count=keep_count or 10
                )
                summary = _format_full_cleanup_summary(result, dry_run)
    
            else:
                # This shouldn't happen due to validation above
                raise ValidationError(f"Unhandled operation: {operation}")
    
            content = [TextContent(type="text", text=summary)]
    
            structured_content = {
                "operation": operation,
                "dry_run": dry_run,
                "workflow": "workflows.md_maintenance_sequence",
                "result": result,
                "parameters": {"max_age_hours": max_age_hours, "keep_count": keep_count},
            }
    
            logger.info(f"Maintenance operation {operation} completed successfully")
    
            return ToolResult(content=content, structured_content=structured_content)
    
        except ValidationError as e:
            logger.error(f"Validation error in maintenance: {e}")
            raise
        except Exception as e:
            logger.error(f"Unexpected error in maintenance: {e}")
            raise
  • Registration point where register_maintenance_tool is imported and invoked to add the maintenance tool to the FastMCP server instance.
    from ..tools.maintenance import register_maintenance_tool
    
    register_generate_image_tool(self.server)
    register_upload_file_tool(self.server)
    register_output_stats_tool(self.server)
    register_maintenance_tool(self.server)
  • Tool schema: @server.tool annotations (title, hints) and Pydantic input parameters with Field descriptions, validation (ge/le), defaults.
        annotations={
            "title": "Maintenance and cleanup operations",
            "readOnlyHint": True,
            "openWorldHint": True,
        }
    )
    def maintenance(
        operation: Annotated[
            str,
            Field(
                description="Maintenance operation to perform: "
                "'cleanup_expired', 'cleanup_local', 'check_quota', 'database_hygiene', 'full_cleanup'"
            ),
        ],
        dry_run: Annotated[
            bool,
            Field(description="If true, only report what would be done without making changes"),
        ] = True,
        max_age_hours: Annotated[
            Optional[int],
            Field(
                description="For local cleanup: maximum age in hours (default: 168 = 1 week)",
                ge=1,
                le=8760,
            ),
        ] = None,
        keep_count: Annotated[
            Optional[int],
            Field(
                description="For local cleanup: minimum number of recent files to keep",
                ge=1,
                le=1000,
            ),
        ] = None,
        ctx: Context = None,
    ) -> ToolResult:
  • Helper function to retrieve the singleton MaintenanceService instance used by the handler for actual cleanup operations.
    def _get_maintenance_service():
        """Get the maintenance service instance."""
        from ..services import get_maintenance_service
        return get_maintenance_service()
  • Key helper method in MaintenanceService: full_maintenance_cycle orchestrates all maintenance operations called by the tool's 'full_cleanup' operation.
    def full_maintenance_cycle(
        self, dry_run: bool = True, max_age_hours: int = 168, keep_count: int = 10
    ) -> Dict[str, Any]:
        """
        Run complete maintenance cycle with all operations.
    
        Args:
            dry_run: If True, only report what would be done
            max_age_hours: For local cleanup
            keep_count: For local cleanup
    
        Returns:
            Dictionary with results from all operations
        """
        try:
            self.logger.info(f"Starting full maintenance cycle (dry_run={dry_run})")
    
            results = {}
    
            # 1. Clean up expired Files API entries
            results["expired_cleanup"] = self.cleanup_expired_files(dry_run=dry_run)
    
            # 2. Clean up old local files
            results["local_cleanup"] = self.cleanup_local_files(
                dry_run=dry_run, max_age_hours=max_age_hours, keep_count=keep_count
            )
    
            # 3. Check storage quota
            results["quota_check"] = self.check_storage_quota()
    
            # 4. Database hygiene
            results["database_hygiene"] = self.database_hygiene(dry_run=dry_run)
    
            self.logger.info(f"Full maintenance cycle complete")
            return results
    
        except Exception as e:
            self.logger.error(f"Full maintenance cycle failed: {e}")
            return {"error": str(e)}
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations provide readOnlyHint=true and openWorldHint=true, indicating safe, non-destructive operations. The description adds valuable context beyond this: it specifies that operations like 'cleanup_expired' remove entries and 'full_cleanup' runs sequences, hinting at potential data changes despite readOnlyHint. It also mentions a '~20GB budget' for quota checks, offering practical constraints. No contradiction with annotations exists, as readOnlyHint might refer to overall safety, but the description enriches behavioral understanding.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured and front-loaded with a purpose statement, followed by a bulleted list of operations. Each bullet is concise and informative, with no wasted sentences. The entire description is appropriately sized for a multi-operation tool, making it easy to scan and understand quickly.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (multiple operations, 4 parameters) and rich annotations (readOnlyHint, openWorldHint), the description is mostly complete. It explains what each operation does, which compensates for the lack of output schema. However, it could benefit from more detail on outcomes or error handling, but the annotations and schema provide sufficient context for effective use.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all parameters thoroughly (e.g., operation choices, dry_run default, max_age_hours range). The description lists operation names with brief meanings (e.g., 'cleanup_local: Clean old local files based on age/LRU'), which adds minimal semantic value beyond the schema's operation descriptions. This meets the baseline for high schema coverage without significant enhancement.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool performs 'maintenance operations following workflows.md patterns' and lists five specific operations with brief explanations. This provides a clear verb+resource combination ('perform maintenance operations') and distinguishes it from sibling tools like generate_image or upload_file. However, it doesn't explicitly contrast with siblings beyond being a different category of tool.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage through the operation list (e.g., 'check_quota: Check Files API storage usage vs. ~20GB budget'), suggesting when to use specific operations. However, it lacks explicit guidance on when to choose this tool over alternatives (none of which are maintenance-related among siblings), nor does it provide when-not-to-use advice or prerequisites. The context is clear but not comprehensive.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/zhongweili/nanobanana-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server