Home / Function/ buildIndexes() — mcp Function Reference

buildIndexes() — mcp Function Reference

Architecture documentation for the buildIndexes() function in graph-cache.ts from the mcp codebase.

Function typescript GraphCache Indexing calls 4 called by 4

Entity Profile

Dependency Diagram

graph TD
  11d5249b_82de_e1fb_e621_e95ae1a093c5["buildIndexes()"]
  4def3ca5_c0bf_fbae_1c00_3a7385fe0264["loadCacheFromDisk()"]
  4def3ca5_c0bf_fbae_1c00_3a7385fe0264 -->|calls| 11d5249b_82de_e1fb_e621_e95ae1a093c5
  1721f7fd_bb7b_c8c3_9b4b_5677293ae256["resolveOrFetchGraph()"]
  1721f7fd_bb7b_c8c3_9b4b_5677293ae256 -->|calls| 11d5249b_82de_e1fb_e621_e95ae1a093c5
  9003922a_3c12_9d09_182b_1d8c2e1893be["precacheForDirectory()"]
  9003922a_3c12_9d09_182b_1d8c2e1893be -->|calls| 11d5249b_82de_e1fb_e621_e95ae1a093c5
  d6ad31c3_e18b_0658_e475_b322f381fe73["buildGraph()"]
  d6ad31c3_e18b_0658_e475_b322f381fe73 -->|calls| 11d5249b_82de_e1fb_e621_e95ae1a093c5
  6407330b_8aa1_cc04_569a_747f6b1debfd["set()"]
  11d5249b_82de_e1fb_e621_e95ae1a093c5 -->|calls| 6407330b_8aa1_cc04_569a_747f6b1debfd
  90af3150_ce81_c645_faa7_5b8b9bcf5ecc["has()"]
  11d5249b_82de_e1fb_e621_e95ae1a093c5 -->|calls| 90af3150_ce81_c645_faa7_5b8b9bcf5ecc
  d6ed9355_f977_306b_b0ef_d7220fdefe68["get()"]
  11d5249b_82de_e1fb_e621_e95ae1a093c5 -->|calls| d6ed9355_f977_306b_b0ef_d7220fdefe68
  6666a1f2_0912_ade3_4b0e_42190c41cd97["normalizePath()"]
  11d5249b_82de_e1fb_e621_e95ae1a093c5 -->|calls| 6666a1f2_0912_ade3_4b0e_42190c41cd97
  style 11d5249b_82de_e1fb_e621_e95ae1a093c5 fill:#6366f1,stroke:#818cf8,color:#fff

Relationship Graph

Source Code

src/cache/graph-cache.ts lines 74–250

