Skip to main content
Glama
wonderwhy-er

Claude Desktop Commander MCP

search_files

Locate files by name using case-insensitive substring matching across subdirectories. Specify absolute paths for reliable results, with a customizable 30-second timeout. Designed for secure and efficient file searching.

Instructions

                    Finds files by name using a case-insensitive substring matching.
                    
                    Use this instead of 'execute_command' with find/dir/ls for locating files.
                    Searches through all subdirectories from the starting path.
                    
                    Has a default timeout of 30 seconds which can be customized using the timeoutMs parameter.
                    Only searches 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
patternYes
timeoutMsNo

Implementation Reference

  • Main implementation of searchFiles function, which performs file search using ripgrep via searchManager with polling for synchronous results, falls back to pure Node.js recursive search.
    export async function searchFiles(rootPath: string, pattern: string): Promise<string[]> {
        // Use the new search manager for better performance
        // This provides a temporary compatibility layer until we fully migrate to search sessions
        const { searchManager } = await import('../search-manager.js');
    
        try {
            const result = await searchManager.startSearch({
                rootPath,
                pattern,
                searchType: 'files',
                ignoreCase: true,
                maxResults: 5000, // Higher limit for compatibility
                earlyTermination: true, // Use early termination for better performance
            });
    
            const sessionId = result.sessionId;
    
            // Poll for results until complete
            let allResults: string[] = [];
            let isComplete = result.isComplete;
            let startTime = Date.now();
    
            // Add initial results
            for (const searchResult of result.results) {
                if (searchResult.type === 'file') {
                    allResults.push(searchResult.file);
                }
            }
    
            while (!isComplete) {
                await new Promise(resolve => setTimeout(resolve, 100)); // Wait 100ms
    
                const results = searchManager.readSearchResults(sessionId);
                isComplete = results.isComplete;
    
                // Add new file paths to results
                for (const searchResult of results.results) {
                    if (searchResult.file !== '__LAST_READ_MARKER__' && searchResult.type === 'file') {
                        allResults.push(searchResult.file);
                    }
                }
    
                // Safety check to prevent infinite loops (30 second timeout)
                if (Date.now() - startTime > 30000) {
                    searchManager.terminateSearch(sessionId);
                    break;
                }
            }
    
            // Log only the count of found files, not their paths
            capture('server_search_files_complete', {
                resultsCount: allResults.length,
                patternLength: pattern.length,
                usedRipgrep: true
            });
    
            return allResults;
        } catch (error) {
            // Fallback to original Node.js implementation if ripgrep fails
            capture('server_search_files_ripgrep_fallback', {
                error: error instanceof Error ? error.message : 'Unknown error'
            });
    
            return await searchFilesNodeJS(rootPath, pattern);
        }
    }
  • Fallback Node.js implementation for searchFiles when ripgrep/searchManager fails. Recursively searches directories for files matching pattern in name.
    async function searchFilesNodeJS(rootPath: string, pattern: string): Promise<string[]> {
        const results: string[] = [];
    
        async function search(currentPath: string): Promise<void> {
            let entries;
            try {
                entries = await fs.readdir(currentPath, { withFileTypes: true });
            } catch (error) {
                return; // Skip this directory on error
            }
    
            for (const entry of entries) {
                const fullPath = path.join(currentPath, entry.name);
    
                try {
                    await validatePath(fullPath);
    
                    if (entry.name.toLowerCase().includes(pattern.toLowerCase())) {
                        results.push(fullPath);
                    }
    
                    if (entry.isDirectory()) {
                        await search(fullPath);
                    }
                } catch (error) {
                    continue;
                }
            }
        }
    
        try {
            // Validate root path before starting search
            const validPath = await validatePath(rootPath);
            await search(validPath);
    
            // Log only the count of found files, not their paths
            capture('server_search_files_complete', {
                resultsCount: results.length,
                patternLength: pattern.length,
                usedRipgrep: false
            });
    
            return results;
        } catch (error) {
            // For telemetry only - sanitize error info
            capture('server_search_files_error', {
                errorType: error instanceof Error ? error.name : 'Unknown',
                error: 'Error with root path',
                isRootPathError: true
            });
    
            // Re-throw the original error for the caller
            throw error;
        }
    }
Behavior4/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. It effectively describes key behaviors: case-insensitive substring matching, recursive search through subdirectories, a default 30-second timeout (customizable via timeoutMs), restriction to allowed directories, and path normalization. It also notes reliability issues with relative and tilde paths. However, it lacks details on output format or error handling, which could be useful for an agent.

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

Conciseness3/5

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

The description is appropriately sized but not optimally structured. Key information is front-loaded (purpose and basic usage), but it includes verbose path advice and a tangential note about command referencing ('DC: ...') that doesn't add core value. Some sentences could be trimmed for better focus without losing essential details.

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

Completeness4/5

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

Given the tool's moderate complexity (3 parameters, no annotations, no output schema), the description is largely complete. It covers purpose, usage, behavioral traits, and parameter semantics well. However, it lacks information on the return value (e.g., what the search results look like) and error conditions, which are important for an agent to handle responses appropriately.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It adds meaningful semantics for all parameters: 'path' is explained with detailed guidance on absolute vs. relative paths and normalization; 'pattern' is implied as the substring for matching; 'timeoutMs' is described as customizing the default 30-second timeout. This goes beyond the bare schema, though it could explicitly map each parameter name to its purpose.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/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 specific verbs ('finds files by name') and resource ('files'), and distinguishes it from sibling tools by explicitly contrasting it with 'execute_command' and 'search_code' (implied). It provides detailed matching behavior ('case-insensitive substring matching') and search scope ('through all subdirectories from the starting path').

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

Usage Guidelines5/5

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

The description explicitly states when to use this tool ('Use this instead of 'execute_command' with find/dir/ls for locating files') and provides clear context on path handling ('Always use absolute paths for reliability'). It also mentions constraints like 'Only searches within allowed directories' and timeout customization, offering practical guidance for effective use.

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

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

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