Home / Function/ buildIndexes() — mcp Function Reference

buildIndexes() — mcp Function Reference

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

Entity Profile

Dependency Diagram

graph TD
  2f679171_fd3f_3cd5_48b2_587cc9ec01fd["buildIndexes()"]
  f528cae6_71d3_4b84_026d_d4778648e9c8["loadCacheFromDisk()"]
  f528cae6_71d3_4b84_026d_d4778648e9c8 -->|calls| 2f679171_fd3f_3cd5_48b2_587cc9ec01fd
  b9fca090_95d0_4cf7_0bb0_7a7efcc55ccb["resolveOrFetchGraph()"]
  b9fca090_95d0_4cf7_0bb0_7a7efcc55ccb -->|calls| 2f679171_fd3f_3cd5_48b2_587cc9ec01fd
  966fdd0a_509a_01b0_865e_32cfde84f964["precacheForDirectory()"]
  966fdd0a_509a_01b0_865e_32cfde84f964 -->|calls| 2f679171_fd3f_3cd5_48b2_587cc9ec01fd
  4794a7fe_68a8_cd2a_1c48_0b495eb9c67b["buildGraph()"]
  4794a7fe_68a8_cd2a_1c48_0b495eb9c67b -->|calls| 2f679171_fd3f_3cd5_48b2_587cc9ec01fd
  b965d3cf_dacd_81fc_77e7_dbe9bdef8bbc["set()"]
  2f679171_fd3f_3cd5_48b2_587cc9ec01fd -->|calls| b965d3cf_dacd_81fc_77e7_dbe9bdef8bbc
  c652ed9f_2901_0635_2a5b_fc305e9cd6c1["has()"]
  2f679171_fd3f_3cd5_48b2_587cc9ec01fd -->|calls| c652ed9f_2901_0635_2a5b_fc305e9cd6c1
  55bde18a_7860_173e_f211_5874970475e3["get()"]
  2f679171_fd3f_3cd5_48b2_587cc9ec01fd -->|calls| 55bde18a_7860_173e_f211_5874970475e3
  d16dc47a_bbc0_2745_401a_8a4d3b67257e["normalizePath()"]
  2f679171_fd3f_3cd5_48b2_587cc9ec01fd -->|calls| d16dc47a_bbc0_2745_401a_8a4d3b67257e
  style 2f679171_fd3f_3cd5_48b2_587cc9ec01fd 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