Skip to main content
Glama
mcollina

MCP Ripgrep Server

search

Search files for patterns using ripgrep to find text across your system. Specify search patterns and paths to locate matching content in files.

Instructions

Search files for patterns using ripgrep (rg)

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
patternYesThe search pattern (regex by default)
pathYesDirectory or file(s) to search.
caseSensitiveNoUse case sensitive search (default: auto)
filePatternNoFilter by file type or glob
maxResultsNoLimit the number of matching lines
contextNoShow N lines before and after each match
useColorsNoUse colors in output (default: false)

Implementation Reference

  • Handler for the 'search' tool: parses arguments, builds ripgrep command with options like case sensitivity, file pattern, max results, context, colors, executes it via exec(), processes output.
    case "search": {
      const pattern = String(args.pattern || "");
      const path = String(args.path);
      const caseSensitive = typeof args.caseSensitive === 'boolean' ? args.caseSensitive : undefined;
      const filePattern = args.filePattern ? String(args.filePattern) : undefined;
      const maxResults = typeof args.maxResults === 'number' ? args.maxResults : undefined;
      const context = typeof args.context === 'number' ? args.context : undefined;
      const useColors = typeof args.useColors === 'boolean' ? args.useColors : false;
      
      if (!pattern) {
        return {
          isError: true,
          content: [{ type: "text", text: "Error: Pattern is required" }]
        };
      }
      
      // Build the rg command with flags
      let command = "rg";
      
      // Add case sensitivity flag if specified
      if (caseSensitive === true) {
        command += " -s"; // Case sensitive
      } else if (caseSensitive === false) {
        command += " -i"; // Case insensitive
      }
      
      // Add file pattern if specified
      if (filePattern) {
        command += ` -g ${escapeShellArg(filePattern)}`;
      }
      
      // Add max results if specified
      if (maxResults !== undefined && maxResults > 0) {
        command += ` -m ${maxResults}`;
      }
      
      // Add context lines if specified
      if (context !== undefined && context > 0) {
        command += ` -C ${context}`;
      }
      
      // Add line numbers
      command += " -n";
      
      // Add color setting
      command += useColors ? " --color always" : " --color never";
      
      // Add pattern and path
      command += ` ${escapeShellArg(pattern)} ${escapeShellArg(path)}`;
      
      console.error(`Executing: ${command}`);
      const { stdout, stderr } = await exec(command);
      
      // If there's anything in stderr, log it for debugging
      if (stderr) {
        console.error(`ripgrep stderr: ${stderr}`);
      }
      
      return {
        content: [
          {
            type: "text",
            text: processOutput(stdout, useColors) || "No matches found"
          }
        ]
      };
    }
  • src/index.ts:98-113 (registration)
    Registration of the 'search' tool in the tools list, including name, description, and full input schema.
      name: "search",
      description: "Search files for patterns using ripgrep (rg)",
      inputSchema: {
        type: "object",
        properties: {
          pattern: { type: "string", description: "The search pattern (regex by default)" },
          path: { type: "string", description: "Directory or file(s) to search." },
          caseSensitive: { type: "boolean", description: "Use case sensitive search (default: auto)" },
          filePattern: { type: "string", description: "Filter by file type or glob" },
          maxResults: { type: "number", description: "Limit the number of matching lines" },
          context: { type: "number", description: "Show N lines before and after each match" },
          useColors: { type: "boolean", description: "Use colors in output (default: false)" }
        },
        required: ["pattern", "path"]
      }
    },
  • Input schema for the 'search' tool defining parameters and requirements.
    inputSchema: {
      type: "object",
      properties: {
        pattern: { type: "string", description: "The search pattern (regex by default)" },
        path: { type: "string", description: "Directory or file(s) to search." },
        caseSensitive: { type: "boolean", description: "Use case sensitive search (default: auto)" },
        filePattern: { type: "string", description: "Filter by file type or glob" },
        maxResults: { type: "number", description: "Limit the number of matching lines" },
        context: { type: "number", description: "Show N lines before and after each match" },
        useColors: { type: "boolean", description: "Use colors in output (default: false)" }
      },
      required: ["pattern", "path"]
  • Helper function to execute shell commands safely using spawn, capturing stdout/stderr, handling ripgrep exit codes.
    function exec(command: string): Promise<{ stdout: string; stderr: string }> {
      return new Promise((resolve, reject) => {
        const parts = command.split(" ");
        const program = parts[0];
        const args = parts.slice(1).filter(arg => arg.length > 0);
        
        // Use spawn with explicit stdio control
        const child = spawn(program, args, {
          shell: true, // Use shell to handle quotes and escaping
        });
        
        let stdout = "";
        let stderr = "";
        
        child.stdout.setEncoding("utf8");
        child.stderr.setEncoding("utf8");
        
        child.stdout.on("data", (data) => {
          stdout += data;
        });
        
        child.stderr.on("data", (data) => {
          stderr += data;
        });
        
        child.on("close", (code) => {
          if (code === 0 || code === 1) { // Code 1 is "no matches" for ripgrep
            resolve({ stdout, stderr });
          } else {
            const error = new Error(`Command failed with exit code ${code}`);
            Object.assign(error, { code, stdout, stderr });
            reject(error);
          }
        });
        
        // Handle process errors
        child.on("error", (error) => {
          reject(error);
        });
      });
    }
  • Helper to escape shell arguments to prevent injection.
    function escapeShellArg(arg: string): string {
      // Replace all single quotes with the sequence: '"'"'
      // This ensures the argument is properly quoted in shell commands
      return `'${arg.replace(/'/g, "'\"'\"'")}'`;
    }
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries full burden for behavioral disclosure but only states what the tool does at a high level. It doesn't describe output format, performance characteristics, error conditions, or any behavioral traits like whether it's read-only, has rate limits, or requires specific permissions. The mention of 'ripgrep (rg)' hints at implementation but doesn't translate to actionable behavioral information.

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 extremely concise at just one sentence with zero wasted words. It's front-loaded with the core functionality and efficiently communicates the essential purpose without unnecessary elaboration.

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

Completeness2/5

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

For a 7-parameter search tool with no annotations and no output schema, the description is insufficiently complete. It doesn't explain what the output looks like (lines of text? structured results?), how results are formatted, or any behavioral constraints. The high parameter count and lack of structured output information create significant gaps in understanding how to effectively use this tool.

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?

With 100% schema description coverage, all 7 parameters are well-documented in the input schema. The description adds no additional parameter semantics beyond what's already in the structured schema fields, so it meets the baseline expectation but provides no extra value.

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

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('search files for patterns') and the tool used ('using ripgrep (rg)'), providing a specific verb+resource combination. However, it doesn't explicitly differentiate this basic search from sibling tools like 'advanced-search' or 'count-matches', which would require more specific scope definition.

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

Usage Guidelines2/5

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

The description provides no guidance on when to use this tool versus alternatives like 'advanced-search' or 'count-matches'. There's no mention of use cases, prerequisites, or limitations that would help an agent choose between these similar search-related tools.

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

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/mcollina/mcp-ripgrep'

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