search_files
Find files by name pattern using wildcards in specified directories to locate documents, code, or data files efficiently.
Instructions
Search for files by name pattern in a directory
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| directory | Yes | The directory to search in | |
| pattern | Yes | The filename pattern to search for (supports * wildcards) |
Implementation Reference
- src/index.ts:44-47 (schema)Defines the Zod input validation schema for the search_files tool parameters.const SearchFilesArgsSchema = z.object({ directory: z.string().describe("The directory to search in"), pattern: z.string().describe("The filename pattern to search for (supports wildcards)") });
- src/index.ts:89-119 (handler)Core handler function that recursively searches for files matching the given pattern, with depth and result limits.async function searchFiles(directory: string, pattern: string, maxResults: number = 50): Promise<string[]> { const results: string[] = []; async function searchRecursive(currentDir: string, depth: number = 0) { // Limit recursion depth to prevent infinite loops if (depth > 10 || results.length >= maxResults) return; try { const entries = await fs.readdir(currentDir, { withFileTypes: true }); for (const entry of entries) { if (results.length >= maxResults) break; const fullPath = path.join(currentDir, entry.name); if (entry.isFile() && matchesPattern(entry.name, pattern)) { results.push(fullPath); } else if (entry.isDirectory()) { // Recursively search subdirectories await searchRecursive(fullPath, depth + 1); } } } catch (error) { // Skip directories we can't read console.error(`Unable to search directory ${currentDir}:`, error); } } await searchRecursive(directory); return results; }
- src/index.ts:75-84 (helper)Helper function for pattern matching using regex conversion from glob patterns, used in searchFiles.function matchesPattern(filename: string, pattern: string): boolean { // Convert glob pattern to regex, being more precise with extensions let regexPattern = pattern .replace(/\./g, '\\.') // Escape dots first .replace(/\*/g, '.*') // Convert * to .* .replace(/\?/g, '.'); // Convert ? to . const regex = new RegExp('^' + regexPattern + '$', 'i'); return regex.test(filename); }
- src/index.ts:186-202 (registration)Tool registration in ListToolsRequestSchema handler, defining name, description, and input schema.{ name: "search_files", description: "Search for files by name pattern in a directory", inputSchema: { type: "object", properties: { directory: { type: "string", description: "The directory to search in" }, pattern: { type: "string", description: "The filename pattern to search for (supports * wildcards)" } }, required: ["directory", "pattern"] }
- src/index.ts:330-361 (handler)Dispatch handler in CallToolRequestSchema that parses arguments, validates input, calls searchFiles, and formats the response.case "search_files": { const { directory, pattern } = SearchFilesArgsSchema.parse(args); const safePath = validatePath(directory); const stats = await fs.stat(safePath); if (!stats.isDirectory()) { throw new Error("Search path must be a directory"); } const results = await searchFiles(safePath, pattern); if (results.length === 0) { return { content: [ { type: "text", text: `No files matching pattern "${pattern}" found in ${safePath}` } ] }; } return { content: [ { type: "text", text: `Found ${results.length} files matching "${pattern}" in ${safePath}:\n\n` + results.map(file => `📄 ${file}`).join('\n') } ] }; }