remove_orphans
Remove orphaned packages on Arch Linux to free up disk space. Preview changes with dry-run mode and exclude specific packages from removal.
Instructions
[MAINTENANCE] Remove all orphaned packages to free up disk space. Supports dry-run mode to preview changes and package exclusion. Only works on Arch Linux. Requires sudo access.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| dry_run | No | Preview what would be removed without actually removing. Default: true | |
| exclude | No | List of package names to exclude from removal |
Implementation Reference
- src/arch_ops_server/pacman.py:537-629 (handler)Core handler function implementing the remove_orphans MCP tool. Lists orphan packages, applies exclusions if provided, supports dry-run preview, and executes safe removal using 'sudo pacman -Rns --noconfirm' on Arch Linux systems.async def remove_orphans(dry_run: bool = True, exclude: Optional[List[str]] = None) -> Dict[str, Any]: """ Remove all orphaned packages. Args: dry_run: If True, show what would be removed without actually removing exclude: List of packages to exclude from removal Returns: Dict with removal status """ if not IS_ARCH: return create_error_response( "NotSupported", "Orphan removal is only available on Arch Linux" ) if not check_command_exists("pacman"): return create_error_response( "CommandNotFound", "pacman command not found" ) # First, get list of orphans orphans_result = await list_orphan_packages() if orphans_result.get("error"): return orphans_result orphans = orphans_result.get("orphans", []) if not orphans: return { "removed_count": 0, "packages": [], "message": "No orphan packages to remove" } # Apply exclusions if provided if exclude: orphans = [pkg for pkg in orphans if pkg not in exclude] if not orphans: return { "removed_count": 0, "packages": [], "message": "All orphan packages are in exclusion list" } logger.info(f"Removing {len(orphans)} orphan packages (dry_run={dry_run})") if dry_run: return { "dry_run": True, "would_remove_count": len(orphans), "packages": orphans, "message": "This is a dry run. No packages were removed." } try: # Remove orphans using pacman -Rns cmd = ["sudo", "pacman", "-Rns", "--noconfirm"] + orphans exit_code, stdout, stderr = await run_command( cmd, timeout=120, check=False, skip_sudo_check=True ) if exit_code != 0: logger.error(f"Orphan removal failed: {stderr}") return create_error_response( "RemovalError", f"Failed to remove orphan packages: {stderr}", f"Exit code: {exit_code}" ) logger.info(f"Successfully removed {len(orphans)} orphan packages") return { "success": True, "removed_count": len(orphans), "packages": orphans, "output": stdout } except Exception as e: logger.error(f"Orphan removal failed with exception: {e}") return create_error_response( "RemovalError", f"Failed to remove orphan packages: {str(e)}" )
- MCP tool schema definition including inputSchema for parameters dry_run (boolean, default true) and exclude (optional list of strings), with description specifying it's for removing orphans on Arch with sudo.name="remove_orphans", description="[MAINTENANCE] Remove all orphaned packages to free up disk space. Supports dry-run mode to preview changes and package exclusion. Only works on Arch Linux. Requires sudo access.", inputSchema={ "type": "object", "properties": { "dry_run": { "type": "boolean", "description": "Preview what would be removed without actually removing. Default: true", "default": True }, "exclude": { "type": "array", "items": {"type": "string"}, "description": "List of package names to exclude from removal" } }, "required": [] } ),
- src/arch_ops_server/server.py:1247-1254 (registration)Tool dispatch registration in the MCP server's call_tool handler, which extracts arguments, checks Arch Linux platform, calls the remove_orphans function from pacman.py, and formats the JSON response.elif name == "remove_orphans": if not IS_ARCH: return [TextContent(type="text", text="Error: remove_orphans only available on Arch Linux systems")] dry_run = arguments.get("dry_run", True) exclude = arguments.get("exclude", None) result = await remove_orphans(dry_run, exclude) return [TextContent(type="text", text=json.dumps(result, indent=2))]
- Helper function called by remove_orphans to list orphan packages using 'pacman -Qtdq' command.async def list_orphan_packages() -> Dict[str, Any]: """ List all orphaned packages (dependencies no longer required). Returns: Dict with list of orphan packages """ if not IS_ARCH: return create_error_response( "NotSupported", "Orphan package detection is only available on Arch Linux" ) if not check_command_exists("pacman"): return create_error_response( "CommandNotFound", "pacman command not found" ) logger.info("Listing orphan packages") try: exit_code, stdout, stderr = await run_command( ["pacman", "-Qtdq"], timeout=10, check=False ) # Exit code 1 with no output means no orphans if exit_code == 1 and not stdout.strip(): logger.info("No orphan packages found") return { "orphan_count": 0, "orphans": [] } if exit_code != 0: logger.error(f"Failed to list orphans: {stderr}") return create_error_response( "CommandError", f"Failed to list orphan packages: {stderr}", f"Exit code: {exit_code}" ) # Parse output - one package per line orphans = [pkg.strip() for pkg in stdout.strip().split('\n') if pkg.strip()] logger.info(f"Found {len(orphans)} orphan packages") return { "orphan_count": len(orphans), "orphans": orphans } except Exception as e: logger.error(f"Orphan listing failed with exception: {e}") return create_error_response( "CommandError", f"Failed to list orphan packages: {str(e)}" )
- Tool metadata defining category, platform requirements, permissions, workflow, and related/prerequisite tools for remove_orphans."remove_orphans": ToolMetadata( name="remove_orphans", category="maintenance", platform="arch", permission="write", workflow="cleanup", related_tools=["list_orphan_packages"], prerequisite_tools=["list_orphan_packages"]