Skip to main content
Glama

scan_dependencies

Analyze code dependencies to identify required functions and imports before making edits, preventing errors in JavaScript, TypeScript, HTML, and Python projects.

Instructions

Scans code for dependencies. Supports JS, TS, HTML, Python.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
codeYes
target_functionYes
languageNoauto
ignore_customNo

Implementation Reference

  • The primary handler function for the 'scan_dependencies' tool. Decorated with @mcp.tool() for registration. Scans code snippets for dependencies in Python (AST), JS/TS/HTML (Tree-sitter), returns formatted analysis with suggested index.
    def scan_dependencies( code: str, target_function: str, language: str = "auto", ignore_custom: Union[List[str], str, None] = None ) -> str: """ Scans code for dependencies. Supports JS, TS, HTML, Python. """ try: if parser_js is None: return "CRITICAL ERROR: Tree-sitter parsers failed to initialize." # СБРОС СОСТОЯНИЯ ПРИ НОВОМ СКАНИРОВАНИИ # Это важно: если ИИ начал сканировать заново, он теряет право на правку APPROVAL_STATE[target_function] = "NONE" normalized_ignore = [] if isinstance(ignore_custom, list): normalized_ignore = ignore_custom elif isinstance(ignore_custom, str): normalized_ignore = [ignore_custom] lang_lower = language.lower() # --- PYTHON --- if lang_lower == "python" or lang_lower == "py": deps, logs = _extract_python_dependencies(code, target_function, normalized_ignore) sorted_deps = sorted(list(deps)) return f""" [ACCESS REVOKED] Python Analysis for '{target_function}': -------------------------------- Found Dependencies: {', '.join(sorted_deps) if sorted_deps else 'None'} SUGGESTED INDEX: {target_function + ("_" + "_".join(sorted_deps) if sorted_deps else "")} DEBUG INFO: {chr(10).join(logs[:15])} """ # --- HTML --- if lang_lower == "html": if not parser_html: return "Error: HTML parser not initialized." tree = parser_html.parse(bytes(code, "utf8")) deps, logs = _extract_html_dependencies(tree) sorted_deps = sorted(list(deps)) return f""" [ACCESS REVOKED] HTML Analysis for '{target_function}': -------------------------------- Found Dependencies: {', '.join(sorted_deps) if sorted_deps else 'None'} DEBUG INFO: {chr(10).join(logs)} """ # --- JS / TS --- selected_parser = parser_js logs_prefix = "JavaScript" if lang_lower == "auto": if "def " in code or "import " in code or "class " in code: try: ast.parse(code) deps, logs = _extract_python_dependencies(code, target_function, normalized_ignore) sorted_deps = sorted(list(deps)) return f""" [ACCESS REVOKED] Auto-Detected Python Analysis for '{target_function}': -------------------------------- Found Dependencies: {', '.join(sorted_deps) if sorted_deps else 'None'} SUGGESTED INDEX: {target_function + ("_" + "_".join(sorted_deps) if sorted_deps else "")} """ except: pass tree_js = parser_js.parse(bytes(code, "utf8")) js_errors = has_syntax_errors(tree_js) tree_ts = parser_ts.parse(bytes(code, "utf8")) ts_errors = has_syntax_errors(tree_ts) if js_errors and not ts_errors: return """ 🛑 AMBIGUITY DETECTED --------------------- The code looks like TypeScript. Please ASK THE USER: "Is this JavaScript or TypeScript?" """ elif not js_errors: selected_parser = parser_js logs_prefix = "Auto-Detected JS" else: selected_parser = parser_ts logs_prefix = "Auto-Detected TS (Fallback)" elif lang_lower in ["ts", "typescript", "tsx"]: selected_parser = parser_ts logs_prefix = "TypeScript" elif lang_lower == "python": return "Python support via AST module is available in v4.3 if needed." tree_raw = selected_parser.parse(bytes(code, "utf8")) deps, logs = _extract_dependencies_from_tree(tree_raw, target_function, normalized_ignore) used_wrapper = False if not deps: logs.append("--- Attempting Auto-Wrapper ---") wrapped_code = f"class AutoWrapper {{ {code} }}" tree_wrapped = selected_parser.parse(bytes(wrapped_code, "utf8")) deps_wrapped, logs_wrapped = _extract_dependencies_from_tree(tree_wrapped, target_function, normalized_ignore) if deps_wrapped: deps = deps_wrapped logs.extend(logs_wrapped) used_wrapper = True sorted_deps = sorted(list(deps)) index_str = target_function + ("_" + "_".join(sorted_deps) if sorted_deps else "") debug_output = "\n ".join(logs[:15]) return f""" [ACCESS REVOKED] {logs_prefix} Analysis for '{target_function}': -------------------------------- Found Dependencies: {', '.join(sorted_deps) if sorted_deps else 'None'} SUGGESTED INDEX: {index_str} DEBUG INFO: Wrapper Used: {used_wrapper} Logs: {debug_output} ... """ except Exception as e: return f"INTERNAL SERVER ERROR during scanning: {str(e)}\nTraceback: {traceback.format_exc()}"
  • Helper function to extract dependencies from Python code using AST, ignoring builtins and custom list.
    def _extract_python_dependencies(code: str, target_name: str, ignore_custom: Optional[List[str]] = None) -> Tuple[Set[str], List[str]]: dependencies = set() logs = [] try: tree = ast.parse(code) except SyntaxError as e: return set(), [f"Python Syntax Error: {e}"] target_node = None for node in ast.walk(tree): if isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef, ast.ClassDef)): if node.name == target_name: target_node = node break if target_node: logs.append(f"✅ Found Python target: {type(target_node).__name__}") else: logs.append("❌ Target node NOT found. Scanning entire snippet.") target_node = tree IGNORE_PYTHON = { "print", "len", "str", "int", "float", "bool", "list", "dict", "set", "tuple", "range", "enumerate", "zip", "map", "filter", "sum", "min", "max", "abs", "isinstance", "issubclass", "type", "super", "getattr", "setattr", "hasattr", "open", "dir", "id", "input", "repr", "round", "sorted", "reversed", "__init__", "__str__", "__repr__", "self" } if ignore_custom: IGNORE_PYTHON.update(ignore_custom) for node in ast.walk(target_node): call_name = None if isinstance(node, ast.Call): if isinstance(node.func, ast.Name): call_name = node.func.id elif isinstance(node.func, ast.Attribute): call_name = node.func.attr if isinstance(node.func.value, ast.Name) and node.func.value.id == 'self': logs.append(f"Found self call: {call_name}") if call_name: if call_name not in IGNORE_PYTHON and call_name != target_name: dependencies.add(call_name) return dependencies, logs
  • Core helper for extracting dependencies from JS/TS Tree-sitter parse trees, scans call expressions and member accesses.
    def _extract_dependencies_from_tree(tree, target_name: str, ignore_custom: Optional[List[str]] = None) -> Tuple[Set[str], List[str]]: if not tree: return set(), ["Error: Tree is None"] root_node = tree.root_node dependencies = set() logs = [] def find_target_node(node, name): if node.type == 'class_declaration': name_node = node.child_by_field_name('name') if name_node and name_node.text.decode('utf8') == name: return node if node.type == 'function_declaration': name_node = node.child_by_field_name('name') if name_node and name_node.text.decode('utf8') == name: return node elif node.type == 'method_definition': name_node = node.child_by_field_name('name') if name_node and name_node.text.decode('utf8') == name: return node.child_by_field_name('body') elif node.type == 'lexical_declaration': for i in range(node.child_count): child = node.child(i) if child.type == 'variable_declarator': name_node = child.child_by_field_name('name') if name_node and name_node.text.decode('utf8') == name: return child.child_by_field_name('value') for i in range(node.child_count): res = find_target_node(node.child(i), name) if res: return res return None target_node = find_target_node(root_node, target_name) if target_node: logs.append(f"✅ Found target node type: {target_node.type}") else: logs.append("❌ Target node NOT found. Scanning root.") target_node = root_node IGNORE_LIST = { "console", "Math", "JSON", "Date", "Object", "Array", "Promise", "Error", "parseInt", "parseFloat", "setTimeout", "setInterval", "alert", "confirm", "require", "window", "document", "history", "navigator", "location" } IGNORE_METHODS = { "log", "error", "warn", "info", "debug", "push", "pop", "shift", "unshift", "splice", "slice", "join", "split", "map", "filter", "reduce", "forEach", "find", "some", "every", "toString", "toFixed", "replace", "replaceAll", "trim", "querySelector", "querySelectorAll", "getElementById", "addEventListener", "remove", "add", "has", "get", "set", "keys", "values", "entries", "now", "abs", "round", "floor", "ceil", "min", "max", "random", "then", "catch", "finally", "length", "subscribe", "unsubscribe" } if ignore_custom: IGNORE_LIST.update(ignore_custom) IGNORE_METHODS.update(ignore_custom) def find_calls(node): if node.type == 'call_expression': func_node = node.child_by_field_name('function') call_name = None if func_node.type == 'identifier': call_name = func_node.text.decode('utf8') elif func_node.type == 'member_expression': prop_node = func_node.child_by_field_name('property') obj_node = func_node.child_by_field_name('object') if prop_node: method_name = prop_node.text.decode('utf8') obj_name = obj_node.text.decode('utf8') if obj_node else "unknown" if (obj_node.type == 'this') or (obj_name == 'this'): call_name = method_name elif method_name not in IGNORE_METHODS: call_name = method_name if call_name: if call_name not in IGNORE_LIST and call_name != target_name: dependencies.add(call_name) else: # logs.append(f"Ignored: {call_name}") pass for i in range(node.child_count): find_calls(node.child(i)) find_calls(target_node) return dependencies, logs
  • Helper to extract dependencies from HTML Tree-sitter tree, focusing on script src and event handlers.
    def _extract_html_dependencies(tree) -> Tuple[Set[str], List[str]]: if not tree: return set(), ["Error: HTML Tree is None"] root_node = tree.root_node dependencies = set() logs = [] logs.append("Scanning HTML structure...") def traverse(node): if node.type == 'attribute': attr_name = None attr_value = None for i in range(node.child_count): child = node.child(i) if child.type == 'attribute_name': attr_name = child.text.decode('utf8') elif child.type == 'quoted_attribute_value' or child.type == 'attribute_value': attr_value = child.text.decode('utf8').strip('"\'') if attr_name and attr_value: if attr_name == 'src': parent = node.parent if parent and (parent.type == 'script_start_tag' or parent.type == 'script_element'): dependencies.add(f"FILE: {attr_value}") logs.append(f"Found script: {attr_value}") elif attr_name.startswith('on'): func_name = attr_value.split('(')[0].strip() if func_name: dependencies.add(f"EVENT: {func_name}") logs.append(f"Found event: {attr_name} -> {func_name}") for i in range(node.child_count): traverse(node.child(i)) traverse(root_node) return dependencies, logs
  • Tool description and implicit schema via type hints in function signature.
    """ Scans code for dependencies. Supports JS, TS, HTML, Python. """

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/yrannkv/mcp-edit-math'

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