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.