grep
Search for text patterns in files using regular expressions to locate specific content within directories and subdirectories.
Instructions
Search for text patterns inside files using regular expressions.
Args: dir (str): Directory to search in (absolute or relative to allowed directories) pattern (str): Regular expression pattern to search for in file contents exclude (str, optional): File pattern to exclude from search
Returns: str: Newline-separated matches in format 'path:lineNo: line', or error message if failed
Note: - Directory must be within allowed directory roots - Searches recursively through subdirectories - Only searches UTF-8 text files - Respects .gitignore files and skips common lock files - Each match shows file path, line number, and the matching line - Uses Python regular expression syntax
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| dir | Yes | ||
| pattern | Yes | ||
| exclude | No |
Implementation Reference
- main.py:500-564 (handler)The main handler function for the MCP 'grep' tool. It performs recursive regex-based text search in files under the specified directory, skipping ignored files and binaries, and formats output as 'path:lineNo:\tline'.@mcp.tool def grep(dir: str, pattern: str, exclude: str | None = None) -> str: """Search for text patterns inside files using regular expressions. Args: dir (str): Directory to search in (absolute or relative to allowed directories) pattern (str): Regular expression pattern to search for in file contents exclude (str, optional): File pattern to exclude from search Returns: str: Newline-separated matches in format 'path:lineNo:\tline', or error message if failed Note: - Directory must be within allowed directory roots - Searches recursively through subdirectories - Only searches UTF-8 text files - Respects .gitignore files and skips common lock files - Each match shows file path, line number, and the matching line - Uses Python regular expression syntax """ try: exclude_spec = ( pathspec.PathSpec( (pathspec.patterns.gitwildmatch.GitWildMatchPattern(exclude),) ) if exclude else None ) root = _resolve(dir) if not root.is_dir(): return f"Error grepping: '{root}' is not a directory" spec_cache: Dict[Path, Optional[pathspec.PathSpec]] = {} try: regex = re.compile(pattern) except re.error as e: return ( f"Error grepping: invalid regular expression pattern '{pattern}' - {e}" ) hits: List[str] = [] for file in root.rglob("*"): if file.is_dir(): continue grep_ignore_spec = pathspec.PathSpec.from_lines( pathspec.patterns.gitwildmatch.GitWildMatchPattern, GREP_IGNORE_FILES ) if grep_ignore_spec.match_file(file): continue if exclude_spec and exclude_spec.match_file(file): continue if _skip_ignored(file, root, spec_cache): continue if not _is_text(file): continue try: for idx, line in enumerate( file.read_text(encoding="utf-8", errors="ignore").splitlines(), 1 ): if regex.search(line): hits.append(f"{file}:{idx}:\t{line}") except Exception: continue return "\n".join(hits) except Exception as e: return _human_error(e, "grepping")
- main.py:182-185 (helper)Constant defining file patterns to ignore during 'grep' tool execution (e.g., lock files). Used within the grep handler to skip specific files.GREP_IGNORE_FILES = [ "*.lock", "package-lock.json", ]
- main.py:500-500 (registration)MCP decorator registering the 'grep' function as a tool (name derived from function name).@mcp.tool