Skip to main content
Glama
247arjun

Grep MCP Server

by 247arjun

grep_files_with_matches

Search files in a directory for specific text patterns using regex or plain text, then list only the filenames containing matches. Filter by file extensions, case sensitivity, whole words, or exclude patterns.

Instructions

List only the names of files that contain the pattern

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
patternYesRegular expression pattern or plain text to search for
targetYesDirectory path to search in
case_sensitiveNoWhether the search should be case sensitive
whole_wordsNoMatch whole words only
file_extensionsNoOnly search files with these extensions
exclude_patternsNoExclude files matching these patterns

Implementation Reference

  • Handler function that validates input, builds grep command with -l -r -E options for listing files recursively containing the regex pattern, executes it via executeGrep, and returns results.
    async ({ pattern, target, case_sensitive, whole_words, file_extensions, exclude_patterns }) => { // Validate target path const pathValidation = validatePath(target); if (!pathValidation.isValid) { return { content: [ { type: "text", text: `Error: ${pathValidation.error}`, }, ], }; } if (!pathValidation.isDirectory) { return { content: [ { type: "text", text: `Error: Target must be a directory for this operation`, }, ], }; } const args = ['grep']; // List filenames only args.push('-l'); // Use extended regex args.push('-E'); args.push(pattern); // Add case sensitivity option if (!case_sensitive) { args.push('-i'); } // Add whole words option if (whole_words) { args.push('-w'); } // Add recursive search args.push('-r'); // Add file extension filters if (file_extensions && file_extensions.length > 0) { file_extensions.forEach(ext => { args.push('--include', `*.${ext}`); }); } // Add exclusion patterns if (exclude_patterns && exclude_patterns.length > 0) { exclude_patterns.forEach(excludePattern => { args.push('--exclude', excludePattern); }); } // Add target path args.push(target); try { const result = await executeGrep(args); return { content: [ { type: "text", text: `Pattern: ${pattern}\nExit Code: ${result.exitCode}\n\nFiles containing matches:\n${result.stdout}${result.stderr ? `\n\nErrors:\n${result.stderr}` : ''}`, }, ], }; } catch (error) { return { content: [ { type: "text", text: `Error executing grep: ${error instanceof Error ? error.message : String(error)}`, }, ], }; } }
  • Zod input schema defining parameters for the grep_files_with_matches tool.
    { pattern: z.string().describe("Regular expression pattern or plain text to search for"), target: z.string().describe("Directory path to search in"), case_sensitive: z.boolean().optional().default(false).describe("Whether the search should be case sensitive"), whole_words: z.boolean().optional().default(false).describe("Match whole words only"), file_extensions: z.array(z.string()).optional().describe("Only search files with these extensions"), exclude_patterns: z.array(z.string()).optional().describe("Exclude files matching these patterns"), },
  • src/index.ts:428-525 (registration)
    Registers the grep_files_with_matches tool on the MCP server with name, description, schema, and handler.
    server.tool( "grep_files_with_matches", "List only the names of files that contain the pattern", { pattern: z.string().describe("Regular expression pattern or plain text to search for"), target: z.string().describe("Directory path to search in"), case_sensitive: z.boolean().optional().default(false).describe("Whether the search should be case sensitive"), whole_words: z.boolean().optional().default(false).describe("Match whole words only"), file_extensions: z.array(z.string()).optional().describe("Only search files with these extensions"), exclude_patterns: z.array(z.string()).optional().describe("Exclude files matching these patterns"), }, async ({ pattern, target, case_sensitive, whole_words, file_extensions, exclude_patterns }) => { // Validate target path const pathValidation = validatePath(target); if (!pathValidation.isValid) { return { content: [ { type: "text", text: `Error: ${pathValidation.error}`, }, ], }; } if (!pathValidation.isDirectory) { return { content: [ { type: "text", text: `Error: Target must be a directory for this operation`, }, ], }; } const args = ['grep']; // List filenames only args.push('-l'); // Use extended regex args.push('-E'); args.push(pattern); // Add case sensitivity option if (!case_sensitive) { args.push('-i'); } // Add whole words option if (whole_words) { args.push('-w'); } // Add recursive search args.push('-r'); // Add file extension filters if (file_extensions && file_extensions.length > 0) { file_extensions.forEach(ext => { args.push('--include', `*.${ext}`); }); } // Add exclusion patterns if (exclude_patterns && exclude_patterns.length > 0) { exclude_patterns.forEach(excludePattern => { args.push('--exclude', excludePattern); }); } // Add target path args.push(target); try { const result = await executeGrep(args); return { content: [ { type: "text", text: `Pattern: ${pattern}\nExit Code: ${result.exitCode}\n\nFiles containing matches:\n${result.stdout}${result.stderr ? `\n\nErrors:\n${result.stderr}` : ''}`, }, ], }; } catch (error) { return { content: [ { type: "text", text: `Error executing grep: ${error instanceof Error ? error.message : String(error)}`, }, ], }; } } );
  • Helper function to safely spawn and execute the grep process, capturing stdout, stderr, and exit code.
    async function executeGrep(args: string[]): Promise<{ stdout: string; stderr: string; exitCode: number }> { return new Promise((resolve) => { // Ensure we're only calling grep with safe arguments if (!args.includes('grep')) { args.unshift('grep'); } const child = spawn('grep', args.slice(1), { stdio: ['pipe', 'pipe', 'pipe'], shell: false, }); let stdout = ''; let stderr = ''; child.stdout.on('data', (data) => { stdout += data.toString(); }); child.stderr.on('data', (data) => { stderr += data.toString(); }); child.on('close', (code) => { resolve({ stdout, stderr, exitCode: code || 0, }); }); child.on('error', (error) => { resolve({ stdout: '', stderr: error.message, exitCode: 1, }); }); }); }
  • Helper function to validate if a path exists and whether it is a directory using fs functions.
    function validatePath(path: string): { isValid: boolean; isDirectory: boolean; error?: string } { try { const resolvedPath = resolve(path); if (!existsSync(resolvedPath)) { return { isValid: false, isDirectory: false, error: `Path does not exist: ${path}` }; } const stats = statSync(resolvedPath); return { isValid: true, isDirectory: stats.isDirectory() }; } catch (error) { return { isValid: false, isDirectory: false, error: `Invalid path: ${path}` }; } }

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/247arjun/mcp-grep'

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