Skip to main content
Glama

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; } }

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