Chapter 3: Git Server

April 13, 2026 ยท View on GitHub

Welcome to Chapter 3: Git Server. In this part of MCP Servers Tutorial: Reference Implementations and Patterns, you will build an intuitive mental model first, then move into concrete implementation details and practical production tradeoffs.

The git server demonstrates a practical balance between read-heavy analysis and controlled mutation.

Core Tool Surface

The reference git server supports:

  • repository state checks (git_status, diffs, logs)
  • staging and commit operations
  • branch creation and checkout
  • commit inspection (git_show)

This mirrors common developer assistant workflows.

Safe Usage Strategy

Start with read-only operations:

  1. status
  2. unstaged/staged diff
  3. log and branch listing

Then enable mutating operations (git_add, git_commit, checkout/reset) only after adding explicit policy controls.

Mutation Guardrails

For production adaptation, add:

  • branch protections
  • commit message policy checks
  • allowlisted repo paths
  • signer identity and audit logging

Without these controls, an agent can perform valid git operations that still violate team policy.

Example Interaction Pattern

analyze changes -> propose patch -> stage selected files -> commit with structured message

Split reasoning and execution. Force explicit confirmation between analysis and mutation steps.

Common Failure Modes

FailureRoot CauseMitigation
Wrong repository targetedAmbiguous repo_pathResolve canonical path and verify allowlist
Overscoped stagingWildcard or broad file selectionEnforce explicit file list
Unsafe branch switchDirty working treeAdd pre-check and block on conflicts
Undocumented commit semanticsInconsistent agent behaviorStandardize commit message template

Summary

You can now treat git server operations as a controllable pipeline instead of ad-hoc commands.

Next: Chapter 4: Memory Server

What Problem Does This Solve?

Most teams struggle here because the hard part is not writing more code, but deciding clear boundaries for analyze, changes, propose so behavior stays predictable as complexity grows.

In practical terms, this chapter helps you avoid three common failures:

  • coupling core logic too tightly to one implementation path
  • missing the handoff boundaries between setup, execution, and validation
  • shipping changes without clear rollback or observability strategy

After working through this chapter, you should be able to reason about Chapter 3: Git Server as an operating subsystem inside MCP Servers Tutorial: Reference Implementations and Patterns, with explicit contracts for inputs, state transitions, and outputs.

Use the implementation notes around patch, stage, selected as your checklist when adapting these patterns to your own repository.

How it Works Under the Hood

Under the hood, Chapter 3: Git Server usually follows a repeatable control path:

  1. Context bootstrap: initialize runtime config and prerequisites for analyze.
  2. Input normalization: shape incoming data so changes receives stable contracts.
  3. Core execution: run the main logic branch and propagate intermediate state through propose.
  4. Policy and safety checks: enforce limits, auth scopes, and failure boundaries.
  5. Output composition: return canonical result payloads for downstream consumers.
  6. Operational telemetry: emit logs/metrics needed for debugging and performance tuning.

When debugging, walk this sequence in order and confirm each stage has explicit success/failure conditions.

Source Walkthrough

Use the following upstream sources to verify implementation details while reading this chapter:

Suggested trace strategy:

  • search upstream code for analyze and changes to map concrete implementation paths
  • compare docs claims against actual runtime/config code before reusing patterns in production

Chapter Connections

Source Code Walkthrough

src/filesystem/lib.ts

The search function in src/filesystem/lib.ts handles a key part of this chapter's functionality:

}

