Skip to main content
Glama
SDGLBL
by SDGLBL

grep

Search file contents using regular expressions to find specific patterns in codebases. Filter files by pattern and get results sorted by modification time.

Instructions

Fast content search tool that works with any codebase size. Searches file contents using regular expressions. Supports full regex syntax (eg. "log.Error", "function\s+\w+", etc.). Filter files by pattern with the include parameter (eg. ".js", "*.{ts,tsx}"). Returns matching file paths sorted by modification time. Use this tool when you need to find files containing specific patterns. When you are doing an open ended search that may require multiple rounds of globbing and grepping, use the Agent tool instead.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
patternYesThe regular expression pattern to search for in file contents
pathNoThe directory to search in. Defaults to the current working directory..
includeNoFile pattern to include in the search (e.g. "*.js", "*.{ts,tsx}")*

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes

Implementation Reference

  • The main handler function that orchestrates the grep search using ripgrep if available or a pure Python fallback implementation.
    async def call(
        self,
        ctx: MCPContext,
        **params: Unpack[GrepToolParams],
    ) -> str:
        """Execute the grep tool with the given parameters.
    
        Args:
            ctx: MCP context
            **params: Tool parameters
    
        Returns:
            Tool result
        """
        tool_ctx = self.create_tool_context(ctx)
    
        # Extract parameters
        pattern = params.get("pattern")
        path: str = params.get("path", ".")
        # Support both 'include' and legacy 'file_pattern' parameter for backward compatibility
        include: str = params.get("include") or params.get("file_pattern")
    
        # Validate required parameters for direct calls (not through MCP framework)
        if pattern is None:
            await tool_ctx.error("Parameter 'pattern' is required but was None")
            return "Error: Parameter 'pattern' is required but was None"
    
        # Validate path if provided
        if path:
            path_validation = self.validate_path(path)
            if path_validation.is_error:
                await tool_ctx.error(path_validation.error_message)
                return f"Error: {path_validation.error_message}"
    
            # Check if path is allowed
            allowed, error_msg = await self.check_path_allowed(path, tool_ctx)
            if not allowed:
                return error_msg
    
            # Check if path exists
            exists, error_msg = await self.check_path_exists(path, tool_ctx)
            if not exists:
                return error_msg
    
        # Log operation
        search_info = f"Searching for pattern '{pattern}'"
        if include:
            search_info += f" in files matching '{include}'"
        search_info += f" in path: {path}"
        await tool_ctx.info(search_info)
    
        # Check if ripgrep is installed and use it if available
        try:
            if self.is_ripgrep_installed():
                await tool_ctx.info("ripgrep is installed, using ripgrep for search")
                result = await self.run_ripgrep(pattern, path, tool_ctx, include)
                return result
            else:
                await tool_ctx.info(
                    "ripgrep is not installed, using fallback implementation"
                )
                result = await self.fallback_grep(pattern, path, tool_ctx, include)
                return result
        except Exception as e:
            await tool_ctx.error(f"Error in grep tool: {str(e)}")
            return f"Error in grep tool: {str(e)}"
  • Pydantic-compatible parameter schema defining the input types for the grep tool using Annotated strings for pattern, path, and include.
    class GrepToolParams(TypedDict):
        """Parameters for the Grep tool.
    
        Attributes:
            pattern: The regular expression pattern to search for in file contents
            path: The directory to search in. Defaults to the current working directory.
            include: File pattern to include in the search (e.g. "*.js", "*.{ts,tsx}")
        """
    
        pattern: Pattern
        path: SearchPath
        include: Include
  • The register method that defines and attaches the tool wrapper function to the FastMCP server.
    def register(self, mcp_server: FastMCP) -> None:
        """Register this grep tool with the MCP server.
    
        Creates a wrapper function with explicitly defined parameters that match
        the tool's parameter schema and registers it with the MCP server.
    
        Args:
            mcp_server: The FastMCP server instance
        """
        tool_self = self  # Create a reference to self for use in the closure
    
        @mcp_server.tool(name=self.name, description=self.description)
        async def grep(
            ctx: MCPContext,
            pattern: Pattern,
            path: SearchPath,
            include: Include,
        ) -> str:
            # Use 'include' parameter if provided, otherwise fall back to 'file_pattern'
            return await tool_self.call(
                ctx, pattern=pattern, path=path, include=include
            )
  • Function that instantiates all filesystem tools (including Grep) via get_filesystem_tools and registers them using ToolRegistry.
    def register_filesystem_tools(
        mcp_server: FastMCP,
        permission_manager: PermissionManager,
    ) -> list[BaseTool]:
        """Register all filesystem tools with the MCP server.
    
        Args:
            mcp_server: The FastMCP server instance
            permission_manager: Permission manager for access control
    
        Returns:
            List of registered tools
        """
        tools = get_filesystem_tools(permission_manager)
        ToolRegistry.register_tools(mcp_server, tools)
        return tools
  • Instantiates the Grep tool instance with permission_manager as part of the filesystem tools list.
    def get_filesystem_tools(permission_manager: PermissionManager) -> list[BaseTool]:
        """Create instances of all filesystem tools.
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 of behavioral disclosure. It effectively describes key traits: it's a search tool (implies read-only, non-destructive), supports regex syntax, filters files by pattern, and returns sorted results by modification time. However, it doesn't mention potential limitations like performance impacts on large files or error handling, leaving some gaps.

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 well-structured and front-loaded with the core purpose. Each sentence adds value: it explains functionality, provides examples, describes output sorting, and gives usage guidelines. There is no wasted text, making it efficient and easy to parse.

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

Completeness5/5

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

Given the tool's moderate complexity, 100% schema coverage, and the presence of an output schema, the description is complete enough. It covers purpose, usage, behavioral traits, and parameter context without needing to explain return values, which are handled by the output schema. No significant gaps remain for effective tool selection and invocation.

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 100%, so the schema already documents all parameters thoroughly. The description adds minimal value beyond the schema by mentioning regex examples and include patterns, but doesn't provide additional syntax or format details. This meets the baseline of 3 for high schema coverage.

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 as 'Fast content search tool that works with any codebase size' and 'Searches file contents using regular expressions,' specifying both the verb (search) and resource (file contents). It distinguishes itself from sibling tools like 'grep_ast' (likely AST-based search) and 'Agent' (for open-ended searches), providing clear differentiation.

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

Usage Guidelines5/5

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

The description explicitly states when to use this tool ('Use this tool when you need to find files containing specific patterns') and when not to ('When you are doing an open ended search that may require multiple rounds of globbing and grepping, use the Agent tool instead'). It provides clear alternatives and exclusions, helping the agent choose correctly among siblings.

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/SDGLBL/mcp-claude-code'

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