Skip to main content
Glama
wonderwhy-er

Claude Desktop Commander MCP

list_directory

List and organize files and directories in a specified path with clear [FILE] and [DIR] prefixes. Use absolute paths for reliable results, as relative paths may fail. Works within allowed directories for structured file navigation.

Instructions

                    Get a detailed listing of all files and directories in a specified path.
                    
                    Use this instead of 'execute_command' with ls/dir commands.
                    Results distinguish between files and directories with [FILE] and [DIR] prefixes.
                    Only works within allowed directories.
                    
                    IMPORTANT: Always use absolute paths for reliability. Paths are automatically normalized regardless of slash direction. Relative paths may fail as they depend on the current working directory. Tilde paths (~/...) might not work in all contexts. Unless the user explicitly asks for relative paths, use absolute paths.
                    This command can be referenced as "DC: ..." or "use Desktop Commander to ..." in your instructions.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
pathYes

Implementation Reference

  • The main handler function for the 'list_directory' tool. Parses input arguments using ListDirectoryArgsSchema, calls the listDirectory helper function, formats the results as text, and returns a ServerResult.
    /**
     * Handle list_directory command
     */
    export async function handleListDirectory(args: unknown): Promise<ServerResult> {
        try {
            const startTime = Date.now();
            const parsed = ListDirectoryArgsSchema.parse(args);
            const entries = await listDirectory(parsed.path, parsed.depth);
            const duration = Date.now() - startTime;
    
            const resultText = entries.join('\n');
    
            return {
                content: [{ type: "text", text: resultText }],
            };
        } catch (error) {
            const errorMessage = error instanceof Error ? error.message : String(error);
            return createErrorResponse(errorMessage);
        }
    }
  • Zod schema defining the input parameters for the list_directory tool: 'path' (required string) and 'depth' (optional number, defaults to 2). Used for validation in the handler.
    export const ListDirectoryArgsSchema = z.object({
      path: z.string(),
      depth: z.number().optional().default(2),
    });
  • src/server.ts:421-454 (registration)
    Tool registration in the MCP listTools handler. Defines the tool name, description, input schema reference (ListDirectoryArgsSchema), and annotations for the protocol.
    {
        name: "list_directory",
        description: `
                Get a detailed listing of all files and directories in a specified path.
                
                Use this instead of 'execute_command' with ls/dir commands.
                Results distinguish between files and directories with [FILE] and [DIR] prefixes.
                
                Supports recursive listing with the 'depth' parameter (default: 2):
                - depth=1: Only direct contents of the directory
                - depth=2: Contents plus one level of subdirectories
                - depth=3+: Multiple levels deep
                
                CONTEXT OVERFLOW PROTECTION:
                - Top-level directory shows ALL items
                - Nested directories are limited to 100 items maximum per directory
                - When a nested directory has more than 100 items, you'll see a warning like:
                  [WARNING] node_modules: 500 items hidden (showing first 100 of 600 total)
                - This prevents overwhelming the context with large directories like node_modules
                
                Results show full relative paths from the root directory being listed.
                Example output with depth=2:
                [DIR] src
                [FILE] src/index.ts
                [DIR] src/tools
                [FILE] src/tools/filesystem.ts
                
                If a directory cannot be accessed, it will show [DENIED] instead.
                Only works within allowed directories.
                
                ${PATH_GUIDANCE}
                ${CMD_PREFIX_DESCRIPTION}`,
        inputSchema: zodToJsonSchema(ListDirectoryArgsSchema),
        annotations: {
  • Core helper function that performs the recursive directory listing. Validates path, reads directories recursively up to the specified depth, formats entries with [DIR]/[FILE] prefixes, handles access denials and item limits for performance.
    export async function listDirectory(dirPath: string, depth: number = 2): Promise<string[]> {
        const validPath = await validatePath(dirPath);
        const results: string[] = [];
    
        const MAX_NESTED_ITEMS = 100; // Maximum items to show per nested directory
    
        async function listRecursive(currentPath: string, currentDepth: number, relativePath: string = '', isTopLevel: boolean = true): Promise<void> {
            if (currentDepth <= 0) return;
    
            let entries;
            try {
                entries = await fs.readdir(currentPath, { withFileTypes: true });
            } catch (error) {
                // If we can't read this directory (permission denied), show as denied
                const displayPath = relativePath || path.basename(currentPath);
                results.push(`[DENIED] ${displayPath}`);
                return;
            }
    
            // Apply filtering for nested directories (not top level)
            const totalEntries = entries.length;
            let entriesToShow = entries;
            let filteredCount = 0;
    
            if (!isTopLevel && totalEntries > MAX_NESTED_ITEMS) {
                entriesToShow = entries.slice(0, MAX_NESTED_ITEMS);
                filteredCount = totalEntries - MAX_NESTED_ITEMS;
            }
    
            for (const entry of entriesToShow) {
                const fullPath = path.join(currentPath, entry.name);
                const displayPath = relativePath ? path.join(relativePath, entry.name) : entry.name;
    
                // Add this entry to results
                results.push(`${entry.isDirectory() ? "[DIR]" : "[FILE]"} ${displayPath}`);
    
                // If it's a directory and we have depth remaining, recurse
                if (entry.isDirectory() && currentDepth > 1) {
                    try {
                        // Validate the path before recursing
                        await validatePath(fullPath);
                        await listRecursive(fullPath, currentDepth - 1, displayPath, false);
                    } catch (error) {
                        // If validation fails or we can't access it, it will be marked as denied
                        // when we try to read it in the recursive call
                        continue;
                    }
                }
            }
    
            // Add warning message if items were filtered
            if (filteredCount > 0) {
                const displayPath = relativePath || path.basename(currentPath);
                results.push(`[WARNING] ${displayPath}: ${filteredCount} items hidden (showing first ${MAX_NESTED_ITEMS} of ${totalEntries} total)`);
            }
        }
    
        await listRecursive(validPath, depth, '', true);
        return results;
    }

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/wonderwhy-er/DesktopCommanderMCP'

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