find_function
Locate function definitions by name using advanced semantic search; optionally filter results by file pattern to streamline code navigation and analysis.
Instructions
Find function definitions by name
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| file_pattern | No | Optional file pattern to limit search | |
| function_name | Yes | Name of the function to find |
Implementation Reference
- Handler: The execute method of FindFunctionTool that implements the core tool logic, processing arguments, calling the search backend, and formatting results.
async def execute(self, arguments: Dict[str, Any]) -> ToolResult: """Execute the find_function tool.""" try: function_name = arguments.get("function_name") file_pattern = arguments.get("file_pattern") if not function_name: return self.format_error("function_name is required") search_tools = AdvancedSearchTools(self.workspace.config, self.workspace.workspace_path) result = await search_tools.find_function(function_name, file_pattern) if "error" in result: return self.format_error(result["error"]) # Format the response if result['results']: message = f"Found {len(result['results'])} function definition(s) for '{function_name}':\n\n" for match in result['results']: message += f"📁 {match['file_path']}:{match['line_number']} ({match['language']})\n" message += f" {match['function_definition']}\n\n" else: message = f"No function definitions found for '{function_name}'" if file_pattern: message += f" in files matching '{file_pattern}'" return ToolResult( success=True, message=message, properties=result ) except Exception as e: logger.error(f"Error in find_function: {e}") return self.format_error(str(e)) - Schema: Input schema property defining the expected parameters for the find_function tool.
@property def input_schema(self) -> Dict[str, Any]: return { "type": "object", "properties": { "function_name": { "type": "string", "description": "Name of the function to find" }, "file_pattern": { "type": "string", "description": "Optional file pattern to limit search" } }, "required": ["function_name"] } - src/moatless_mcp/tools/registry.py:63-68 (registration)Registration: Instantiation and registration of FindFunctionTool in the ToolRegistry's default tools list.
# Advanced tools FindClassTool(self.workspace), FindFunctionTool(self.workspace), ViewCodeTool(self.workspace), SemanticSearchTool(self.workspace), RunTestsTool(self.workspace), - Helper: The underlying find_function method in AdvancedSearchTools that performs the actual codebase search for function definitions using tree-sitter or regex fallbacks.
async def find_function(self, function_name: str, file_pattern: Optional[str] = None) -> Dict[str, Any]: """Find function definitions in the codebase using tree-sitter when available. Args: function_name: Name of the function to find file_pattern: Optional file pattern to limit search Returns: Dictionary with search results including file paths and line numbers """ try: if not function_name or not function_name.strip(): return {"error": "Function name cannot be empty"} clean_function_name = function_name.strip() results = [] search_paths = [] # Determine search paths if file_pattern: try: search_paths = list(self.workspace_root.glob(file_pattern)) except Exception as e: logger.warning(f"Invalid file pattern {file_pattern}: {e}") search_paths = [] if not search_paths: search_paths = [] for root, dirs, files in os.walk(self.workspace_root): for file in files: file_path = Path(root) / file if self.config.is_file_allowed(file_path): search_paths.append(file_path) # Use tree-sitter parser if available if TREE_SITTER_AVAILABLE: parser = CodeParser() for file_path in search_paths: if not self.config.is_file_allowed(file_path): continue try: # Use tree-sitter to find functions functions = parser.find_functions(str(file_path), clean_function_name) for func_def in functions: # Extract the function definition line lines = func_def.text.split('\n') func_line = lines[0].strip() if lines else "" # Determine if it's a method (has parent class) func_type = "method" if func_def.parent else "function" results.append({ "file_path": str(file_path.relative_to(self.workspace_root)), "line_number": func_def.start_line, "function_definition": func_line, "match_text": func_line, "language": detect_language(str(file_path)) if detect_language else "unknown", "function_type": func_type, "parent_class": func_def.parent.name if func_def.parent else None, "parameters": func_def.parameters if hasattr(func_def, 'parameters') else [], "tree_sitter": True }) except Exception as e: logger.debug(f"Tree-sitter parsing failed for {file_path}: {e}") # Fall back to regex for this file self._find_function_regex(file_path, clean_function_name, results) else: # Fallback to regex search for file_path in search_paths: if not self.config.is_file_allowed(file_path): continue self._find_function_regex(file_path, clean_function_name, results) # Remove duplicates (same file and line) unique_results = [] seen = set() for result in results: key = (result["file_path"], result["line_number"]) if key not in seen: seen.add(key) unique_results.append(result) return { "function_name": clean_function_name, "results": unique_results, "total_matches": len(unique_results), "search_pattern": file_pattern, "tree_sitter_used": TREE_SITTER_AVAILABLE } except Exception as e: logger.error(f"Error in find_function: {e}") return {"error": f"Search failed: {str(e)}"}