export function buildIndexes(raw: SupermodelIR, cacheKey: string): IndexedGraph {
  const nodes = raw.graph?.nodes || [];
  const relationships = raw.graph?.relationships || [];

  // Initialize indexes
  const nodeById = new Map<string, CodeGraphNode>();
  const labelIndex = new Map<string, string[]>();
  const pathIndex = new Map<string, PathIndexEntry>();
  const dirIndex = new Map<string, string[]>();
  const nameIndex = new Map<string, string[]>();
  const callAdj = new Map<string, AdjacencyList>();
  const importAdj = new Map<string, AdjacencyList>();
  const domainIndex = new Map<string, { memberIds: string[], relationships: CodeGraphRelationship[] }>();

  // Build node indexes
  for (const node of nodes) {
    const id = node.id;
    const props = node.properties || {};
    const labels = node.labels || [];

    // nodeById
    nodeById.set(id, node);

    // labelIndex
    for (const label of labels) {
      if (!labelIndex.has(label)) {
        labelIndex.set(label, []);
      }
      labelIndex.get(label)!.push(id);
    }

    // nameIndex (lowercase for case-insensitive search)
    const name = props.name as string | undefined;
    if (name) {
      const lowerName = name.toLowerCase();
      if (!nameIndex.has(lowerName)) {
        nameIndex.set(lowerName, []);
      }
      nameIndex.get(lowerName)!.push(id);
    }

    // pathIndex - track what's defined in each file
    const filePath = props.filePath as string | undefined;
    if (filePath) {
      const normalized = normalizePath(filePath);
      if (!pathIndex.has(normalized)) {
        pathIndex.set(normalized, { fileId: '', classIds: [], functionIds: [], typeIds: [] });
      }
      const entry = pathIndex.get(normalized)!;

      const primaryLabel = labels[0];
      if (primaryLabel === 'File') {
        entry.fileId = id;
      } else if (primaryLabel === 'Class') {
        entry.classIds.push(id);
      } else if (primaryLabel === 'Function') {
        entry.functionIds.push(id);
      } else if (primaryLabel === 'Type') {
        entry.typeIds.push(id);
      }
    }

    // dirIndex - build directory tree
    if (labels[0] === 'Directory') {
      const dirPath = normalizePath(props.path as string || props.name as string || '');
      if (!dirIndex.has(dirPath)) {
        dirIndex.set(dirPath, []);
      }
    }

    // Initialize adjacency lists for functions and files
    if (labels[0] === 'Function') {
      callAdj.set(id, { out: [], in: [] });
    }
    if (labels[0] === 'File' || labels[0] === 'LocalModule' || labels[0] === 'ExternalModule') {
      importAdj.set(id, { out: [], in: [] });
    }

    // domainIndex
    if (labels[0] === 'Domain' || labels[0] === 'Subdomain') {
      domainIndex.set(name || id, { memberIds: [], relationships: [] });
    }
  }

  // Build relationship indexes
  for (const rel of relationships) {
    const { type, startNode, endNode } = rel;

    // Call adjacency
    if (type === 'calls') {
      if (callAdj.has(startNode)) {
        callAdj.get(startNode)!.out.push(endNode);
      }
      if (callAdj.has(endNode)) {
        callAdj.get(endNode)!.in.push(startNode);
      }
    }

    // Import adjacency
    if (type === 'IMPORTS') {
      // Some graphs emit IMPORTS edges from non-File nodes (e.g. Function -> Module).
      // Create adjacency lazily for any node that participates.
      let startAdj = importAdj.get(startNode);
      if (!startAdj) {
        startAdj = { out: [], in: [] };
        importAdj.set(startNode, startAdj);
      }
      startAdj.out.push(endNode);

      let endAdj = importAdj.get(endNode);
      if (!endAdj) {
        endAdj = { out: [], in: [] };
        importAdj.set(endNode, endAdj);
      }
      endAdj.in.push(startNode);
    }

    // Directory contains
    if (type === 'CONTAINS_FILE' || type === 'CHILD_DIRECTORY') {
      const startNode_ = nodeById.get(startNode);
      if (startNode_ && startNode_.labels?.[0] === 'Directory') {
        const dirPath = normalizePath(startNode_.properties?.path as string || startNode_.properties?.name as string || '');
        if (dirIndex.has(dirPath)) {
          dirIndex.get(dirPath)!.push(endNode);
        }
      }
    }

    // Domain membership
    if (type === 'belongsTo') {
      const targetNode = nodeById.get(endNode);
      if (targetNode) {
        const domainName = targetNode.properties?.name as string;
        if (domainIndex.has(domainName)) {
          domainIndex.get(domainName)!.memberIds.push(startNode);
        }
      }
    }

    // Domain relationships
    const startNodeData = nodeById.get(startNode);
    const endNodeData = nodeById.get(endNode);
    if (startNodeData?.labels?.[0] === 'Domain' && endNodeData?.labels?.[0] === 'Domain') {
      const domainName = startNodeData.properties?.name as string;
      if (domainIndex.has(domainName)) {
        domainIndex.get(domainName)!.relationships.push(rel);
      }
    }
  }

  // Compute summary
  const summary = {
    filesProcessed: raw.summary?.filesProcessed || labelIndex.get('File')?.length || 0,
    classes: raw.summary?.classes || labelIndex.get('Class')?.length || 0,
    functions: raw.summary?.functions || labelIndex.get('Function')?.length || 0,
    types: raw.summary?.types || labelIndex.get('Type')?.length || 0,
    domains: raw.summary?.domains || labelIndex.get('Domain')?.length || 0,
    primaryLanguage: raw.summary?.primaryLanguage || 'unknown',
    nodeCount: nodes.length,
    relationshipCount: relationships.length,
  };

  return {
    raw,
    nodeById,
    labelIndex,
    pathIndex,
    dirIndex,
    nameIndex,
    callAdj,
    importAdj,
    domainIndex,
    summary,
    cachedAt: new Date().toISOString(),
    cacheKey,
  };
}

Domain

Subdomains

Frequently Asked Questions

What does buildIndexes() do?
buildIndexes() is a function in the mcp codebase.
What does buildIndexes() call?
buildIndexes() calls 4 function(s): get, has, normalizePath, set.
What calls buildIndexes()?
buildIndexes() is called by 4 function(s): buildGraph, loadCacheFromDisk, precacheForDirectory, resolveOrFetchGraph.

Analyze Your Own Codebase

Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.

Try Supermodel Free