Skip to main content
Glama

search_files

Find notes by searching for files and directories matching a pattern in your notes directory. Returns full paths to matching items for easy access.

Instructions

Recursively search for files and directories matching a pattern in your notes directory. The search is case-insensitive and matches partial names. Returns full paths to all matching items. Great for finding notes when you don't know their exact location.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
patternYesThe pattern to search for in file and directory names
excludePatternsNoGlob patterns to exclude from search results

Implementation Reference

  • Primary handler for the 'search_files' tool: validates arguments, calls searchFiles utility, formats and returns matching file paths relative to notes directory or error.
    export async function handleSearchFiles(notesPath: string, args: SearchFilesArgs): Promise<ToolCallResult> { try { // Validate pattern is provided if (!args.pattern) { throw new Error("'pattern' parameter is required"); } // Always search in the notes directory const results = await searchFiles( notesPath, args.pattern, args.excludePatterns || [] ); if (results.length === 0) { return { content: [{ type: "text", text: "No files found matching the pattern." }] }; } // Format results as relative paths const formattedResults = results.map((filePath: string) => path.relative(notesPath, filePath) ); return { content: [{ type: "text", text: `Found ${results.length} files matching "${args.pattern}":\n\n${formattedResults.join('\n')}` }] }; } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); return { content: [{ type: "text", text: `Error searching files: ${errorMessage}` }], isError: true }; } }
  • Tool definition including input schema (JSON Schema) for 'search_files' returned by getFilesystemToolDefinitions().
    { name: "search_files", description: "Recursively search for files and directories matching a pattern in your notes directory. " + "The search is case-insensitive and matches partial names. Returns full paths to all " + "matching items. Great for finding notes when you don't know their exact location.", inputSchema: { type: "object", properties: { pattern: { type: "string", description: "The pattern to search for in file and directory names" }, excludePatterns: { type: "array", items: { type: "string" }, description: "Glob patterns to exclude from search results", default: [] } }, required: ["pattern"] }, },
  • Registration in main tool dispatcher (handleToolCall switch): routes 'search_files' calls to handleSearchFiles handler.
    case "search_files": return await handleSearchFiles(notesPath, args);
  • Core utility function implementing recursive case-insensitive file search with glob exclusion support, used by the handler.
    export async function searchFiles(rootPath: string, pattern: string, excludePatterns: string[] = []): Promise<string[]> { const results: string[] = []; // Normalize the search pattern for better matching const normalizedPattern = pattern.toLowerCase(); // Make sure the root path exists try { const rootStats = await fs.stat(rootPath); if (!rootStats.isDirectory()) { console.error(`Search root is not a directory: ${rootPath}`); return []; } } catch (error) { console.error(`Error accessing search root path ${rootPath}:`, error); return []; } async function search(currentPath: string): Promise<void> { try { // Read directory entries const entries = await fs.readdir(currentPath, { withFileTypes: true }); for (const entry of entries) { const fullPath = path.join(currentPath, entry.name); try { // Check if path matches any exclude pattern const relativePath = path.relative(rootPath, fullPath); const shouldExclude = excludePatterns.some(pattern => { const globPattern = pattern.includes('*') ? pattern : `**/${pattern}/**`; return minimatch(relativePath, globPattern, { dot: true }); }); if (shouldExclude) { continue; } // Match the name (case-insensitive) if (entry.name.toLowerCase().includes(normalizedPattern)) { results.push(fullPath); } // Recursively search subdirectories if (entry.isDirectory()) { await search(fullPath); } } catch (error) { // Skip problematic entries console.error(`Error processing ${fullPath}:`, error); continue; } } } catch (error) { console.error(`Error reading directory ${currentPath}:`, error); } } // Start the search await search(rootPath); // Log the number of results found console.error(`Search found ${results.length} results for pattern "${pattern}" in ${rootPath}`); 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/mikeysrecipes/mcp-notes'

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