Skip to main content
Glama
rawr-ai

Filesystem MCP Server

search_files

Recursively locate files and directories using a case-insensitive pattern match from a specified path. Control search depth and result limits to efficiently find matching items, even when exact locations are unknown. Ideal for quick file discovery within permitted directories.

Instructions

Recursively search for files and directories matching a pattern. Searches through all subdirectories from the starting path. The search is case-insensitive and matches partial names. Returns full paths to all matching items. Requires maxDepth (default 2) and maxResults (default 10) parameters. Great for finding files when you don't know their exact location. Only searches within allowed directories.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
excludePatternsNo
maxDepthYesMaximum directory depth to search. Must be a positive integer. Handler default: 2.
maxResultsYesMaximum number of results to return. Must be a positive integer. Handler default: 10.
pathYes
patternYes

Implementation Reference

  • The main handler function for the 'search_files' tool. It parses arguments using the schema, validates the path, calls the searchFiles helper, and formats the response.
    export async function handleSearchFiles(
      args: unknown,
      allowedDirectories: string[],
      symlinksMap: Map<string, string>,
      noFollowSymlinks: boolean
    ) {
      const parsed = parseArgs(SearchFilesArgsSchema, args, 'search_files');
      const { path: startPath, pattern, excludePatterns, maxDepth, maxResults } = parsed;
      const validPath = await validatePath(startPath, allowedDirectories, symlinksMap, noFollowSymlinks);
      const results = await searchFiles(validPath, pattern, excludePatterns, maxDepth, maxResults);
      return {
        content: [{ type: "text", text: results.length > 0 ? results.join("\n") : "No matches found" }],
      };
    }
  • TypeBox schema definition for SearchFilesArgs, defining input parameters: path, pattern, excludePatterns, maxDepth, maxResults.
    export const SearchFilesArgsSchema = Type.Object({
      path: Type.String(),
      pattern: Type.String(),
      excludePatterns: Type.Optional(
        Type.Array(Type.String(), { default: [] })
      ),
      maxDepth: Type.Integer({
        minimum: 1,
        description: 'Maximum directory depth to search. Must be a positive integer. Handler default: 2.'
      }),
      maxResults: Type.Integer({
        minimum: 1,
        description: 'Maximum number of results to return. Must be a positive integer. Handler default: 10.'
      })
    });
    export type SearchFilesArgs = Static<typeof SearchFilesArgsSchema>;
  • Core helper function that performs the recursive file search based on pattern, respecting depth, results limit, and exclusions using minimatch.
    export async function searchFiles(
      rootPath: string,
      pattern: string,
      excludePatterns: string[] = [],
      maxDepth: number = 2, // Default depth
      maxResults: number = 10 // Default results
    ): Promise<ReadonlyArray<string>> {
      const results: string[] = [];
    
      async function search(currentPath: string, currentDepth: number) {
        // Stop if max depth is reached
        if (currentDepth >= maxDepth) {
          return;
        }
        
        // Stop if max results are reached
        if (results.length >= maxResults) {
          return;
        }
        const entries = await fsPromises.readdir(currentPath, { withFileTypes: true });
    
        for (const entry of entries) {
          const fullPath = path.join(currentPath, entry.name);
    
          // 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;
          }
    
          if (entry.name.toLowerCase().includes(pattern.toLowerCase())) {
            if (results.length < maxResults) {
              results.push(fullPath);
            }
            // Check again if max results reached after adding
            if (results.length >= maxResults) {
              return; // Stop searching this branch
            }
          }
    
          if (entry.isDirectory()) {
            // Check results length before recursing
            if (results.length < maxResults) {
              await search(fullPath, currentDepth + 1);
            }
          }
        }
      }
    
      await search(rootPath, 0); // Start search at depth 0
      return results;
    }
  • index.ts:236-237 (registration)
    Registration of the 'search_files' tool handler in the toolHandlers object, which is used to add the tool to the MCP server.
    search_files: (a: unknown) =>
      handleSearchFiles(a, allowedDirectories, symlinksMap, noFollowSymlinks),
  • index.ts:309-309 (registration)
    Tool metadata registration in the allTools array, including name and description, used conditionally in server.addTool calls.
    { name: "search_files", description: "Search files by name" },
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 and does well by disclosing key behavioral traits: it's recursive, case-insensitive, matches partial names, returns full paths, has defaults for maxDepth and maxResults, and is restricted to allowed directories. It doesn't mention error handling, performance characteristics, or authentication needs, keeping it from a perfect score.

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

Conciseness5/5

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

The description is front-loaded with the core purpose, followed by key behavioral details and usage context in just four sentences. Every sentence adds value without redundancy, making it efficient and well-structured for quick understanding.

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?

For a tool with 5 parameters, no annotations, and no output schema, the description does a good job covering the essential behavior and usage. It explains the search mechanics, constraints, and key parameters, though it could benefit from more detail on parameter interactions or example patterns to be fully complete.

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

Parameters3/5

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

Schema description coverage is low at 40%, but the description adds value by explaining maxDepth and maxResults parameters (including defaults), which aren't described in the schema. However, it doesn't cover other parameters like excludePatterns or path/pattern details, leaving gaps that the schema doesn't fill either.

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 ('recursively search for files and directories matching a pattern') and resources ('files and directories'), distinguishing it from siblings like list_directory (which lists without searching) or regex_search_content (which searches within file content rather than by name).

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

Usage Guidelines4/5

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

The description provides clear context for when to use this tool ('Great for finding files when you don't know their exact location') and mentions constraints ('Only searches within allowed directories'), but doesn't explicitly compare it to alternatives like find_files_by_extension or directory_tree, which might offer different search capabilities.

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/rawr-ai/mcp-filesystem'

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