Skip to content

Code Navigation Examples

Navigate and analyze large codebases efficiently with Large File MCP Server.

Overview

Large codebases can be challenging to navigate, especially when files contain thousands of lines. This guide shows practical patterns for code exploration, refactoring, and analysis.

Basic Navigation

Jump to Function Definition

Navigate to specific function with context:

typescript
// Step 1: Find function definition
const results = await search_in_large_file({
  filePath: "/code/app.ts",
  pattern: "^export (async )?function processData",
  regex: true,
  contextAfter: 10
});

// Step 2: Navigate to definition for full view
const functionDef = await navigate_to_line({
  filePath: "/code/app.ts",
  lineNumber: results.matches[0].lineNumber,
  contextLines: 30
});

console.log("Function definition:");
console.log(functionDef.content);
console.log("\nFunction body:");
console.log(functionDef.contextAfter.join("\n"));

Find All Function Definitions

List all functions in a file:

typescript
async function listFunctions(codeFile: string) {
  const functions = await search_in_large_file({
    filePath: codeFile,
    pattern: "^(export\\s+)?(async\\s+)?function\\s+(\\w+)",
    regex: true,
    contextAfter: 3
  });

  console.log(`Found ${functions.totalMatches} functions:\n`);

  functions.matches.forEach(match => {
    // Extract function name
    const nameMatch = match.line.match(/function\s+(\w+)/);
    const name = nameMatch ? nameMatch[1] : "unknown";

    console.log(`${name} (line ${match.lineNumber})`);
    console.log(`  ${match.line}`);
    console.log();
  });
}

await listFunctions("/code/server.ts");

Find Class Definitions

Locate and analyze classes:

