Skip to main content
Glama

find_symbol

Locate specific functions, classes, or methods in codebases using fuzzy search to find code symbols without exact names.

Instructions

🔍 STEP 2: Find specific functions, classes, or methods in the codebase.

USE THIS AFTER explore_repo() when you need to locate a specific piece of code. Uses fuzzy matching - you don't need the exact name!

INPUTS:

  • root_path: Same ABSOLUTE path used in explore_repo

  • query: What you're looking for (fuzzy search works!) Examples: "auth", "user service", "validate", "parseJSON"

EXAMPLE INPUTS: find_symbol("/Users/john/awesome-project", "authenticate") find_symbol("/Users/john/awesome-project", "user model") # Fuzzy matches "UserModel"

EXAMPLE OUTPUT: [ { "name": "authenticate_user", "type": "function", "path": "/Users/john/awesome-project/src/auth.py", "start_line": 45, "end_line": 67 }, { "name": "AuthService", "type": "class", "path": "/Users/john/awesome-project/src/services.py", "start_line": 12, "end_line": 89 } ]

RETURNS: List of symbol objects (dictionaries). Save these objects - you'll pass them to what_breaks()! Empty list if no matches found.

WHAT TO DO NEXT: Pick a symbol from the results and pass THE ENTIRE SYMBOL OBJECT to what_breaks() to see where it's used in the codebase.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
root_pathYes
queryYes

Implementation Reference

  • MCP tool handler for 'find_symbol'. Retrieves the XRayIndexer for the given root_path and delegates to its find_symbol method, handling errors by returning an error dictionary.
    @mcp.tool def find_symbol(root_path: str, query: str) -> List[Dict[str, Any]]: """ 🔍 STEP 2: Find specific functions, classes, or methods in the codebase. USE THIS AFTER explore_repo() when you need to locate a specific piece of code. Uses fuzzy matching - you don't need the exact name! INPUTS: - root_path: Same ABSOLUTE path used in explore_repo - query: What you're looking for (fuzzy search works!) Examples: "auth", "user service", "validate", "parseJSON" EXAMPLE INPUTS: find_symbol("/Users/john/awesome-project", "authenticate") find_symbol("/Users/john/awesome-project", "user model") # Fuzzy matches "UserModel" EXAMPLE OUTPUT: [ { "name": "authenticate_user", "type": "function", "path": "/Users/john/awesome-project/src/auth.py", "start_line": 45, "end_line": 67 }, { "name": "AuthService", "type": "class", "path": "/Users/john/awesome-project/src/services.py", "start_line": 12, "end_line": 89 } ] RETURNS: List of symbol objects (dictionaries). Save these objects - you'll pass them to what_breaks()! Empty list if no matches found. WHAT TO DO NEXT: Pick a symbol from the results and pass THE ENTIRE SYMBOL OBJECT to what_breaks() to see where it's used in the codebase. """ try: indexer = get_indexer(root_path) results = indexer.find_symbol(query) return results except Exception as e: return [{"error": f"Error finding symbol: {str(e)}"}]
  • Core helper function implementing the symbol search logic. Uses multiple ast-grep patterns for different languages to find potential symbols, extracts details, deduplicates, applies fuzzy matching with thefuzz library, and returns the top matching symbols with their locations.
    def find_symbol(self, query: str, limit: int = 10) -> List[Dict[str, Any]]: """ Find symbols matching the query using fuzzy search. Uses ast-grep to find all symbols, then fuzzy matches against the query. Returns a list of the top matching "Exact Symbol" objects. """ all_symbols = [] # Define patterns for different symbol types patterns = [ # Python functions and classes ("def $NAME($$$):", "function"), ("class $NAME($$$):", "class"), ("async def $NAME($$$):", "function"), # JavaScript/TypeScript functions and classes ("function $NAME($$$)", "function"), ("const $NAME = ($$$) =>", "function"), ("let $NAME = ($$$) =>", "function"), ("var $NAME = ($$$) =>", "function"), ("class $NAME", "class"), ("interface $NAME", "interface"), ("type $NAME =", "type"), # Go functions and types ("func $NAME($$$)", "function"), ("func ($$$) $NAME($$$)", "method"), ("type $NAME struct", "struct"), ("type $NAME interface", "interface"), ] # Run ast-grep for each pattern for pattern, symbol_type in patterns: cmd = [ "ast-grep", "--pattern", pattern, "--json", str(self.root_path) ] result = subprocess.run(cmd, capture_output=True, text=True) if result.returncode == 0: try: matches = json.loads(result.stdout) for match in matches: # Extract details from match text = match.get("text", "") file_path = match.get("file", "") start = match.get("range", {}).get("start", {}) end = match.get("range", {}).get("end", {}) # Extract the name from metavariables metavars = match.get("metaVariables", {}) name = None # Try to get NAME from metavariables if "NAME" in metavars: name = metavars["NAME"]["text"] else: # Fallback to regex extraction name = self._extract_symbol_name(text) if name: symbol = { "name": name, "type": symbol_type, "path": file_path, "start_line": start.get("line", 1), "end_line": end.get("line", start.get("line", 1)) } all_symbols.append(symbol) except json.JSONDecodeError: continue # Deduplicate symbols (same name and location) seen = set() unique_symbols = [] for symbol in all_symbols: key = (symbol["name"], symbol["path"], symbol["start_line"]) if key not in seen: seen.add(key) unique_symbols.append(symbol) # Now perform fuzzy matching against the query scored_symbols = [] for symbol in unique_symbols: # Calculate similarity score score = fuzz.partial_ratio(query.lower(), symbol["name"].lower()) # Boost score for exact substring matches if query.lower() in symbol["name"].lower(): score = max(score, 80) scored_symbols.append((score, symbol)) # Sort by score and take top results scored_symbols.sort(key=lambda x: x[0], reverse=True) top_symbols = [s[1] for s in scored_symbols[:limit]] return top_symbols

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/srijanshukla18/xray'

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