Skip to main content
Glama

search_file

Find regex patterns in a file and display matching lines with specified context lines before and after each match for precise file analysis.

Instructions

Search for regex patterns in a file and show matching lines with context.

Input Schema

NameRequiredDescriptionDefault
file_pathYesAbsolute path to the file
lines_afterNoNumber of lines to show after each match
lines_beforeNoNumber of lines to show before each match
regexpYesRegular expression pattern to search for

Input Schema (JSON Schema)

{ "$schema": "http://json-schema.org/draft-07/schema#", "additionalProperties": false, "properties": { "file_path": { "description": "Absolute path to the file", "type": "string" }, "lines_after": { "description": "Number of lines to show after each match", "minimum": 0, "type": "integer" }, "lines_before": { "description": "Number of lines to show before each match", "minimum": 0, "type": "integer" }, "regexp": { "description": "Regular expression pattern to search for", "type": "string" } }, "required": [ "file_path", "regexp" ], "type": "object" }

Implementation Reference

  • The main handler function for the 'search_file' tool. It validates the file path, reads the file contents, splits into lines, searches each line using the provided regex, and for each match, includes context lines before and after with line numbers and a '>' marker on the matching line. Returns formatted matches or no-match message.
    execute: async ({ file_path, regexp, lines_before, lines_after }) => { const absolutePath = validateAbsolutePath(file_path, 'file_path'); validateFileExists(absolutePath); try { const content = fs.readFileSync(absolutePath, 'utf-8'); const lines = content.split('\n'); const regex = new RegExp(regexp); const matches: string[] = []; lines.forEach((line, index) => { if (regex.test(line)) { const lineNumber = index + 1; // 1-based const startLine = Math.max(1, lineNumber - (lines_before || 0)); const endLine = Math.min(lines.length, lineNumber + (lines_after || 0)); const contextLines = lines.slice(startLine - 1, endLine); const context = contextLines.map((ctxLine, ctxIndex) => { const ctxLineNumber = startLine + ctxIndex; const marker = ctxLineNumber === lineNumber ? '>' : ' '; return `${marker} ${ctxLineNumber} | ${ctxLine}`; }).join('\n'); matches.push(`Match at line ${lineNumber}:\n${context}`); } }); if (matches.length === 0) { return `No matches found for pattern "${regexp}" in file "${absolutePath}".`; } return matches.join('\n\n'); } catch (error: any) { if (error instanceof UserError) throw error; throw new UserError(`Error searching file "${absolutePath}": ${error.message}`); } }
  • Zod schema defining the input parameters for the 'search_file' tool: file_path (required string), regexp (required string), lines_before and lines_after (optional non-negative integers).
    parameters: z.object({ file_path: z.string().describe('Absolute path to the file'), regexp: z.string().describe('Regular expression pattern to search for'), lines_before: z.number().int().min(0).optional().describe('Number of lines to show before each match'), lines_after: z.number().int().min(0).optional().describe('Number of lines to show after each match') }),
  • src/index.ts:435-481 (registration)
    The registration of the 'search_file' tool via server.addTool(), including name, description, parameters schema, and inline handler.
    server.addTool({ name: 'search_file', description: 'Search for regex patterns in a file and show matching lines with context.', parameters: z.object({ file_path: z.string().describe('Absolute path to the file'), regexp: z.string().describe('Regular expression pattern to search for'), lines_before: z.number().int().min(0).optional().describe('Number of lines to show before each match'), lines_after: z.number().int().min(0).optional().describe('Number of lines to show after each match') }), execute: async ({ file_path, regexp, lines_before, lines_after }) => { const absolutePath = validateAbsolutePath(file_path, 'file_path'); validateFileExists(absolutePath); try { const content = fs.readFileSync(absolutePath, 'utf-8'); const lines = content.split('\n'); const regex = new RegExp(regexp); const matches: string[] = []; lines.forEach((line, index) => { if (regex.test(line)) { const lineNumber = index + 1; // 1-based const startLine = Math.max(1, lineNumber - (lines_before || 0)); const endLine = Math.min(lines.length, lineNumber + (lines_after || 0)); const contextLines = lines.slice(startLine - 1, endLine); const context = contextLines.map((ctxLine, ctxIndex) => { const ctxLineNumber = startLine + ctxIndex; const marker = ctxLineNumber === lineNumber ? '>' : ' '; return `${marker} ${ctxLineNumber} | ${ctxLine}`; }).join('\n'); matches.push(`Match at line ${lineNumber}:\n${context}`); } }); if (matches.length === 0) { return `No matches found for pattern "${regexp}" in file "${absolutePath}".`; } return matches.join('\n\n'); } catch (error: any) { if (error instanceof UserError) throw error; throw new UserError(`Error searching file "${absolutePath}": ${error.message}`); } } });

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/pwilkin/mcp-file-edit'

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