grep
Search file contents for specific patterns within virtual filesystem workspaces to locate relevant information quickly.
Instructions
Search file contents for a pattern.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| request | Yes |
Implementation Reference
- src/chuk_mcp_vfs/vfs_tools.py:368-452 (handler)The core handler function for the 'grep' tool. It recursively searches files under the specified path for lines matching the pattern, collecting matches with file path, line number, and line content. Supports max_results limit and reports if truncated.async def grep(self, request: GrepRequest) -> GrepResponse: """ Search file contents for a pattern. Args: request: GrepRequest with pattern, path, and max_results Returns: GrepResponse with matches """ vfs = self.workspace_manager.get_current_vfs() resolved_path = self.workspace_manager.resolve_path(request.path) matches: list[GrepMatch] = [] truncated = False async def search_file(file_path: str) -> None: nonlocal truncated if len(matches) >= request.max_results: truncated = True return try: content = await vfs.read_file(file_path) if content is None: return if isinstance(content, bytes): content_str = content.decode("utf-8", errors="ignore") else: content_str = content for line_num, line in enumerate(content_str.splitlines(), start=1): if request.pattern in line: matches.append( GrepMatch( file=file_path, line=line_num, content=line.strip() ) ) if len(matches) >= request.max_results: truncated = True break except Exception: # Skip files that can't be read pass async def search_dir(current_path: str) -> None: nonlocal truncated if len(matches) >= request.max_results: truncated = True return filenames = await vfs.ls(current_path) for name in filenames: if len(matches) >= request.max_results: truncated = True break # Construct full path if current_path == "/": full_path = f"/{name}" else: full_path = f"{current_path}/{name}" node_info = await vfs.get_node_info(full_path) if not node_info: continue if node_info.is_dir: await search_dir(full_path) else: await search_file(full_path) node = await vfs.get_node_info(resolved_path) if not node: raise ValueError(f"Path not found: {resolved_path}") if node.is_dir: await search_dir(resolved_path) else: await search_file(resolved_path) return GrepResponse( pattern=request.pattern, matches=matches, truncated=truncated )
- src/chuk_mcp_vfs/models.py:248-270 (schema)Pydantic models defining the input (GrepRequest with pattern, path, max_results), output (GrepResponse with matches list and truncated flag), and match structure (GrepMatch with file, line, content).class GrepMatch(BaseModel): """A grep match result""" file: str line: int content: str class GrepRequest(BaseModel): """Request to grep files""" pattern: str path: str = "." max_results: int = Field(default=100, ge=1, le=1000) class GrepResponse(BaseModel): """Response from grep operation""" pattern: str matches: list[GrepMatch] truncated: bool = False
- src/chuk_mcp_vfs/server.py:146-149 (registration)Registers the 'grep' tool on the MCP server using @server.tool decorator, delegating to VFSTools.grep method.@server.tool async def grep(request: GrepRequest): """Search file contents for a pattern.""" return await vfs_tools.grep(request)