export async function searchFilesWithValidation(
  rootPath: string,
  pattern: string,
  allowedDirectories: string[],
  options: SearchOptions = {}
): Promise<string[]> {
  const { excludePatterns = [] } = options;
  const results: string[] = [];

  async function search(currentPath: string) {
    const entries = await fs.readdir(currentPath, { withFileTypes: true });

    for (const entry of entries) {
      const fullPath = path.join(currentPath, entry.name);

      try {
        await validatePath(fullPath);

        const relativePath = path.relative(rootPath, fullPath);
        const shouldExclude = excludePatterns.some(excludePattern =>
          minimatch(relativePath, excludePattern, { dot: true })
        );

        if (shouldExclude) continue;

        // Use glob matching for the search pattern
        if (minimatch(relativePath, pattern, { dot: true })) {
          results.push(fullPath);
        }

This function is important because it defines how MCP Servers Tutorial: Reference Implementations and Patterns implements the patterns covered in this chapter.

src/filesystem/lib.ts

The FileInfo interface in src/filesystem/lib.ts handles a key part of this chapter's functionality:


// Type definitions
interface FileInfo {
  size: number;
  created: Date;
  modified: Date;
  accessed: Date;
  isDirectory: boolean;
  isFile: boolean;
  permissions: string;
}

export interface SearchOptions {
  excludePatterns?: string[];
}

export interface SearchResult {
  path: string;
  isDirectory: boolean;
}

// Pure Utility Functions
export function formatSize(bytes: number): string {
  const units = ['B', 'KB', 'MB', 'GB', 'TB'];
  if (bytes === 0) return '0 B';
  
  const i = Math.floor(Math.log(bytes) / Math.log(1024));
  
  if (i < 0 || i === 0) return `${bytes} ${units[0]}`;
  
  const unitIndex = Math.min(i, units.length - 1);
  return `${(bytes / Math.pow(1024, unitIndex)).toFixed(2)} ${units[unitIndex]}`;

This interface is important because it defines how MCP Servers Tutorial: Reference Implementations and Patterns implements the patterns covered in this chapter.

src/filesystem/lib.ts

The SearchOptions interface in src/filesystem/lib.ts handles a key part of this chapter's functionality:

}

export interface SearchOptions {
  excludePatterns?: string[];
}

export interface SearchResult {
  path: string;
  isDirectory: boolean;
}

// Pure Utility Functions
export function formatSize(bytes: number): string {
  const units = ['B', 'KB', 'MB', 'GB', 'TB'];
  if (bytes === 0) return '0 B';
  
  const i = Math.floor(Math.log(bytes) / Math.log(1024));
  
  if (i < 0 || i === 0) return `${bytes} ${units[0]}`;
  
  const unitIndex = Math.min(i, units.length - 1);
  return `${(bytes / Math.pow(1024, unitIndex)).toFixed(2)} ${units[unitIndex]}`;
}

export function normalizeLineEndings(text: string): string {
  return text.replace(/\r\n/g, '\n');
}

export function createUnifiedDiff(originalContent: string, newContent: string, filepath: string = 'file'): string {
  // Ensure consistent line endings for diff
  const normalizedOriginal = normalizeLineEndings(originalContent);
  const normalizedNew = normalizeLineEndings(newContent);

This interface is important because it defines how MCP Servers Tutorial: Reference Implementations and Patterns implements the patterns covered in this chapter.

src/filesystem/lib.ts

The SearchResult interface in src/filesystem/lib.ts handles a key part of this chapter's functionality:

}

export interface SearchResult {
  path: string;
  isDirectory: boolean;
}

// Pure Utility Functions
export function formatSize(bytes: number): string {
  const units = ['B', 'KB', 'MB', 'GB', 'TB'];
  if (bytes === 0) return '0 B';
  
  const i = Math.floor(Math.log(bytes) / Math.log(1024));
  
  if (i < 0 || i === 0) return `${bytes} ${units[0]}`;
  
  const unitIndex = Math.min(i, units.length - 1);
  return `${(bytes / Math.pow(1024, unitIndex)).toFixed(2)} ${units[unitIndex]}`;
}

export function normalizeLineEndings(text: string): string {
  return text.replace(/\r\n/g, '\n');
}

export function createUnifiedDiff(originalContent: string, newContent: string, filepath: string = 'file'): string {
  // Ensure consistent line endings for diff
  const normalizedOriginal = normalizeLineEndings(originalContent);
  const normalizedNew = normalizeLineEndings(newContent);

  return createTwoFilesPatch(
    filepath,
    filepath,

This interface is important because it defines how MCP Servers Tutorial: Reference Implementations and Patterns implements the patterns covered in this chapter.

How These Components Connect

flowchart TD
    A[search]
    B[FileInfo]
    C[SearchOptions]
    D[SearchResult]
    E[FileEdit]
    A --> B
    B --> C
    C --> D
    D --> E