Skip to main content
Glama

Maintenance and cleanup operations

maintenance
Read-only

Perform cleanup operations to manage storage and database hygiene for image generation workflows, including removing expired files, checking quota usage, 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 function for the 'maintenance' tool. Includes the @server.tool decorator, input schema via Pydantic Field annotations, operation validation, dispatching to MaintenanceService methods, and formatted ToolResult return.
    @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[
            int | None,
            Field(
                description="For local cleanup: maximum age in hours (default: 168 = 1 week)",
                ge=1,
                le=8760,
            ),
        ] = None,
        keep_count: Annotated[
            int | None,
            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
  • Pydantic-based input schema for the maintenance tool parameters: operation (str enum), dry_run (bool), max_age_hours (int|None), keep_count (int|None).
        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[
            int | None,
            Field(
                description="For local cleanup: maximum age in hours (default: 168 = 1 week)",
                ge=1,
                le=8760,
            ),
        ] = None,
        keep_count: Annotated[
            int | None,
            Field(
                description="For local cleanup: minimum number of recent files to keep",
                ge=1,
                le=1000,
            ),
        ] = None,
        ctx: Context = None,
    ) -> ToolResult:
  • The register_maintenance_tool function that defines the nested handler and registers it via @server.tool decorator.
    def register_maintenance_tool(server: FastMCP):
        """Register the maintenance tool with the FastMCP server."""
  • Server initialization calls register_maintenance_tool(self.server) to register the tool.
    from ..tools.maintenance import register_maintenance_tool
    from ..tools.output_stats import register_output_stats_tool
    from ..tools.upload_file import register_upload_file_tool
    
    register_generate_image_tool(self.server)
    register_upload_file_tool(self.server)
    register_output_stats_tool(self.server)
    register_maintenance_tool(self.server)
  • Key helper method in MaintenanceService implementing the full cleanup cycle, orchestrating all maintenance operations called by the tool handler.
    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("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 indicate readOnlyHint=true and openWorldHint=true, but the description adds valuable behavioral context: it specifies that operations like 'cleanup_expired' and 'cleanup_local' involve removal/deletion actions, mentions a storage budget ('~20GB'), and implies sequential execution for 'full_cleanup'. This goes beyond annotations by detailing what gets cleaned and operational constraints.

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 the purpose, followed by a bulleted list of operations that efficiently conveys key information. Every sentence earns its place by specifying operations without redundancy, making it easy to scan and understand.

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 with potential side effects) and lack of output schema, the description is mostly complete: it covers what each operation does and hints at behaviors like deletion. However, it could improve by mentioning expected outputs or error conditions, though annotations provide some safety context (readOnlyHint=true suggests non-destructive default).

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 fully documents all parameters. The description lists operation names but does not add meaning beyond what the schema provides (e.g., no extra details on 'dry_run' effects or 'max_age_hours' implications). Baseline 3 is appropriate as the schema handles parameter documentation adequately.

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

Purpose5/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 their purposes (e.g., 'Remove expired Files API entries', 'Clean old local files'). It distinguishes from sibling tools like 'generate_image' and 'upload_file' by focusing on system maintenance rather than content creation or file management.

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

Usage Guidelines4/5

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

The description provides clear context for when to use each operation (e.g., 'Check Files API storage usage vs. ~20GB budget' for monitoring, 'Clean up database inconsistencies' for data integrity). However, it does not explicitly state when NOT to use this tool or mention alternatives among siblings, though the distinct purpose makes alternatives less relevant.

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/zengwenliang416/banana-image-mcp'

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