execute_read_command
Execute read-only Unix/macOS terminal commands like ls, cat, and grep through a controlled interface, returning output and status for safe command execution.
Instructions
Execute a read-only Unix/macOS terminal command (ls, cat, grep, etc.).
Args: command: The read-only command to execute session_id: Optional session ID for permission management
Returns: A dictionary with command output and status
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| command | Yes | ||
| session_id | No |
Implementation Reference
- src/cmd_line_mcp/server.py:181-373 (handler)The `execute_read_command` tool handler function that validates the command, performs directory permission checks, and calls `_execute_command` if permitted.
async def execute_read_command( command: str, session_id: str | None = None ) -> dict[str, Any]: """ Execute a read-only Unix/macOS terminal command (ls, cat, grep, etc.). Args: command: The read-only command to execute session_id: Optional session ID for permission management Returns: A dictionary with command output and status """ # For Claude Desktop compatibility, use the fixed session ID when no session ID provided if not session_id: session_id = self.claude_desktop_session_id logger.info( f"Using persistent Claude Desktop session for read command: {session_id}" ) # Validate command and check directory permissions in one go # Get the latest command lists command_lists = self.config.get_effective_command_lists() allow_separators = self.config.get( "security", "allow_command_separators", True ) validation = validate_command( command, command_lists["read"], command_lists["write"], command_lists["system"], command_lists["blocked"], command_lists["dangerous_patterns"], allow_command_separators=allow_separators, ) if not validation["is_valid"]: return { "success": False, "output": "", "error": validation["error"], } if validation["command_type"] != "read": return { "success": False, "output": "", "error": "This tool only supports read commands. Use execute_command for other command types.", } # Extract directory and check permissions (apply same directory checks as in _execute_command) working_dir = extract_directory_from_command(command) logger.info(f"Read command - extracted working directory: {working_dir}") # Check if directory is whitelisted or has session approval directory_allowed = False if working_dir: # Check global whitelist first if is_directory_whitelisted(working_dir, self.whitelisted_directories): directory_allowed = True logger.info( f"Read command - directory '{working_dir}' is globally whitelisted" ) # Check session approvals if we have a session ID elif session_id and self.session_manager.has_directory_approval( session_id, working_dir ): directory_allowed = True logger.info( f"Read command - directory '{working_dir}' is approved for session {session_id}" ) else: logger.warning( f"Read command - directory '{working_dir}' is not whitelisted or approved" ) # For Claude Desktop compatibility mode (require_session_id = False) require_session_id = self.config.get( "security", "require_session_id", False ) auto_approve_in_desktop = self.config.get_section("security").get( "auto_approve_directories_in_desktop_mode", False ) if not require_session_id: # Check if the directory is approved in the persistent desktop session if self.session_manager.has_directory_approval( self.claude_desktop_session_id, working_dir ): directory_allowed = True logger.info( f"Read command - directory '{working_dir}' is approved in persistent desktop session" ) elif auto_approve_in_desktop: # Auto-approve directories in desktop mode if configured directory_allowed = True # Also add to persistent session for future requests self.session_manager.approve_directory( self.claude_desktop_session_id, working_dir ) logger.warning( f"Read command - auto-approving directory access in desktop mode: {working_dir}" ) else: # Only allow whitelisted directories if auto-approve is off directory_allowed = False logger.warning( f"Read command - directory '{working_dir}' is not whitelisted - restricting access" ) else: # If we couldn't extract a directory, default to requiring permission logger.warning( "Read command - could not extract working directory from command" ) working_dir = os.getcwd() # Default to current directory # Check whitelist for current directory if is_directory_whitelisted(working_dir, self.whitelisted_directories): directory_allowed = True elif session_id and self.session_manager.has_directory_approval( session_id, working_dir ): directory_allowed = True else: # For Claude Desktop compatibility mode require_session_id = self.config.get( "security", "require_session_id", False ) auto_approve_in_desktop = self.config.get_section("security").get( "auto_approve_directories_in_desktop_mode", False ) if not require_session_id: # Check if the directory is approved in the persistent desktop session if self.session_manager.has_directory_approval( self.claude_desktop_session_id, working_dir ): directory_allowed = True logger.info( f"Read command - directory '{working_dir}' is approved in persistent desktop session" ) elif auto_approve_in_desktop: # Auto-approve directories in desktop mode if configured directory_allowed = True # Also add to persistent session for future requests self.session_manager.approve_directory( self.claude_desktop_session_id, working_dir ) logger.warning( f"Read command - auto-approving directory access in desktop mode: {working_dir}" ) else: # Only allow whitelisted directories if auto-approve is off directory_allowed = False # If directory is not allowed if not directory_allowed: # Check if we're in Claude Desktop mode (no session ID or require_session_id=false) require_session_id = self.config.get( "security", "require_session_id", False ) if not session_id or not require_session_id: # Always use the fixed persistent session ID for Claude Desktop desktop_session_id = self.claude_desktop_session_id # Include approval request information for Claude Desktop return { "success": False, "output": "", "error": f"Read command - access to directory '{working_dir}' is not allowed. Only whitelisted directories can be accessed.\n" + f"Whitelisted directories include: {', '.join(self.whitelisted_directories)}\n" + "Note: To request access to this directory, use the approve_directory tool with:\n" + f' approve_directory(directory="{working_dir}", session_id="{desktop_session_id}", remember=True)', "directory": working_dir, "session_id": desktop_session_id, "requires_directory_approval": True, # Signal that approval is needed } else: # For normal mode, request approval return { "success": False, "output": "", "error": f"Read command - directory '{working_dir}' requires approval. Use approve_directory tool with session_id '{session_id}'.", "requires_directory_approval": True, "directory": working_dir, "session_id": session_id, } # Now that we've validated both the command and directory permissions, execute the command return await self._execute_command( command, command_type="read", session_id=session_id )