Skip to main content
Glama

what_breaks

Analyze code impact by identifying references to a specific symbol using structural search. Shows what might break when modifying functions or classes in Python, JavaScript, TypeScript, or Go projects.

Instructions

💥 STEP 3: See what code might break if you change this symbol.

USE THIS AFTER find_symbol() to understand the impact of changing a function/class.

IMPROVEMENTS:

  • Uses structural search (ast-grep) to find ACTUAL code references (ignoring comments/strings).

  • Returns 2 lines of context around each match.

INPUT:

  • exact_symbol: Pass THE ENTIRE SYMBOL OBJECT from find_symbol(), not just the name! Must be a dictionary with AT LEAST 'name' and 'path' keys.

EXAMPLE INPUT:

First, get a symbol from find_symbol():

symbols = find_symbol("/Users/john/project", "authenticate") symbol = symbols[0] # Pick the first result

Then pass THE WHOLE SYMBOL OBJECT:

what_breaks(symbol)

EXAMPLE OUTPUT: { "references": [ { "file": "/Users/john/project/src/api.py", "line": 23, "text": " # Authenticate the user user = authenticate_user(username, password) if not user:", "type": "code" } ], "total_count": 1, "strategy": "structural", "note": "Found 1 references using structural search." }

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
exact_symbolYes

Implementation Reference

  • MCP tool handler and registration for 'what_breaks'. Extracts repository root, gets indexer, calls core what_breaks method.
    @mcp.tool def what_breaks(exact_symbol: Dict[str, Any]) -> Dict[str, Any]: """ 💥 STEP 3: See what code might break if you change this symbol. USE THIS AFTER find_symbol() to understand the impact of changing a function/class. IMPROVEMENTS: - Uses structural search (ast-grep) to find ACTUAL code references (ignoring comments/strings). - Returns 2 lines of context around each match. INPUT: - exact_symbol: Pass THE ENTIRE SYMBOL OBJECT from find_symbol(), not just the name! Must be a dictionary with AT LEAST 'name' and 'path' keys. EXAMPLE INPUT: # First, get a symbol from find_symbol(): symbols = find_symbol("/Users/john/project", "authenticate") symbol = symbols[0] # Pick the first result # Then pass THE WHOLE SYMBOL OBJECT: what_breaks(symbol) EXAMPLE OUTPUT: { "references": [ { "file": "/Users/john/project/src/api.py", "line": 23, "text": " # Authenticate the user\n user = authenticate_user(username, password)\n if not user:", "type": "code" } ], "total_count": 1, "strategy": "structural", "note": "Found 1 references using structural search." } """ try: # Extract root path from the symbol's path symbol_path = Path(exact_symbol['path']) root_path = str(symbol_path.parent) # Find a suitable root (go up until we find a git repo or reach root) while root_path != '/': if (Path(root_path) / '.git').exists(): break parent = Path(root_path).parent if parent == Path(root_path): break root_path = str(parent) indexer = get_indexer(root_path) return indexer.what_breaks(exact_symbol) except Exception as e: return {"error": f"Error finding references: {str(e)}"}
  • Core logic of what_breaks: structural search with ast-grep (prioritized), fallback to text search (ripgrep/python), filters definition file/line, returns references with context.
    def what_breaks(self, exact_symbol: Dict[str, Any], context_lines: int = 2) -> Dict[str, Any]: """ Find what uses a symbol (reverse dependencies) using structural search. Prioritizes ast-grep for code references, falls back to text search. """ symbol_name = exact_symbol['name'] definition_path = str(Path(exact_symbol['path']).resolve()) definition_start = exact_symbol.get('start_line', -1) references = [] strategy = "structural" # Try structural search first (ast-grep) struct_refs = self._ast_grep_search(symbol_name, context_lines) if struct_refs: # Filter out the definition itself for ref in struct_refs: ref_path = str(Path(ref['file']).resolve()) ref_line = ref['line'] # Simple collision check: same file and line is close to definition # (ast-grep definition match might be on definition line) if ref_path == definition_path and abs(ref_line - definition_start) <= 1: continue references.append(ref) else: # Fallback to text search if ast-grep found nothing (or failed) # Note: This might happen if the symbol is not in a supported language file # or if it's only used in comments/strings (which we might want to know about as fallback?) # For now, if structural search returns empty list, we trust it for code. # But we might want to run text search as a backup for non-code files? # Let's stick to the previous behavior's fallback logic: if ast-grep *fails to run*, we use grep. # If ast-grep runs and finds nothing, we return nothing (for code). # BUT, to be safe and "improve" without breaking, let's run text search # if structural search is empty, but mark them as "text matches". # Actually, let's just use the text search if structural returned nothing. strategy = "text" references = self._text_search(symbol_name, context_lines) return { "references": references, "total_count": len(references), "strategy": strategy, "note": f"Found {len(references)} references using {strategy} search." }

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