Skip to main content
Glama
TwT23333
by TwT23333

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

TableJSON Schema
NameRequiredDescriptionDefault
file_patternNoOptional file pattern to limit search
function_nameYesName 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"]
        }
  • 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)}"}

Schema Changelog

Changes observed during successful MCP inspections.

  1. First observedv1.0.0

TDQS

C2.7/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries full burden but only states the basic action without behavioral details. It doesn't disclose whether this is a read-only operation, if it searches across files or a workspace, performance considerations, or output format. For a tool with no annotations, this is inadequate as it misses key operational context.

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 a single, clear sentence with zero waste—'Find function definitions by name' is front-loaded and efficiently conveys the core purpose without unnecessary words. It earns its place by being direct and to the point.

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

Completeness2/5

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

Given no annotations, no output schema, and a simple input schema, the description is incomplete. It doesn't explain what a 'function definition' includes (e.g., signatures, bodies), the search scope (e.g., current directory, all files), or return values. For a tool in a code-focused server with many siblings, more context is needed to guide effective use.

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 both parameters ('function_name' as required and 'file_pattern' as optional). The description adds no additional meaning beyond implying the tool uses 'function_name' to find definitions, which aligns with the schema. Baseline 3 is appropriate as the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description 'Find function definitions by name' clearly states the action (find) and target (function definitions), but it's vague about scope and doesn't distinguish from siblings like 'find_class' or 'grep'. It specifies 'by name' which helps, but lacks detail on what constitutes a 'function definition' or where it searches.

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

Usage Guidelines2/5

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

No guidance is provided on when to use this tool versus alternatives like 'find_class' for classes, 'grep' for text search, or 'semantic_search' for broader code queries. The description implies it's for functions by name, but doesn't specify contexts or exclusions, leaving the agent to guess based on tool names alone.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.