Skip to main content
Glama

code-index-mcp

""" Common validation logic for the MCP server. This module provides shared validation functions used across services to ensure consistent validation behavior and reduce code duplication. """ import os import re import fnmatch from typing import Optional, List from ..indexing.qualified_names import normalize_file_path class ValidationHelper: """ Helper class containing common validation logic. This class provides static methods for common validation operations that are used across multiple services. """ @staticmethod def validate_file_path(file_path: str, base_path: str) -> Optional[str]: """ Validate a file path for security and accessibility. This method checks for: - Path traversal attempts - Absolute path usage (not allowed) - Path existence within base directory Args: file_path: The file path to validate (should be relative) base_path: The base project directory path Returns: Error message if validation fails, None if valid """ if not file_path: return "File path cannot be empty" if not base_path: return "Base path not set" # Handle absolute paths (especially Windows paths starting with drive letters) if os.path.isabs(file_path) or (len(file_path) > 1 and file_path[1] == ':'): return (f"Absolute file paths like '{file_path}' are not allowed. " "Please use paths relative to the project root.") # Normalize the file path norm_path = os.path.normpath(file_path) # Check for path traversal attempts if "..\\" in norm_path or "../" in norm_path or norm_path.startswith(".."): return f"Invalid file path: {file_path} (directory traversal not allowed)" # Construct the full path and verify it's within the project bounds full_path = os.path.join(base_path, norm_path) real_full_path = os.path.realpath(full_path) real_base_path = os.path.realpath(base_path) if not real_full_path.startswith(real_base_path): return "Access denied. File path must be within project directory." return None @staticmethod def validate_directory_path(dir_path: str) -> Optional[str]: """ Validate a directory path for project initialization. Args: dir_path: The directory path to validate Returns: Error message if validation fails, None if valid """ if not dir_path: return "Directory path cannot be empty" # Normalize and get absolute path try: norm_path = os.path.normpath(dir_path) abs_path = os.path.abspath(norm_path) except (OSError, ValueError) as e: return f"Invalid path format: {str(e)}" if not os.path.exists(abs_path): return f"Path does not exist: {abs_path}" if not os.path.isdir(abs_path): return f"Path is not a directory: {abs_path}" return None @staticmethod def validate_glob_pattern(pattern: str) -> Optional[str]: """ Validate a glob pattern for file searching. Args: pattern: The glob pattern to validate Returns: Error message if validation fails, None if valid """ if not pattern: return "Pattern cannot be empty" # Check for potentially dangerous patterns if pattern.startswith('/') or pattern.startswith('\\'): return "Pattern cannot start with path separator" # Test if the pattern is valid by trying to compile it try: # This will raise an exception if the pattern is malformed fnmatch.translate(pattern) except (ValueError, TypeError) as e: return f"Invalid glob pattern: {str(e)}" return None @staticmethod def validate_search_pattern(pattern: str, regex: bool = False) -> Optional[str]: """ Validate a search pattern for code searching. Args: pattern: The search pattern to validate regex: Whether the pattern is a regex pattern Returns: Error message if validation fails, None if valid """ if not pattern: return "Search pattern cannot be empty" if regex: # Basic regex validation - check for potentially dangerous patterns try: re.compile(pattern) except re.error as e: return f"Invalid regex pattern: {str(e)}" # Check for potentially expensive regex patterns (basic ReDoS protection) dangerous_patterns = [ r'\(\?\=.*\)\+', # Positive lookahead with quantifier r'\(\?\!.*\)\+', # Negative lookahead with quantifier r'\(\?\<\=.*\)\+', # Positive lookbehind with quantifier r'\(\?\<\!.*\)\+', # Negative lookbehind with quantifier ] for dangerous in dangerous_patterns: if re.search(dangerous, pattern): return "Potentially dangerous regex pattern detected" return None @staticmethod def validate_file_extensions(extensions: List[str]) -> Optional[str]: """ Validate a list of file extensions. Args: extensions: List of file extensions to validate Returns: Error message if validation fails, None if valid """ if not extensions: return "Extensions list cannot be empty" for ext in extensions: if not isinstance(ext, str): return "All extensions must be strings" if not ext.startswith('.'): return f"Extension '{ext}' must start with a dot" if len(ext) < 2: return f"Extension '{ext}' is too short" return None @staticmethod def sanitize_file_path(file_path: str) -> str: """ Sanitize a file path by normalizing separators and removing dangerous elements. Args: file_path: The file path to sanitize Returns: Sanitized file path """ if not file_path: return "" # Normalize path separators and structure sanitized = normalize_file_path(file_path) # Remove any leading slashes to ensure relative path sanitized = sanitized.lstrip('/') return sanitized

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/johnhuang316/code-index-mcp'

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