Skip to main content
Glama
safurrier

MCP Filesystem Server

list_directory

Retrieve detailed directory and file listings from a specified path, with options to include hidden files, apply filtering patterns, and choose output format (text or JSON).

Instructions

Get a detailed listing of files and directories in a path.

Args: path: Path to the directory include_hidden: Whether to include hidden files (starting with .) pattern: Optional glob pattern to filter entries format: Output format ('text' or 'json') ctx: MCP context Returns: Formatted directory listing

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
formatNotext
include_hiddenNo
pathYes
patternNo

Implementation Reference

  • MCP tool handler for 'list_directory'. Dispatches to operations.list_directory or list_directory_formatted based on 'format' parameter ('text' or 'json'), handles errors and JSON serialization.
    @mcp.tool() async def list_directory( path: str, ctx: Context, include_hidden: bool = False, pattern: Optional[str] = None, format: str = "text", ) -> str: """Get a detailed listing of files and directories in a path. Args: path: Path to the directory include_hidden: Whether to include hidden files (starting with .) pattern: Optional glob pattern to filter entries format: Output format ('text' or 'json') ctx: MCP context Returns: Formatted directory listing """ try: components = get_components() if format.lower() == "json": entries = await components["operations"].list_directory( path, include_hidden, pattern ) return json.dumps(entries, indent=2) else: return await components["operations"].list_directory_formatted( path, include_hidden, pattern ) except Exception as e: return f"Error listing directory: {str(e)}"
  • Core helper method in FileOperations class that lists directory contents, applies filters for hidden files and patterns, validates paths, and returns list of file info dicts using FileInfo.
    async def list_directory( self, path: Union[str, Path], include_hidden: bool = False, pattern: Optional[str] = None, ) -> List[Dict]: """List directory contents. Args: path: Path to the directory include_hidden: Whether to include hidden files (starting with .) pattern: Optional glob pattern to filter files Returns: List of file/directory information dictionaries Raises: ValueError: If path is outside allowed directories or not a directory PermissionError: If directory cannot be read """ abs_path, allowed = await self.validator.validate_path(path) if not allowed: raise ValueError(f"Path outside allowed directories: {path}") if not abs_path.is_dir(): raise ValueError(f"Not a directory: {path}") results = [] try: entries = await anyio.to_thread.run_sync(list, abs_path.iterdir()) for entry in entries: # Skip hidden files if not requested if not include_hidden and entry.name.startswith("."): continue # Apply pattern filter if specified if pattern and not entry.match(pattern): continue try: info = FileInfo(entry) results.append(info.to_dict()) except (PermissionError, FileNotFoundError): # Skip files we can't access pass return results except PermissionError as e: raise ValueError(f"Cannot read directory: {e}")
  • Helper method that formats the output of list_directory into a human-readable string, sorting directories first.
    async def list_directory_formatted( self, path: Union[str, Path], include_hidden: bool = False, pattern: Optional[str] = None, ) -> str: """List directory contents in a formatted string. Args: path: Path to the directory include_hidden: Whether to include hidden files pattern: Optional glob pattern to filter files Returns: Formatted string with directory contents """ entries = await self.list_directory(path, include_hidden, pattern) if not entries: return "Directory is empty" # Format the output result = [] for entry in sorted(entries, key=lambda x: (not x["is_directory"], x["name"])): prefix = "[DIR] " if entry["is_directory"] else "[FILE]" size = "" if entry["is_directory"] else f" ({entry['size']:,} bytes)" modified = datetime.fromisoformat(entry["modified"]).strftime( "%Y-%m-%d %H:%M:%S" ) result.append(f"{prefix} {entry['name']}{size} - {modified}") return "\n".join(result)
  • FileInfo class used by list_directory to create standardized dictionary representations of file/directory metadata, including permissions, timestamps, and sizes.
    class FileInfo: """Information about a file or directory.""" def __init__(self, path: Path): """Initialize with a file path. Args: path: Path to the file or directory Raises: FileNotFoundError: If the file or directory does not exist """ self.path = path self.stat = path.stat() self.is_dir = path.is_dir() self.is_file = path.is_file() self.is_symlink = path.is_symlink() self.size = self.stat.st_size self.created = datetime.fromtimestamp(self.stat.st_ctime) self.modified = datetime.fromtimestamp(self.stat.st_mtime) self.accessed = datetime.fromtimestamp(self.stat.st_atime) self.name = path.name # Format permissions similar to Unix 'ls -l' mode = self.stat.st_mode self.permissions = "".join( [ "r" if mode & stat.S_IRUSR else "-", "w" if mode & stat.S_IWUSR else "-", "x" if mode & stat.S_IXUSR else "-", "r" if mode & stat.S_IRGRP else "-", "w" if mode & stat.S_IWGRP else "-", "x" if mode & stat.S_IXGRP else "-", "r" if mode & stat.S_IROTH else "-", "w" if mode & stat.S_IWOTH else "-", "x" if mode & stat.S_IXOTH else "-", ] ) # Numeric permissions in octal self.permissions_octal = oct(mode & 0o777)[2:] def to_dict(self) -> Dict: """Convert to dictionary. Returns: Dictionary with file information """ return { "name": self.name, "path": str(self.path), "size": self.size, "created": self.created.isoformat(), "modified": self.modified.isoformat(), "accessed": self.accessed.isoformat(), "is_directory": self.is_dir, "is_file": self.is_file, "is_symlink": self.is_symlink, "permissions": self.permissions, "permissions_octal": self.permissions_octal, } def __str__(self) -> str: """Get string representation. Returns: Formatted string with file information """ file_type = "Directory" if self.is_dir else "File" symlink_info = " (symlink)" if self.is_symlink else "" size_str = f"{self.size:,} bytes" return ( f"{file_type}{symlink_info}: {self.path}\n" f"Size: {size_str}\n" f"Created: {self.created.isoformat()}\n" f"Modified: {self.modified.isoformat()}\n" f"Accessed: {self.accessed.isoformat()}\n" f"Permissions: {self.permissions} ({self.permissions_octal})" )

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