Skip to main content
Glama
rodhayl
by rodhayl

index_symbols

Build an in-memory symbol index for cross-file lookups to enable symbol-aware code analysis and workspace exploration.

Instructions

Build in-memory symbol index for cross-file lookups.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
rootYesRoot directory to index
languagesNoLanguages to index
symbolTypesNoSymbol types to include

Implementation Reference

  • The `indexSymbols` method within the `SymbolIndexer` class performs the indexing logic by scanning the source directory for files, parsing them based on language-specific regex patterns, and caching the results for efficiency.
    indexSymbols(
      root: string,
      options: {
        languages?: string[];
        symbolTypes?: string[];
      } = {}
    ): IndexSymbolsResult {
      const startTime = performance.now();
      const resolvedRoot = this.config.resolveWorkspacePath(root);
    
      if (!this.config.isPathAllowed(resolvedRoot)) {
        throw new Error(`Access denied: Path '${root}' is not in the allowlist`);
      }
    
      const languages = options.languages || ['typescript', 'javascript', 'python'];
    
      // Build language extensions set for filtering
      const langExtensions = new Set<string>();
      for (const lang of languages) {
        const exts = this.languageExtensions[lang];
        if (exts) {
          exts.forEach((ext) => langExtensions.add(ext));
        }
      }
    
      // Check cache - but we still need to filter by language
      const cacheKey = resolvedRoot;
      const cached = this.cache.get(cacheKey);
      if (cached && Date.now() - cached.timestamp < this.cacheTTL) {
        // Filter cached results by language and symbol types
        let symbols = cached.symbols;
    
        // Filter by language
        symbols = symbols.filter((s) => {
          const ext = extname(s.file).toLowerCase();
          return langExtensions.has(ext);
        });
    
        // Filter by symbol types
        if (options.symbolTypes?.length) {
          symbols = symbols.filter((s) => options.symbolTypes!.includes(s.type));
        }
        return {
          indexed: symbols.length,
          symbols,
          indexDuration: 0,
          languages,
        };
      }
    
      // For non-cached case, find and index files
      const files = this.findSourceFiles(resolvedRoot, ['typescript', 'javascript', 'python']); // Always scan all
      const allSymbols: SymbolInfo[] = [];
      const detectedLanguages = new Set<string>();
    
      for (const filePath of files) {
        try {
          const language = this.getLanguage(filePath);
          if (!language) continue;
    
          const content = readFileSync(filePath, 'utf-8');
          const symbols = this.extractSymbols(content, filePath, language);
          allSymbols.push(...symbols);
          if (symbols.length > 0) {
            detectedLanguages.add(language);
          }
        } catch {
          // Skip files we can't read
        }
      }
    
      // Cache the unfiltered results (all languages)
      this.cache.set(cacheKey, {
        symbols: allSymbols,
        timestamp: Date.now(),
        root: resolvedRoot,
      });
    
      // Now filter by requested languages and symbol types
      let filteredSymbols = allSymbols.filter((s) => {
        const ext = extname(s.file).toLowerCase();
        return langExtensions.has(ext);
      });
    
      if (options.symbolTypes?.length) {
        filteredSymbols = filteredSymbols.filter((s) => options.symbolTypes!.includes(s.type));
      }
    
      const duration = Math.max(0.001, performance.now() - startTime);
    
      return {
        indexed: filteredSymbols.length,
        symbols: filteredSymbols,
        indexDuration: duration,
        languages: Array.from(detectedLanguages).filter((lang) => languages.includes(lang)),
      };
    }

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/rodhayl/mcpLocalHelper'

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