typescript
async function analyzeClasses(codeFile: string) {
  const classes = await search_in_large_file({
    filePath: codeFile,
    pattern: "^(export\\s+)?(abstract\\s+)?class\\s+(\\w+)",
    regex: true,
    contextAfter: 20
  });

  console.log(`Found ${classes.totalMatches} classes:\n`);

  for (const match of classes.matches) {
    const nameMatch = match.line.match(/class\s+(\w+)/);
    const className = nameMatch ? nameMatch[1] : "unknown";

    // Find methods in class
    const methods = match.contextAfter.filter(line =>
      /^\s+(public|private|protected)?\s*(async\s+)?\w+\s*\(/.test(line)
    );

    console.log(`Class: ${className} (line ${match.lineNumber})`);
    console.log(`Methods: ${methods.length}`);
    methods.forEach(method => {
      console.log(`  - ${method.trim()}`);
    });
    console.log();
  }
}

await analyzeClasses("/code/services.ts");

Code Analysis

Find TODO Comments

Track technical debt and pending work:

typescript
async function findTodos(directory: string) {
  const files = await glob("**/*.ts", { cwd: directory });

  const todos: Array<{
    file: string;
    line: number;
    content: string;
    priority: string;
  }> = [];

  for (const file of files) {
    const results = await search_in_large_file({
      filePath: path.join(directory, file),
      pattern: "//\\s*TODO|//\\s*FIXME|//\\s*HACK",
      regex: true,
      contextAfter: 2
    });

    results.matches.forEach(match => {
      const priority = match.line.includes("FIXME")
        ? "HIGH"
        : match.line.includes("HACK")
        ? "MEDIUM"
        : "LOW";

      todos.push({
        file,
        line: match.lineNumber,
        content: match.line.trim(),
        priority
      });
    });
  }

  // Group by priority
  console.log("=== TODO Items ===\n");
  ["HIGH", "MEDIUM", "LOW"].forEach(priority => {
    const items = todos.filter(t => t.priority === priority);
    if (items.length > 0) {
      console.log(`${priority} (${items.length}):`);
      items.forEach(item => {
        console.log(`  ${item.file}:${item.line}`);
        console.log(`    ${item.content}`);
      });
      console.log();
    }
  });
}

await findTodos("/code/src");

Analyze Import Dependencies

Map file dependencies:

typescript
async function analyzeDependencies(codeFile: string) {
  const imports = await search_in_large_file({
    filePath: codeFile,
    pattern: "^import.*from\\s+['\"](.+)['\"]",
    regex: true
  });

  const dependencies = {
    npm: new Set<string>(),
    local: new Set<string>()
  };

  imports.matches.forEach(match => {
    const pathMatch = match.line.match(/from\s+['"](.+)['"]/);
    if (pathMatch) {
      const importPath = pathMatch[1];
      if (importPath.startsWith(".")) {
        dependencies.local.add(importPath);
      } else {
        dependencies.npm.add(importPath);
      }
    }
  });

  console.log("=== Dependencies ===\n");
  console.log(`NPM packages (${dependencies.npm.size}):`);
  Array.from(dependencies.npm)
    .sort()
    .forEach(pkg => console.log(`  - ${pkg}`));

  console.log(`\nLocal imports (${dependencies.local.size}):`);
  Array.from(dependencies.local)
    .sort()
    .forEach(file => console.log(`  - ${file}`));
}

await analyzeDependencies("/code/app.ts");

Find Unused Exports

Detect potentially unused code:

typescript
async function findUnusedExports(directory: string) {
  const files = await glob("**/*.ts", { cwd: directory });

  // Step 1: Find all exports
  const exports = new Map<string, Set<string>>();

  for (const file of files) {
    const results = await search_in_large_file({
      filePath: path.join(directory, file),
      pattern: "^export\\s+(const|function|class|interface)\\s+(\\w+)",
      regex: true
    });

    const fileExports = new Set<string>();
    results.matches.forEach(match => {
      const nameMatch = match.line.match(/\s+(\w+)/g);
      if (nameMatch && nameMatch[1]) {
        fileExports.add(nameMatch[1].trim());
      }
    });

    exports.set(file, fileExports);
  }

  // Step 2: Find imports
  const imported = new Set<string>();

  for (const file of files) {
    const results = await search_in_large_file({
      filePath: path.join(directory, file),
      pattern: "import\\s+\\{([^}]+)\\}",
      regex: true
    });

    results.matches.forEach(match => {
      const namesMatch = match.line.match(/\{([^}]+)\}/);
      if (namesMatch) {
        const names = namesMatch[1].split(",").map(n => n.trim());
        names.forEach(name => imported.add(name));
      }
    });
  }

  // Step 3: Find unused
  console.log("=== Potentially Unused Exports ===\n");

  for (const [file, fileExports] of exports) {
    const unused = Array.from(fileExports).filter(
      exp => !imported.has(exp)
    );

    if (unused.length > 0) {
      console.log(`${file}:`);
      unused.forEach(name => console.log(`  - ${name}`));
      console.log();
    }
  }
}

await findUnusedExports("/code/src");

Refactoring Support

Find and Replace Pattern

Preview changes before applying:

typescript
async function findAndReplace(
  codeFile: string,
  pattern: string,
  replacement: string
) {
  const matches = await search_in_large_file({
    filePath: codeFile,
    pattern,
    regex: true,
    contextBefore: 2,
    contextAfter: 2
  });

  console.log(`Found ${matches.totalMatches} occurrences:\n`);

  matches.matches.forEach(match => {
    console.log(`Line ${match.lineNumber}:`);
    console.log("Before:");
    console.log(match.contextBefore.join("\n"));
    console.log(`> ${match.line}`);
    console.log(match.contextAfter.join("\n"));

    console.log("\nAfter:");
    const replaced = match.line.replace(new RegExp(pattern), replacement);
    console.log(match.contextBefore.join("\n"));
    console.log(`> ${replaced}`);
    console.log(match.contextAfter.join("\n"));
    console.log("\n---\n");
  });

  console.log(`Total changes: ${matches.totalMatches}`);
}

await findAndReplace(
  "/code/app.ts",
  "var\\s+(\\w+)",
  "const $1"
);

Extract Function Candidates

Find code duplication for refactoring:

typescript
async function findDuplication(codeFile: string, minLines: number = 5) {
  const structure = await get_file_structure({
    filePath: codeFile
  });

  const lineHashes = new Map<string, number[]>();

  // Read file and hash line sequences
  const stream = stream_large_file({
    filePath: codeFile,
    chunkSize: 100
  });

  let currentLine = 0;

  for await (const chunk of stream) {
    for (const line of chunk.lines) {
      currentLine++;

      // Skip empty lines and comments
      const trimmed = line.trim();
      if (!trimmed || trimmed.startsWith("//")) continue;

      // Create hash of normalized line
      const normalized = trimmed.replace(/\s+/g, " ");

      if (!lineHashes.has(normalized)) {
        lineHashes.set(normalized, []);
      }
      lineHashes.get(normalized)!.push(currentLine);
    }
  }

  // Find duplicated sequences
  console.log("=== Potential Duplication ===\n");

  for (const [line, occurrences] of lineHashes) {
    if (occurrences.length >= 3) {
      console.log(`Line appears ${occurrences.length} times:`);
      console.log(`"${line}"`);
      console.log(`At lines: ${occurrences.join(", ")}`);
      console.log();
    }
  }
}

await findDuplication("/code/utils.ts");

Code Quality Checks

Find Long Functions

Identify functions that may need refactoring:

typescript
async function findLongFunctions(codeFile: string, maxLines: number = 50) {
  // Find all function starts
  const functions = await search_in_large_file({
    filePath: codeFile,
    pattern: "^\\s*(export\\s+)?(async\\s+)?function\\s+(\\w+)",
    regex: true,
    contextAfter: maxLines + 10
  });

  const longFunctions: Array<{
    name: string;
    line: number;
    estimatedLines: number;
  }> = [];

  functions.matches.forEach(match => {
    const nameMatch = match.line.match(/function\s+(\w+)/);
    const name = nameMatch ? nameMatch[1] : "unknown";

    // Estimate function length by finding closing brace
    let braceCount = 0;
    let lineCount = 0;
    let foundOpening = false;

    for (const line of [match.line, ...match.contextAfter]) {
      if (line.includes("{")) {
        braceCount++;
        foundOpening = true;
      }
      if (line.includes("}")) {
        braceCount--;
      }

      if (foundOpening) {
        lineCount++;
      }

      if (braceCount === 0 && foundOpening) {
        break;
      }
    }

    if (lineCount > maxLines) {
      longFunctions.push({
        name,
        line: match.lineNumber,
        estimatedLines: lineCount
      });
    }
  });

  console.log(`=== Long Functions (> ${maxLines} lines) ===\n`);
  longFunctions
    .sort((a, b) => b.estimatedLines - a.estimatedLines)
    .forEach(func => {
      console.log(`${func.name} (line ${func.line}): ~${func.estimatedLines} lines`);
    });
}

await findLongFunctions("/code/server.ts");

Find Complex Conditions

Identify complex if statements:

typescript
async function findComplexConditions(codeFile: string) {
  const conditions = await search_in_large_file({
    filePath: codeFile,
    pattern: "if\\s*\\([^)]*&&[^)]*&&",
    regex: true,
    contextBefore: 2,
    contextAfter: 3
  });

  console.log(`Found ${conditions.totalMatches} complex conditions:\n`);

  conditions.matches.forEach(match => {
    console.log(`Line ${match.lineNumber}:`);
    console.log(match.line);

    // Count conditions
    const conditionCount = (match.line.match(/&&/g) || []).length + 1;
    console.log(`Conditions: ${conditionCount}`);

    if (conditionCount > 3) {
      console.log("⚠ Consider extracting to helper function");
    }
    console.log();
  });
}

await findComplexConditions("/code/validation.ts");

Check Error Handling

Verify try-catch coverage:

typescript
async function analyzeErrorHandling(codeFile: string) {
  // Find async functions
  const asyncFunctions = await search_in_large_file({
    filePath: codeFile,
    pattern: "async\\s+function\\s+(\\w+)",
    regex: true,
    contextAfter: 30
  });

  console.log("=== Error Handling Analysis ===\n");

  asyncFunctions.matches.forEach(match => {
    const nameMatch = match.line.match(/function\s+(\w+)/);
    const name = nameMatch ? nameMatch[1] : "unknown";

    const hasTryCatch = match.contextAfter.some(line =>
      line.includes("try {") || line.includes("catch")
    );

    const hasErrorCheck = match.contextAfter.some(line =>
      line.includes(".catch(") || line.includes("if (error")
    );

    console.log(`${name} (line ${match.lineNumber}):`);

    if (hasTryCatch || hasErrorCheck) {
      console.log("  ✓ Has error handling");
    } else {
      console.log("  ⚠ Missing error handling");
    }
    console.log();
  });
}

await analyzeErrorHandling("/code/api.ts");

Documentation

Generate Function Signatures

Extract function signatures for documentation:

typescript
async function generateSignatures(codeFile: string) {
  const functions = await search_in_large_file({
    filePath: codeFile,
    pattern: "^export\\s+(async\\s+)?function\\s+\\w+.*\\{",
    regex: true,
    contextBefore: 5
  });

  console.log("# API Reference\n");

  functions.matches.forEach(match => {
    // Extract JSDoc comment if exists
    const jsdoc = match.contextBefore
      .filter(line => line.trim().startsWith("*"))
      .map(line => line.trim())
      .join("\n");

    // Extract signature
    const signature = match.line.replace("{", "").trim();

    console.log("## " + signature);
    if (jsdoc) {
      console.log("\n" + jsdoc);
    }
    console.log();
  });
}

await generateSignatures("/code/api.ts");

Best Practices

1. Use Regex for Precise Matching

typescript
// Good: Precise regex
const results = await search_in_large_file({
  filePath: codeFile,
  pattern: "^export\\s+function\\s+(\\w+)",
  regex: true
});

// Bad: Loose string search
const results = await search_in_large_file({
  filePath: codeFile,
  pattern: "function",
  regex: false
});

2. Cache File Structure

typescript
const structureCache = new Map();

async function getCachedStructure(file: string) {
  if (!structureCache.has(file)) {
    structureCache.set(file, await get_file_structure({ filePath: file }));
  }
  return structureCache.get(file);
}

3. Combine Search and Navigate

typescript
// Step 1: Find
const results = await search_in_large_file({
  filePath: file,
  pattern: "class\\s+Database",
  regex: true
});

// Step 2: Navigate for full context
const fullContext = await navigate_to_line({
  filePath: file,
  lineNumber: results.matches[0].lineNumber,
  contextLines: 50
});

See Also

Released under the MIT License.