Skip to main content
Glama

list_windows

Retrieve available windows for screenshot capture, providing IDs and titles to select targets for automated document processing and PDF conversion.

Instructions

List all available windows for screenshot capture.

Returns:
    JSON string containing list of windows with their IDs, titles, and properties.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Implementation Reference

  • Primary MCP tool handler and registration for 'list_windows'. Initializes CrossPlatformWindowManager, lists windows, adds environment info, and returns formatted JSON response.
    @mcp.tool()
    async def list_windows() -> str:
        """
        List all available windows for screenshot capture.
        
        Returns:
            JSON string containing list of windows with their IDs, titles, and properties.
        """
        try:
            wm = get_window_manager()
            windows = wm.list_windows()
            env_info = wm.get_environment_info()
            
            result = {
                "status": "success",
                "windows": windows,
                "count": len(windows),
                "environment": env_info
            }
            
            return json.dumps(result, indent=2)
            
        except Exception as e:
            logger.error(f"Failed to list windows: {e}")
            return json.dumps({
                "status": "error",
                "error": str(e),
                "windows": [],
                "count": 0,
                "environment": {"error": "Could not determine environment"}
            })
  • CrossPlatformWindowManager.list_windows(): Platform-agnostic wrapper that delegates to specific manager (WindowsWindowManager or WindowCapture) and enriches window data with environment information.
    def list_windows(self) -> List[Dict[str, str]]:
        """List all available windows using the appropriate manager."""
        try:
            windows = self.manager.list_windows()
            
            # Add environment info to each window
            for window in windows:
                window['environment'] = self.environment
                if 'type' not in window:
                    window['type'] = 'x11' if self.environment == 'linux' else self.environment
                    
            return windows
        except Exception as e:
            logger.error(f"Failed to list windows: {e}")
            return []
  • WindowsWindowManager.list_windows(): Core implementation for Windows using detailed PowerShell script with Win32 API calls to enumerate capturable windows (visible, minimized, maximized) with properties like ID, title, process info, state.
        def list_windows(self) -> List[Dict[str, str]]:
            """
            List all Windows applications with visible windows using PowerShell.
            Returns list of window info dictionaries.
            """
            if not self.powershell_available:
                logger.error("PowerShell not available - cannot list Windows applications")
                return []
                
            try:
                # Enhanced PowerShell script to get comprehensive window information
                ps_script = '''
                Add-Type -TypeDefinition @"
                    using System;
                    using System.Runtime.InteropServices;
                    using System.Text;
                    
                    public class Win32 {
                        [DllImport("user32.dll")]
                        public static extern bool IsWindowVisible(IntPtr hWnd);
                        
                        [DllImport("user32.dll")]
                        public static extern bool IsIconic(IntPtr hWnd);
                        
                        [DllImport("user32.dll")]
                        public static extern bool IsZoomed(IntPtr hWnd);
                        
                        [DllImport("user32.dll")]
                        public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
                        
                        [DllImport("user32.dll")]
                        public static extern int GetWindowTextLength(IntPtr hWnd);
                        
                        [DllImport("user32.dll")]
                        public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
                    }
    "@
    
                $windows = @()
    
                # Get processes with capturable windows only
                Get-Process | Where-Object { 
                    $_.MainWindowHandle -ne 0 -and $_.ProcessName -notmatch "^(dwm|csrss|winlogon|wininit)$"
                } | ForEach-Object {
                    $handle = [IntPtr]$_.MainWindowHandle
                    $isVisible = [Win32]::IsWindowVisible($handle)
                    $isMinimized = [Win32]::IsIconic($handle)
                    $isMaximized = [Win32]::IsZoomed($handle)
                    
                    # Only include windows that are in capturable states
                    # Skip hidden windows that can't be meaningfully captured
                    if (-not ($isVisible -or $isMinimized)) {
                        return  # Skip this window
                    }
                    
                    # Get window title using Windows API (more reliable than MainWindowTitle)
                    $titleLength = [Win32]::GetWindowTextLength($handle)
                    if ($titleLength -gt 0) {
                        $title = New-Object System.Text.StringBuilder($titleLength + 1)
                        [Win32]::GetWindowText($handle, $title, $title.Capacity) | Out-Null
                        $windowTitle = $title.ToString()
                    } else {
                        $windowTitle = $_.MainWindowTitle
                    }
                    
                    # Include window even if title is empty, but provide useful info
                    if ([string]::IsNullOrEmpty($windowTitle)) {
                        $windowTitle = "[$($_.ProcessName) - $($_.Id)]"
                    }
                    
                    # Determine window state - only capturable states
                    $windowState = if ($isMinimized) { 
                        "minimized" 
                    } elseif ($isMaximized) { 
                        "maximized" 
                    } else { 
                        "normal" 
                    }
                    
                    $windows += @{
                        id = $_.MainWindowHandle.ToString()
                        title = $windowTitle
                        process_name = $_.ProcessName
                        process_id = $_.Id.ToString()
                        window_handle = $_.MainWindowHandle.ToString()
                        is_visible = $isVisible
                        is_minimized = $isMinimized
                        is_maximized = $isMaximized
                        window_state = $windowState
                        type = "windows"
                    }
                }
    
                # Convert to JSON
                $windows | ConvertTo-Json -Compress
                '''
                
                result = subprocess.run(
                    ['powershell.exe', '-Command', ps_script],
                    capture_output=True,
                    text=True,
                    check=True,
                    timeout=30,  # 30 second timeout for window enumeration
                    encoding='utf-8',
                    errors='ignore'  # Ignore encoding errors to handle special characters
                )
                
                import json
                if result.stdout.strip():
                    try:
                        # Handle both single object and array responses
                        data = json.loads(result.stdout.strip())
                        if isinstance(data, dict):
                            data = [data]  # Convert single result to list
                        
                        windows = []
                        for window_info in data:
                            # Only include windows with valid window handles (> 0)
                            window_handle = str(window_info.get('window_handle', '0'))
                            if window_handle == '0':
                                continue  # Skip processes without actual windows
                            
                            # Use the enhanced window information from the new PowerShell script
                            windows.append({
                                'id': str(window_info.get('id', '')),
                                'title': window_info.get('title', ''),
                                'process_name': window_info.get('process_name', ''),
                                'process_id': str(window_info.get('process_id', '')),
                                'window_handle': window_handle,
                                'is_visible': window_info.get('is_visible', False),
                                'is_minimized': window_info.get('is_minimized', False),
                                'is_maximized': window_info.get('is_maximized', False),
                                'window_state': window_info.get('window_state', 'normal'),  # Default to normal instead of unknown
                                'type': 'windows'
                            })
                        
                        logger.info(f"Found {len(windows)} capturable windows using enhanced detection")
                        if windows:
                            # Log stats about capturable window states for debugging
                            normal_count = sum(1 for w in windows if w['window_state'] == 'normal')
                            minimized_count = sum(1 for w in windows if w['window_state'] == 'minimized')
                            maximized_count = sum(1 for w in windows if w['window_state'] == 'maximized')
                            logger.info(f"Window states: {normal_count} normal, {minimized_count} minimized, {maximized_count} maximized")
                        
                        return windows
                    except json.JSONDecodeError as e:
                        logger.error(f"Failed to parse PowerShell JSON output: {e}")
                        logger.error(f"PowerShell output was: {result.stdout[:500]}...")  # Log first 500 chars for debugging
                        return []
                else:
                    logger.warning("PowerShell returned empty output - no windows detected")
                    return []
                
            except subprocess.TimeoutExpired:
                logger.error("PowerShell window enumeration timed out after 30 seconds")
                return []
            except subprocess.CalledProcessError as e:
                logger.error(f"Failed to list Windows applications: {e}")
                return []
  • WindowCapture.list_windows(): Linux/X11-specific implementation using 'wmctrl -l' command to list windows with basic properties (ID, title, desktop, machine).
    def list_windows(self) -> List[Dict[str, str]]:
        """
        List all available windows using wmctrl command.
        Returns list of window info dictionaries.
        """
        try:
            # Use wmctrl to list windows
            result = subprocess.run(
                ['wmctrl', '-l'],
                capture_output=True,
                text=True,
                check=True,
                timeout=10  # 10 second timeout for window listing
            )
            
            windows = []
            for line in result.stdout.strip().split('\n'):
                if line.strip():
                    parts = line.split(None, 3)
                    if len(parts) >= 4:
                        window_id = parts[0]
                        desktop = parts[1]
                        machine = parts[2]
                        title = parts[3]
                        
                        windows.append({
                            'id': window_id,
                            'title': title,
                            'desktop': desktop,
                            'machine': machine
                        })
            
            return windows
            
        except subprocess.CalledProcessError as e:
            logger.error(f"Failed to list windows with wmctrl: {e}")
            return []
        except FileNotFoundError:
            logger.error("wmctrl not found. Please install: sudo apt-get install wmctrl")
            return []

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/PovedaAqui/auto-snap-mcp'

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