Skip to main content
Glama
safurrier

MCP Filesystem Server

find_empty_directories

Identify and list empty directories in a filesystem to help clean up unused folder structures and optimize storage organization.

Instructions

Find empty directories.

Args:
    path: Starting directory
    recursive: Whether to search subdirectories
    exclude_patterns: Optional patterns to exclude
    format: Output format ('text' or 'json')
    ctx: MCP context

Returns:
    Empty directory information

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
pathYes
recursiveNo
exclude_patternsNo
formatNotext

Implementation Reference

  • Core implementation of find_empty_directories in AdvancedFileOperations class. Recursively scans directories to identify empty ones, handles path validation, exclusion patterns, and permission errors.
    async def find_empty_directories(
        self,
        root_path: Union[str, Path],
        recursive: bool = True,
        exclude_patterns: Optional[List[str]] = None,
    ) -> List[str]:
        """Find empty directories.
    
        Args:
            root_path: Starting directory
            recursive: Whether to search subdirectories
            exclude_patterns: Optional patterns to exclude
    
        Returns:
            List of empty directory paths
    
        Raises:
            ValueError: If root_path is outside allowed directories
        """
        abs_path, allowed = await self.validator.validate_path(root_path)
        if not allowed:
            raise ValueError(f"Path outside allowed directories: {root_path}")
    
        if not abs_path.is_dir():
            raise ValueError(f"Not a directory: {root_path}")
    
        # Compile exclude patterns if provided
        exclude_regexes = []
        if exclude_patterns:
            for exclude in exclude_patterns:
                try:
                    exclude_regexes.append(re.compile(exclude))
                except re.error:
                    logger.warning(f"Invalid exclude pattern: {exclude}")
    
        empty_dirs = []
    
        async def scan_for_empty_dirs(dir_path: Path) -> bool:
            """Scan for empty directories, return True if directory is empty."""
            try:
                entries = await anyio.to_thread.run_sync(list, dir_path.iterdir())
    
                if not entries:
                    # Found an empty directory
                    empty_dirs.append(str(dir_path))
                    return True
    
                # If not recursive, just check if this directory is empty
                if not recursive:
                    return False
    
                # Check if directory is empty after checking all subdirectories
                is_empty = True
    
                for entry in entries:
                    # Skip if matched by exclude pattern
                    path_str = str(entry)
                    excluded = False
                    for exclude_re in exclude_regexes:
                        if exclude_re.search(path_str):
                            excluded = True
                            break
    
                    if excluded:
                        # Treat excluded entries as if they don't exist
                        continue
    
                    if entry.is_file():
                        # Files make the directory non-empty
                        is_empty = False
                    elif entry.is_dir():
                        # Check if this subdir is allowed
                        entry_abs, entry_allowed = await self.validator.validate_path(
                            entry
                        )
                        if entry_allowed:
                            # If any subdirectory is non-empty, this directory is non-empty
                            subdir_empty = await scan_for_empty_dirs(entry)
                            if not subdir_empty:
                                is_empty = False
    
                if is_empty:
                    empty_dirs.append(str(dir_path))
    
                return is_empty
    
            except (PermissionError, FileNotFoundError):
                # Skip directories we can't access
                return False
    
        await scan_for_empty_dirs(abs_path)
        return empty_dirs
  • MCP tool registration for find_empty_directories. Delegates to AdvancedFileOperations implementation, handles JSON/text formatting, and error responses.
    @mcp.tool()
    async def find_empty_directories(
        path: str,
        ctx: Context,
        recursive: bool = True,
        exclude_patterns: Optional[List[str]] = None,
        format: str = "text",
    ) -> str:
        """Find empty directories.
    
        Args:
            path: Starting directory
            recursive: Whether to search subdirectories
            exclude_patterns: Optional patterns to exclude
            format: Output format ('text' or 'json')
            ctx: MCP context
    
        Returns:
            Empty directory information
        """
        try:
            components = get_components()
            results = await components["advanced"].find_empty_directories(
                path, recursive, exclude_patterns
            )
    
            if format.lower() == "json":
                return json.dumps(results, indent=2)
    
            # Format as text
            if not results:
                return "No empty directories found"
    
            return f"Found {len(results)} empty directories:\n\n" + "\n".join(results)
    
        except Exception as e:
            return f"Error finding empty directories: {str(e)}"
Behavior2/5

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

With no annotations provided, the description carries the full burden of behavioral disclosure. While 'Find empty directories' implies a read-only operation, it doesn't specify whether this requires special permissions, how it handles symbolic links, what happens with permission errors, or any rate limits. The description mentions output format options but doesn't describe the actual return structure or what 'empty directory information' includes.

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

Conciseness4/5

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

The description is appropriately sized and well-structured with clear sections for Args and Returns. The purpose statement is front-loaded. However, the 'ctx: MCP context' parameter explanation adds no value (it's boilerplate that should be omitted), and the Returns section is vague enough that it could be more concise or informative.

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

Completeness2/5

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

For a tool with 4 parameters, 0% schema coverage, no annotations, and no output schema, the description is insufficient. It doesn't explain what constitutes an 'empty' directory, how the search algorithm works, what the output actually contains, or provide any examples. The tool has meaningful complexity (recursive search with exclusions and format options) that isn't adequately addressed.

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?

With 0% schema description coverage, the description adds some value by listing all 4 parameters with brief explanations. However, it doesn't fully compensate for the schema gap - it doesn't explain what 'empty' means (no files at all? no regular files?), what patterns are supported for exclude_patterns, or provide examples. The parameter explanations are minimal and don't add rich semantic context beyond naming them.

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's purpose with 'Find empty directories' - a specific verb+resource combination. It distinguishes itself from siblings like 'list_directory' or 'directory_tree' by focusing specifically on empty directories rather than general directory listing. However, it doesn't explicitly differentiate from all siblings, so it doesn't reach the highest score.

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

Usage Guidelines2/5

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

The description provides no guidance on when to use this tool versus alternatives. With siblings like 'list_directory' and 'directory_tree' that also provide directory information, there's no indication of when this specialized tool is preferable. No exclusions, prerequisites, or comparison to similar tools are mentioned.

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/safurrier/mcp-filesystem'

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