npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

gitlab-auto-reviewers

v2.1.0

Published

Shared library for GitLab auto-reviewer suggestions with MCP server, CLI, and library modes

Readme

GitLab Auto Reviewers

A shared library for intelligent GitLab merge request reviewer suggestions. Provides MCP server, CLI, and library modes for analyzing git blame data, team member availability with FTE-aware load balancing, CODEOWNERS rules, and current reviewer workload to suggest the most appropriate reviewers.

Table of Contents

Installation

Install the package from npm:

npm install gitlab-auto-reviewers

Quick Start

The package supports three execution modes:

MCP Server Mode

Run as an MCP server for AI assistants:

# MCP Server mode
npx gitlab-auto-reviewers mcp

# Or using the deprecated command (backward compatibility)
npx auto-reviewers-mcp-server

Or add it to your MCP configuration (see MCP Integration section below).

CLI Mode

Use the command-line interface for posting reviewer suggestions:

# Posts reviewer suggestions as comments (default behavior)
npx gitlab-auto-reviewers cli --project my-group/my-project --mr 123

# Analysis only (use --dry-run for testing)
npx gitlab-auto-reviewers cli --project my-group/my-project --mr 123 --dry-run

# Post suggestions for a branch
npx gitlab-auto-reviewers cli --project my-group/my-project --branch feature/new-feature

# JSON output for automation (still posts comments)
npx gitlab-auto-reviewers cli --project my-group/my-project --mr 123 --format json

# Use local git repository (faster analysis)
npx gitlab-auto-reviewers cli --repo-path /path/to/repo --mr 123

See CLI Usage section and Migration Guide for detailed documentation.

Library Mode

Import and use as a library in your Node.js application:

import { ReviewerService, GitLabAPIDataSource } from 'gitlab-auto-reviewers';

const dataSource = new GitLabAPIDataSource(gitlabToken, gitlabUrl);
const service = new ReviewerService(dataSource);

const suggestions = await service.suggestReviewers({
  project: 'my-group/my-project',
  mergeRequestIid: 123
});

See Library Usage section for detailed documentation.

What's New in v2.0

Version 2.0 brings significant improvements to reliability, performance, and developer experience:

🚀 Performance Improvements

  • In-memory caching with configurable TTL (default 5 minutes)
  • Parallel data fetching for independent operations
  • Automatic retry logic with exponential backoff
  • Up to 5x faster response times with caching enabled

🛡️ Reliability Enhancements

  • Automatic retry for transient failures (network errors, rate limits)
  • Smart error classification (retryable vs. permanent)
  • Graceful degradation with partial results on partial failures
  • Configuration validation on startup with clear error messages

🔍 Developer Experience

  • Full TypeScript strict mode with zero any types
  • Structured logging with DEBUG, INFO, WARN, ERROR levels
  • Performance metrics tracking for all operations
  • Enhanced error messages with context and suggestions
  • Comprehensive documentation including migration and troubleshooting guides

📊 Observability

  • Cache statistics (hit rate, size, performance)
  • Operation timing for performance monitoring
  • Debug mode with detailed diagnostic information
  • Contextual logging for easier troubleshooting

🔧 Configuration

  • Centralized configuration management
  • Environment variable support with validation
  • Default values with logging
  • Multiple configuration profiles (development, production, etc.)

💬 CLI Enhancement (Breaking Change)

  • Comment posting by default - CLI now posts reviewer suggestions as comments
  • Dry-run mode with --dry-run flag for analysis-only
  • Cross-interface consistency - CLI behavior matches MCP server
  • Enhanced help system with actionable error messages
  • Migration guide for upgrading from v1.x

See MIGRATION.md and CLI Migration Guide for detailed upgrade instructions.

Features

Core Functionality

  • Intelligent Reviewer Suggestions: Automatically suggest reviewers based on multiple factors

    • Git blame analysis of changed files to find previous contributors
    • Team member availability with FTE-aware load balancing
    • Code ownership rules from CODEOWNERS file
    • Current reviewer workload across open merge requests
  • Dual Data Source Support: Works with both GitLab API and local git repositories

    • API Mode: Fetches data from GitLab API (requires network access)
    • Local Git Mode: Analyzes local repository (faster, works offline)

Performance & Reliability (New in v2.0)

  • In-Memory Caching: Configurable caching with TTL support

    • Reduces API calls and improves response times
    • Automatic cache invalidation
    • Cache statistics tracking
  • Automatic Retry Logic: Resilient error handling

    • Exponential backoff for transient failures
    • Configurable retry attempts and delays
    • Smart classification of retryable vs. permanent errors
  • Parallel Operations: Concurrent data fetching

    • Multiple API requests in parallel
    • Configurable concurrency limits
    • Significantly faster response times

Developer Experience (New in v2.0)

  • Type Safety: Full TypeScript strict mode

    • Zero any types in production code
    • Comprehensive type definitions
    • Type guards for runtime validation
  • Structured Logging: Multi-level logging system

    • DEBUG, INFO, WARN, ERROR levels
    • Contextual information in all logs
    • Performance metrics tracking
    • Easy debugging and monitoring
  • Configuration Management: Centralized configuration

    • Environment variable support
    • Validation on startup with clear error messages
    • Default values with logging
    • Runtime configuration access
  • Enhanced Error Messages: Clear, actionable errors

    • Error codes for programmatic handling
    • Detailed context and suggestions
    • Stack traces in debug mode

Architecture

System Overview

┌─────────────────────────────────────────────────────────────────┐
│                     gitlab-auto-reviewers                        │
│                      (npm package)                               │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  ┌────────────────┐  ┌────────────────┐  ┌────────────────┐   │
│  │  MCP Server    │  │      CLI       │  │ Shared Library │   │
│  │   (bin/mcp)    │  │   (bin/cli)    │  │   (exports)    │   │
│  └────────┬───────┘  └────────┬───────┘  └────────┬───────┘   │
│           │                   │                    │            │
│           └───────────────────┴────────────────────┘            │
│                              │                                   │
│  ┌───────────────────────────┴──────────────────────────────┐  │
│  │              Core Services & Data Sources                 │  │
│  ├───────────────────────────────────────────────────────────┤  │
│  │  • ReviewerService                                        │  │
│  │  • ContributorsService                                    │  │
│  │  • CodeownersService                                      │  │
│  │  • TeamMembersService                                     │  │
│  │  • CommentBuilderService                                  │  │
│  ├───────────────────────────────────────────────────────────┤  │
│  │  Data Sources:                                            │  │
│  │  • GitLabAPIDataSource (API-based, stateless)            │  │
│  │  • LocalGitDataSource (local repo, faster)               │  │
│  └───────────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────────┘
                              │
                              │ imported by
                              ↓
┌─────────────────────────────────────────────────────────────────┐
│                    oce-gitlab-mr-bot                             │
│                   (NestJS Application)                           │
├─────────────────────────────────────────────────────────────────┤
│  ┌────────────────────────────────────────────────────────┐    │
│  │  B2B-MFE Webhook Module                                │    │
│  │  • Controller (receives GitLab webhook events)         │    │
│  │  • Service (uses gitlab-auto-reviewers library)        │    │
│  │  • Type Guards (validates webhook payloads)            │    │
│  └────────────────────────────────────────────────────────┘    │
└─────────────────────────────────────────────────────────────────┘

Component Responsibilities

  • MCP Server: Handles MCP protocol communication and tool routing
  • Config Service: Centralized configuration management with validation
  • Logger Service: Structured logging with appropriate log levels
  • Error Handler: Consistent error handling with retry logic
  • Cache Service: Optional in-memory caching for performance
  • Reviewer Service: Core business logic for reviewer suggestions
  • Data Sources: Abstract data access (API or local git)

Configuration

The server can be configured through environment variables or tool parameters.

Environment Variables

| Variable | Description | Default | Required | |----------|-------------|---------|----------| | GITLAB_TOKEN | GitLab API token | - | Yes* | | GITLAB_URL | GitLab instance URL | https://gitlab.com | No | | REPO_PATH | Local repository path | Auto-detected | No | | CACHE_ENABLED | Enable in-memory caching | true | No | | CACHE_TTL | Cache TTL in milliseconds | 300000 (5 min) | No | | MAX_PARALLEL_REQUESTS | Max parallel API requests | 5 | No | | CONTRIBUTOR_DAYS | Days to analyze for contributors | 352 | No | | MAX_RETRIES | Max retry attempts for failures | 3 | No | | RETRY_DELAY_MS | Initial retry delay in ms | 1000 | No | | LOG_LEVEL | Logging level | info | No | | DEBUG | Enable debug mode | false | No |

*Can be provided as tool parameter instead

Configuration File

Create a .env file in your project root:

# GitLab Configuration
GITLAB_TOKEN=your_gitlab_token_here
GITLAB_URL=https://gitlab.com

# Performance Configuration
CACHE_ENABLED=true
CACHE_TTL=300000
MAX_PARALLEL_REQUESTS=5

# Git Configuration
CONTRIBUTOR_DAYS=352
MAX_RETRIES=3
RETRY_DELAY_MS=1000

# Logging Configuration
LOG_LEVEL=info
DEBUG=false

Configuration Examples

High Performance Setup

# Optimized for speed with aggressive caching
CACHE_ENABLED=true
CACHE_TTL=600000              # 10 minutes
MAX_PARALLEL_REQUESTS=10      # More concurrent requests
CONTRIBUTOR_DAYS=90           # Shorter analysis window
MAX_RETRIES=2                 # Fewer retries

Development Setup

# Optimized for debugging
CACHE_ENABLED=false           # Disable cache for fresh data
LOG_LEVEL=debug               # Detailed logging
DEBUG=true                    # Enable debug mode
MAX_RETRIES=1                 # Fail fast

Production Setup

# Balanced for reliability and performance
CACHE_ENABLED=true
CACHE_TTL=300000              # 5 minutes
MAX_PARALLEL_REQUESTS=5       # Moderate concurrency
CONTRIBUTOR_DAYS=352          # Empirically optimized analysis
MAX_RETRIES=3                 # Standard retries
LOG_LEVEL=info                # Normal logging
DEBUG=false                   # Disable debug mode

Offline/Local Git Setup

# Use local git repository (no API calls)
REPO_PATH=/path/to/repo       # Local repository path
CACHE_ENABLED=true            # Cache git operations
CONTRIBUTOR_DAYS=180          # Moderate analysis window
LOG_LEVEL=info

Low Memory Setup

# Minimize memory usage
CACHE_ENABLED=false           # Disable caching
MAX_PARALLEL_REQUESTS=2       # Reduce concurrency
CONTRIBUTOR_DAYS=90           # Shorter analysis

Configuration Validation

The server validates all configuration on startup and will fail fast with clear error messages if:

  • Required values are missing
  • Values are invalid (e.g., negative numbers, invalid URLs)
  • Values are out of acceptable ranges

Example error message:

Configuration validation failed:
  - GITLAB_URL is not a valid URL: not-a-url
  - CACHE_TTL must be non-negative, got: -1000
  - MAX_PARALLEL_REQUESTS must be at least 1, got: 0

Please check your environment variables and try again.

Tools

The MCP server exposes the following tools for AI assistants:

suggest_reviewers

Suggests reviewers for a GitLab merge request based on multiple factors.

Analysis Factors:

  • Git blame analysis of changed files to find previous contributors
  • Team member availability with FTE-aware load balancing
  • Code ownership rules from CODEOWNERS file
  • Current reviewer workload across open merge requests

Parameters:

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | project | string | number | No* | GitLab project ID or path (e.g., "group/project" or 123) | | mergeRequestIid | number | No* | Merge request internal ID (IID) | | branch | string | No* | Branch name (alternative to mergeRequestIid) | | gitlabToken | string | No** | GitLab API token | | gitlabUrl | string | No | GitLab instance URL (defaults to https://gitlab.com) | | repoPath | string | No | Local repository path (auto-detected if not provided) |

*Either mergeRequestIid or branch must be provided
**Required if not set in environment variable GITLAB_TOKEN

Returns:

{
  contributors: ReviewerSuggestion[],  // Reviewers based on file contributions
  teamMembers: ReviewerSuggestion[],   // Reviewers based on team membership
  codeOwners: ReviewerSuggestion[],    // Reviewers based on CODEOWNERS
  comment: string                       // Formatted comment for GitLab MR
}

Example:

{
  "project": "my-group/my-project",
  "mergeRequestIid": 123,
  "gitlabToken": "glpat-xxxxxxxxxxxx"
}

get_contributor_analysis

Provides detailed analysis of who contributed to the changed files using git blame.

Parameters:

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | project | string | number | Yes | GitLab project ID or path | | mergeRequestIid | number | Yes | Merge request internal ID | | gitlabToken | string | No* | GitLab API token | | gitlabUrl | string | No | GitLab instance URL |

*Required if not set in environment variable GITLAB_TOKEN

Returns:

{
  files: Array<{
    path: string,
    contributors: Array<{
      username: string,
      email: string,
      lineCount: number
    }>
  }>
}

Example:

{
  "project": 123,
  "mergeRequestIid": 456
}

get_reviewer_workload

Analyzes current workload of potential reviewers across open merge requests.

Parameters:

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | project | string | number | Yes | GitLab project ID or path | | gitlabToken | string | No* | GitLab API token | | gitlabUrl | string | No | GitLab instance URL |

*Required if not set in environment variable GITLAB_TOKEN

Returns:

{
  reviewers: Array<{
    username: string,
    openMRCount: number,
    fte?: number,
    capacity?: number,
    utilizationPercent?: number
  }>
}

Example:

{
  "project": "my-group/my-project"
}

post_comment

Posts a comment to a GitLab merge request.

Parameters:

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | project | string | number | No* | GitLab project ID or path | | mergeRequestIid | number | No* | Merge request internal ID | | branch | string | No* | Branch name (alternative to mergeRequestIid) | | comment | string | Yes | Comment text to post | | gitlabToken | string | No** | GitLab API token | | gitlabUrl | string | No | GitLab instance URL | | repoPath | string | No | Local repository path |

*Either mergeRequestIid or branch must be provided
**Required if not set in environment variable GITLAB_TOKEN

Example:

{
  "project": 123,
  "mergeRequestIid": 456,
  "comment": "Suggested reviewers: @alice, @bob"
}

invite_reviewers

Invites suggested reviewers to a GitLab merge request.

Parameters:

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | project | string | number | No* | GitLab project ID or path | | mergeRequestIid | number | No* | Merge request internal ID | | branch | string | No* | Branch name (alternative to mergeRequestIid) | | gitlabToken | string | No** | GitLab API token | | gitlabUrl | string | No | GitLab instance URL | | repoPath | string | No | Local repository path |

*Either mergeRequestIid or branch must be provided
**Required if not set in environment variable GITLAB_TOKEN

Example:

{
  "project": "my-group/my-project",
  "branch": "feature/new-feature"
}

CLI Usage

The CLI mode allows you to analyze merge requests from the command line, useful for development, CI/CD pipelines, and automation scripts.

For comprehensive CLI documentation, see docs/CLI.md.

Quick Start

# Analyze a merge request
npx gitlab-auto-reviewers cli --repo-path . --mr 123

# Analyze by branch name
npx gitlab-auto-reviewers cli --repo-path . --branch feature/my-feature

# Output as JSON
npx gitlab-auto-reviewers cli --repo-path . --mr 123 --format json

Basic Options

| Option | Description | Example | |--------|-------------|---------| | --repo-path <path> | Path to local git repository | --repo-path . | | --mr <number> | Merge request IID | --mr 123 | | --branch <name> | Branch name (alternative to --mr) | --branch feature/new-feature | | --format <type> | Output format: json or text | --format json | | --gitlab-token <token> | GitLab API token | --gitlab-token glpat-xxxx | | --gitlab-url <url> | GitLab instance URL | --gitlab-url https://gitlab.com | | --verbose | Enable verbose logging | --verbose | | --help | Show help message | --help |

Development Environment

# Set GitLab token
export GITLAB_TOKEN=glpat-xxxxxxxxxxxx

# Analyze current merge request
cd /path/to/your/project
gitlab-auto-reviewers cli --repo-path . --mr 123

# Enable verbose output for debugging
gitlab-auto-reviewers cli --repo-path . --mr 123 --verbose

CI/CD Integration

GitLab CI

suggest-reviewers:
  stage: review
  image: node:18
  script:
    - npx gitlab-auto-reviewers cli --repo-path $CI_PROJECT_DIR --mr $CI_MERGE_REQUEST_IID --format json > reviewers.json
  artifacts:
    paths:
      - reviewers.json
  only:
    - merge_requests

GitHub Actions

- name: Suggest Reviewers
  env:
    GITLAB_TOKEN: ${{ secrets.GITLAB_TOKEN }}
  run: |
    npx gitlab-auto-reviewers cli \
      --repo-path . \
      --mr ${{ github.event.pull_request.number }} \
      --format json

Output Formats

Text Format (Default):

Suggested Reviewers for MR !123

Contributors (based on file changes):
  • alice (85 points) - Contributed 45% of changed lines
  • bob (60 points) - Contributed 30% of changed lines

Code Owners:
  • charlie - Owner of /backend/

JSON Format:

{
  "contributors": [
    {
      "email": "[email protected]",
      "username": "alice",
      "score": 85,
      "reasons": ["Contributed 45% of changed lines"],
      "isCodeowner": false,
      "contributionCount": 12
    }
  ],
  "teamMembers": [...],
  "codeOwners": [...],
  "comment": "## Suggested Reviewers\n\n..."
}

Complete Documentation

For detailed CLI documentation including:

  • Complete command reference
  • Development environment usage patterns
  • CI/CD pipeline integration examples
  • Troubleshooting guide
  • Performance tips
  • Security considerations

See docs/CLI.md

Library Usage

Use gitlab-auto-reviewers as a library in your Node.js or TypeScript application.

Installation

npm install gitlab-auto-reviewers

Basic Usage

import { 
  ReviewerService, 
  GitLabAPIDataSource,
  LocalGitDataSource 
} from 'gitlab-auto-reviewers';

// Using GitLab API
const apiDataSource = new GitLabAPIDataSource(
  'glpat-xxxxxxxxxxxx',  // GitLab token
  'https://gitlab.com'    // GitLab URL
);

const service = new ReviewerService(apiDataSource);

const suggestions = await service.suggestReviewers({
  project: 'my-group/my-project',
  mergeRequestIid: 123
});

console.log(suggestions.contributors);
console.log(suggestions.teamMembers);
console.log(suggestions.codeOwners);
console.log(suggestions.comment);

Using Local Git Repository

import { ReviewerService, LocalGitDataSource } from 'gitlab-auto-reviewers';

// Using local git repository (faster, works offline)
const localDataSource = new LocalGitDataSource(
  '/path/to/repo',        // Repository path
  'glpat-xxxxxxxxxxxx',   // GitLab token (for API fallback)
  'https://gitlab.com'    // GitLab URL (for API fallback)
);

const service = new ReviewerService(localDataSource);

const suggestions = await service.suggestReviewers({
  project: 'my-group/my-project',
  mergeRequestIid: 123
});

Advanced Usage

Custom Configuration

import { 
  ReviewerService, 
  GitLabAPIDataSource,
  ConfigService 
} from 'gitlab-auto-reviewers';

// Custom configuration
const config = new ConfigService({
  cacheEnabled: true,
  cacheTTL: 600000,  // 10 minutes
  maxParallelRequests: 10,
  contributorDays: 180,
  maxRetries: 5,
  logLevel: 'debug'
});

const dataSource = new GitLabAPIDataSource(
  process.env.GITLAB_TOKEN!,
  process.env.GITLAB_URL,
  config
);

const service = new ReviewerService(dataSource, config);

Error Handling

import { 
  ReviewerService, 
  GitLabAPIDataSource,
  MCPError 
} from 'gitlab-auto-reviewers';

try {
  const suggestions = await service.suggestReviewers({
    project: 'my-group/my-project',
    mergeRequestIid: 123
  });
} catch (error) {
  if (error instanceof MCPError) {
    console.error(`Error [${error.code}]: ${error.message}`);
    console.error('Details:', error.details);
    
    if (error.retryable) {
      // Retry logic
      console.log('Error is retryable, attempting retry...');
    }
  } else {
    console.error('Unexpected error:', error);
  }
}

Filtering Reviewers

import { 
  ReviewerService, 
  GitLabAPIDataSource,
  BlacklistService,
  WhitelistService 
} from 'gitlab-auto-reviewers';

const dataSource = new GitLabAPIDataSource(token, url);
const service = new ReviewerService(dataSource);

// Apply blacklist
const blacklist = new BlacklistService(dataSource);
await blacklist.load(project);

// Apply whitelist
const whitelist = new WhitelistService(dataSource);
await whitelist.load(project);

const suggestions = await service.suggestReviewers({
  project: 'my-group/my-project',
  mergeRequestIid: 123,
  blacklist: blacklist.getBlacklist(),
  whitelist: whitelist.getWhitelist()
});

Posting Comments

import { 
  ReviewerService, 
  GitLabAPIDataSource,
  CommentBuilderService 
} from 'gitlab-auto-reviewers';

const dataSource = new GitLabAPIDataSource(token, url);
const service = new ReviewerService(dataSource);

const suggestions = await service.suggestReviewers({
  project: 'my-group/my-project',
  mergeRequestIid: 123
});

// Post comment to merge request
await dataSource.createNote(
  'my-group/my-project',
  123,
  suggestions.comment
);

TypeScript Types

import type {
  ReviewerSuggestion,
  ReviewerSuggestions,
  MergeRequest,
  User,
  GitDataSource,
  ConfigOptions
} from 'gitlab-auto-reviewers';

// ReviewerSuggestion
interface ReviewerSuggestion {
  email: string;
  username?: string;
  score: number;
  reasons: string[];
  isCodeowner: boolean;
  contributionCount?: number;
  fte?: number;
  openMRCount?: number;
}

// ReviewerSuggestions
interface ReviewerSuggestions {
  contributors: ReviewerSuggestion[];
  teamMembers: ReviewerSuggestion[];
  codeOwners: ReviewerSuggestion[];
  comment: string;
}

Data Source Comparison

See Data Source Comparison section for detailed comparison of GitLabAPIDataSource vs LocalGitDataSource.

Data Source Comparison

The package supports two data source implementations with different trade-offs:

GitLabAPIDataSource

Use when:

  • Running in a stateless environment (webhooks, serverless)
  • No local repository available
  • Need to analyze any project without cloning
  • Running in CI/CD without repository checkout

Advantages:

  • ✅ No local repository required
  • ✅ Works from anywhere with network access
  • ✅ Always up-to-date with GitLab
  • ✅ Stateless operation (no disk usage)
  • ✅ Can analyze any project with API access

Disadvantages:

  • ❌ Slower (network latency)
  • ❌ Subject to API rate limits
  • ❌ Requires network connectivity
  • ❌ May hit API limits for large merge requests
  • ❌ Higher API usage costs

Configuration:

import { GitLabAPIDataSource } from 'gitlab-auto-reviewers';

const dataSource = new GitLabAPIDataSource(
  'glpat-xxxxxxxxxxxx',  // GitLab token
  'https://gitlab.com'    // GitLab URL
);

Environment:

GITLAB_TOKEN=glpat-xxxxxxxxxxxx
GITLAB_URL=https://gitlab.com

LocalGitDataSource

Use when:

  • Running on developer machine with repository clone
  • Running in CI/CD with repository checkout
  • Need faster performance
  • Want to work offline
  • Analyzing large merge requests

Advantages:

  • ✅ Much faster (no network latency)
  • ✅ Works offline
  • ✅ No API rate limits for git operations
  • ✅ Can handle large merge requests
  • ✅ Lower API usage

Disadvantages:

  • ❌ Requires local repository clone
  • ❌ Requires disk space
  • ❌ Must keep repository up-to-date
  • ❌ Falls back to API for some operations
  • ❌ Requires git installed

Configuration:

import { LocalGitDataSource } from 'gitlab-auto-reviewers';

const dataSource = new LocalGitDataSource(
  '/path/to/repo',        // Repository path
  'glpat-xxxxxxxxxxxx',   // GitLab token (for API fallback)
  'https://gitlab.com'    // GitLab URL (for API fallback)
);

Environment:

REPO_PATH=/path/to/repo
GITLAB_TOKEN=glpat-xxxxxxxxxxxx  # For API fallback
GITLAB_URL=https://gitlab.com

Performance Comparison

| Operation | GitLabAPIDataSource | LocalGitDataSource | Speedup | |-----------|--------------------|--------------------|---------| | Get MR details | ~200ms | ~200ms | 1x (same) | | Get diffs | ~300ms | ~50ms | 6x faster | | Get blame (per file) | ~400ms | ~30ms | 13x faster | | Get file content | ~200ms | ~10ms | 20x faster | | Total (typical MR) | ~3-5s | ~500ms-1s | 3-5x faster |

Performance varies based on network latency, repository size, and number of changed files

Feature Comparison

| Feature | GitLabAPIDataSource | LocalGitDataSource | |---------|--------------------|--------------------| | Get merge request | ✅ API | ✅ API (fallback) | | Get diffs | ✅ API | ✅ Git command | | Get blame | ✅ API | ✅ Git command | | Get file content | ✅ API | ✅ Git command | | Get contributors | ✅ API | ✅ Git command | | Post comments | ✅ API | ✅ API (fallback) | | Get open MRs | ✅ API | ✅ API (fallback) | | Works offline | ❌ No | ✅ Yes (partial) | | Requires repository | ❌ No | ✅ Yes | | API rate limits | ⚠️ Subject to limits | ✅ Minimal API usage |

Choosing the Right Data Source

Use GitLabAPIDataSource for:

  • Webhook servers (oce-gitlab-mr-bot)
  • Serverless functions
  • Cloud-based CI/CD without repository
  • Multi-project analysis tools
  • When disk space is limited

Use LocalGitDataSource for:

  • MCP server on developer machine
  • CLI usage in development
  • CI/CD with repository checkout
  • Large merge request analysis
  • Offline development

Hybrid Approach:

LocalGitDataSource automatically falls back to API for operations that require it:

  • Posting comments
  • Getting open merge requests
  • Getting project metadata

This provides the best of both worlds: fast local operations with API fallback when needed.

Example: Webhook Server

// oce-gitlab-mr-bot webhook service
import { ReviewerService, GitLabAPIDataSource } from 'gitlab-auto-reviewers';

@Injectable()
export class B2BMfeAutoReviewersService {
  async processWebhook(event: MergeRequestEvent): Promise<void> {
    // Use API data source (no local repository)
    const dataSource = new GitLabAPIDataSource(
      this.configService.get('GITLAB_TOKEN'),
      this.configService.get('GITLAB_URL')
    );
    
    const service = new ReviewerService(dataSource);
    
    const suggestions = await service.suggestReviewers({
      project: event.project.id,
      mergeRequestIid: event.object_attributes.iid
    });
    
    // Post comment to MR
    await dataSource.createNote(
      event.project.id,
      event.object_attributes.iid,
      suggestions.comment
    );
  }
}

Example: CLI Tool

// CLI tool for local development
import { ReviewerService, LocalGitDataSource } from 'gitlab-auto-reviewers';

async function analyzeMR(mrIid: number): Promise<void> {
  // Use local git data source (faster)
  const dataSource = new LocalGitDataSource(
    process.cwd(),  // Current directory
    process.env.GITLAB_TOKEN,
    process.env.GITLAB_URL
  );
  
  const service = new ReviewerService(dataSource);
  
  const suggestions = await service.suggestReviewers({
    project: await dataSource.getProjectFromRemote(),
    mergeRequestIid: mrIid
  });
  
  console.log(suggestions.comment);
}

Webhook Integration

Integrate gitlab-auto-reviewers into your webhook server to automatically suggest reviewers when merge requests are created or updated.

NestJS Integration (oce-gitlab-mr-bot)

Step 1: Install Dependency

npm install gitlab-auto-reviewers

Step 2: Create Webhook Module

// src/libs/b2b-mfe-auto-reviewers/b2b-mfe-auto-reviewers.module.ts
import { Module } from '@nestjs/common';
import { B2BMfeAutoReviewersController } from './b2b-mfe-auto-reviewers.controller';
import { B2BMfeAutoReviewersService } from './b2b-mfe-auto-reviewers.service';

@Module({
  controllers: [B2BMfeAutoReviewersController],
  providers: [B2BMfeAutoReviewersService],
})
export class B2BMfeAutoReviewersModule {}

Step 3: Create Type Guards

// src/libs/b2b-mfe-auto-reviewers/b2b-mfe-auto-reviewers.type-guards.ts
import { z } from 'zod';

const MergeRequestEventSchema = z.object({
  object_kind: z.literal('merge_request'),
  event_type: z.literal('merge_request'),
  project: z.object({
    id: z.number(),
    path_with_namespace: z.string(),
  }),
  object_attributes: z.object({
    iid: z.number(),
    title: z.string(),
    source_branch: z.string(),
    target_branch: z.string(),
    action: z.enum(['open', 'update', 'reopen']),
  }),
});

export type MergeRequestEvent = z.infer<typeof MergeRequestEventSchema>;

export function isMergeRequestEvent(data: unknown): data is MergeRequestEvent {
  return MergeRequestEventSchema.safeParse(data).success;
}

Step 4: Create Service

// src/libs/b2b-mfe-auto-reviewers/b2b-mfe-auto-reviewers.service.ts
import { Injectable, Logger } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { 
  ReviewerService, 
  GitLabAPIDataSource,
  MCPError 
} from 'gitlab-auto-reviewers';
import { MergeRequestEvent } from './b2b-mfe-auto-reviewers.type-guards';

@Injectable()
export class B2BMfeAutoReviewersService {
  private readonly logger = new Logger(B2BMfeAutoReviewersService.name);

  constructor(private readonly configService: ConfigService) {}

  async processWebhook(event: MergeRequestEvent): Promise<void> {
    try {
      this.logger.log(
        `Processing MR webhook: ${event.project.path_with_namespace}!${event.object_attributes.iid}`
      );

      // Create data source
      const dataSource = new GitLabAPIDataSource(
        this.configService.get<string>('GITLAB_TOKEN')!,
        this.configService.get<string>('GITLAB_URL', 'https://gitlab.com')
      );

      // Create reviewer service
      const service = new ReviewerService(dataSource);

      // Get reviewer suggestions
      const suggestions = await service.suggestReviewers({
        project: event.project.id,
        mergeRequestIid: event.object_attributes.iid,
      });

      // Post comment to merge request
      await dataSource.createNote(
        event.project.id,
        event.object_attributes.iid,
        suggestions.comment
      );

      this.logger.log(
        `Posted reviewer suggestions to MR !${event.object_attributes.iid}`
      );
    } catch (error) {
      if (error instanceof MCPError) {
        this.logger.error(
          `Failed to process webhook [${error.code}]: ${error.message}`,
          error.details
        );
      } else {
        this.logger.error('Unexpected error processing webhook', error);
      }
      throw error;
    }
  }
}

Step 5: Create Controller

// src/libs/b2b-mfe-auto-reviewers/b2b-mfe-auto-reviewers.controller.ts
import { Controller, Post, Body, HttpCode, Logger } from '@nestjs/common';
import { B2BMfeAutoReviewersService } from './b2b-mfe-auto-reviewers.service';
import { isMergeRequestEvent } from './b2b-mfe-auto-reviewers.type-guards';

@Controller('webhooks/b2b-mfe-auto-reviewers')
export class B2BMfeAutoReviewersController {
  private readonly logger = new Logger(B2BMfeAutoReviewersController.name);

  constructor(
    private readonly service: B2BMfeAutoReviewersService
  ) {}

  @Post()
  @HttpCode(200)
  async handleWebhook(@Body() body: unknown): Promise<{ success: boolean }> {
    // Validate webhook event
    if (!isMergeRequestEvent(body)) {
      this.logger.warn('Invalid webhook event received');
      return { success: false };
    }

    // Only process open/update/reopen actions
    const action = body.object_attributes.action;
    if (!['open', 'update', 'reopen'].includes(action)) {
      this.logger.log(`Ignoring action: ${action}`);
      return { success: true };
    }

    // Process webhook
    await this.service.processWebhook(body);

    return { success: true };
  }
}

Step 6: Register Module

// src/app.module.ts
import { Module } from '@nestjs/common';
import { B2BMfeAutoReviewersModule } from './libs/b2b-mfe-auto-reviewers/b2b-mfe-auto-reviewers.module';

@Module({
  imports: [
    // ... other modules
    B2BMfeAutoReviewersModule,
  ],
})
export class AppModule {}

Step 7: Configure Environment

# .env
GITLAB_TOKEN=glpat-xxxxxxxxxxxx
GITLAB_URL=https://gitlab.com

Step 8: Configure GitLab Webhook

  1. Go to your GitLab project: Settings → Webhooks
  2. Add webhook URL: https://your-server.com/webhooks/b2b-mfe-auto-reviewers
  3. Select trigger: "Merge request events"
  4. Select actions: "Opened", "Updated", "Reopened"
  5. Save webhook

Express.js Integration

import express from 'express';
import { 
  ReviewerService, 
  GitLabAPIDataSource 
} from 'gitlab-auto-reviewers';

const app = express();
app.use(express.json());

app.post('/webhooks/auto-reviewers', async (req, res) => {
  try {
    const event = req.body;

    // Validate event
    if (event.object_kind !== 'merge_request') {
      return res.status(200).json({ success: false });
    }

    // Create data source
    const dataSource = new GitLabAPIDataSource(
      process.env.GITLAB_TOKEN!,
      process.env.GITLAB_URL
    );

    // Create service
    const service = new ReviewerService(dataSource);

    // Get suggestions
    const suggestions = await service.suggestReviewers({
      project: event.project.id,
      mergeRequestIid: event.object_attributes.iid,
    });

    // Post comment
    await dataSource.createNote(
      event.project.id,
      event.object_attributes.iid,
      suggestions.comment
    );

    res.status(200).json({ success: true });
  } catch (error) {
    console.error('Webhook error:', error);
    res.status(500).json({ success: false, error: error.message });
  }
});

app.listen(3000, () => {
  console.log('Webhook server listening on port 3000');
});

Webhook Configuration for New Repositories

To enable auto-reviewer suggestions for a new repository:

  1. Install Package (if using webhook server):

    npm install gitlab-auto-reviewers
  2. Configure Environment Variables:

    GITLAB_TOKEN=glpat-xxxxxxxxxxxx
    GITLAB_URL=https://gitlab.com
  3. Create Configuration Files (in repository root):

    CONTRIBUTORS (optional):

    {
      "contributors": [
        {
          "username": "alice",
          "email": "[email protected]",
          "teams": [
            { "name": "Backend", "fte": 1.0 },
            { "name": "API", "fte": 0.5 }
          ]
        }
      ]
    }

    CODEOWNERS (optional):

    # Backend team owns all backend code
    /backend/ @backend-team
    
    # API section requires 2 approvals
    [API][2] @api-lead
    /api/ @alice @bob
  4. Configure GitLab Webhook:

    • Go to: Project → Settings → Webhooks
    • URL: https://your-webhook-server.com/webhooks/auto-reviewers
    • Trigger: "Merge request events"
    • Actions: "Opened", "Updated", "Reopened"
    • Secret token: (optional, for security)
    • SSL verification: Enabled (recommended)
  5. Test Webhook:

    • Create a test merge request
    • Check webhook logs for successful delivery
    • Verify comment appears on merge request
  6. Monitor and Adjust:

    • Monitor webhook logs for errors
    • Adjust CONTRIBUTORS and CODEOWNERS as needed
    • Update team FTE values based on workload

Webhook Security

Verify Webhook Signature (recommended):

import crypto from 'crypto';

function verifyWebhookSignature(
  payload: string,
  signature: string,
  secret: string
): boolean {
  const hmac = crypto.createHmac('sha256', secret);
  const digest = hmac.update(payload).digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(digest)
  );
}

app.post('/webhooks/auto-reviewers', (req, res) => {
  const signature = req.headers['x-gitlab-token'];
  const payload = JSON.stringify(req.body);
  
  if (!verifyWebhookSignature(payload, signature, process.env.WEBHOOK_SECRET!)) {
    return res.status(401).json({ error: 'Invalid signature' });
  }
  
  // Process webhook...
});

IP Whitelist (optional):

const GITLAB_IPS = [
  '34.74.90.64/28',
  '34.74.226.0/24',
  // Add your GitLab instance IPs
];

function isGitLabIP(ip: string): boolean {
  // Check if IP is in whitelist
  return GITLAB_IPS.some(range => ipInRange(ip, range));
}

MCP Integration

To use this MCP server with an AI assistant, add it to your MCP configuration:

{
  "mcpServers": {
    "gitlab-auto-reviewers": {
      "command": "npx",
      "args": ["-y", "gitlab-auto-reviewers", "mcp"],
      "env": {
        "GITLAB_TOKEN": "your_token_here",
        "GITLAB_URL": "https://gitlab.com"
      }
    }
  }
}

For backward compatibility, the old command name is still supported:

{
  "mcpServers": {
    "auto-reviewers": {
      "command": "npx",
      "args": ["-y", "auto-reviewers-mcp-server"],
      "env": {
        "GITLAB_TOKEN": "your_token_here",
        "GITLAB_URL": "https://gitlab.com"
      }
    }
  }
}

Team Configuration

Create a CONTRIBUTORS file in your repository root with team and FTE data:

{
  "contributors": [
    {
      "username": "developer1",
      "email": "[email protected]",
      "teams": [
        { "name": "Backend", "fte": 1.0 },
        { "name": "API", "fte": 0.5 }
      ]
    }
  ]
}

Code Owners

Create a CODEOWNERS file in your repository root (or docs/CODEOWNERS or .gitlab/CODEOWNERS):

# Backend team owns all backend code
/backend/ @backend-team

# API section requires 2 approvals
[API][2] @api-lead
/api/ @developer1 @developer2

Troubleshooting

For comprehensive troubleshooting information, see TROUBLESHOOTING.md.

Quick Diagnostics

Run these commands to quickly identify issues:

# 1. Check Node.js version (must be 18+)
node --version

# 2. Check if server starts
npm start 2>&1 | head -20

# 3. Check environment variables
env | grep -E 'GITLAB|CACHE|LOG|DEBUG|REPO'

# 4. Test GitLab API access
curl -H "PRIVATE-TOKEN: $GITLAB_TOKEN" $GITLAB_URL/api/v4/user

# 5. Check git repository (if using local mode)
git status

Common Issues

Server Won't Start

# Check Node.js version (must be 18+)
node --version

# Verify environment variables
echo $GITLAB_TOKEN
cat .env

# Check for configuration errors
npm start 2>&1 | grep ERROR

No Reviewers Suggested

# Check git history
git log --follow path/to/file

# Verify configuration files
cat CONTRIBUTORS | jq .
cat CODEOWNERS

# Enable debug logging
DEBUG=true LOG_LEVEL=debug npm start

Performance Issues

# Enable caching
CACHE_ENABLED=true
CACHE_TTL=300000

# Use local git mode (faster)
REPO_PATH=/path/to/repo

# Monitor performance
DEBUG=true LOG_LEVEL=debug npm start 2>&1 | grep duration

Authentication Errors

# Test token
curl -H "PRIVATE-TOKEN: $GITLAB_TOKEN" $GITLAB_URL/api/v4/user

# Create new token with required scopes:
# - api OR read_api
# - read_repository

Debug Mode

Enable detailed logging:

DEBUG=true LOG_LEVEL=debug npm start

Debug logs include:

  • Configuration loading and validation
  • Cache hits and misses
  • API request/response details
  • Git command execution
  • Performance timing for all operations

Getting Help

If you encounter issues:

  1. Check Documentation:

  2. Enable Debug Mode: DEBUG=true LOG_LEVEL=debug npm start

  3. Report Issues: Open an issue with:

    • Error messages and stack traces
    • Configuration (redact sensitive tokens)
    • Steps to reproduce
    • Server version and environment
    • Debug logs

Development

Building from Source

# Clone repository
git clone ssh://git@code.[company-name].com:2222/frank.renfeng/state-of-merge-requests.git
cd state-of-merge-requests/gitlab-auto-reviewers

# Install dependencies
npm install

# Build
npm run build

# Run tests
npm test

# Run in development mode
npm run dev

Project Structure

mcp-server/
├── src/
│   ├── index.ts                 # Main entry point
│   ├── types.ts                 # TypeScript interfaces
│   ├── tools.ts                 # MCP tool definitions
│   ├── config/
│   │   └── config.service.ts    # Configuration management
│   ├── logging/
│   │   └── logger.service.ts    # Logging service
│   ├── errors/
│   │   └── error-handler.ts     # Error handling
│   ├── cache/
│   │   └── cache.service.ts     # Caching service
│   ├── datasources/
│   │   ├── git-data-source.interface.ts
│   │   ├── gitlab-api-data-source.ts
│   │   └── local-git-data-source.ts
│   └── services/
│       ├── reviewer-service.ts
│       ├── contributors.service.ts
│       ├── codeowners.service.ts
│       ├── team-members.service.ts
│       ├── blacklist.service.ts
│       ├── whitelist.service.ts
│       └── comment-builder.service.ts
├── dist/                        # Compiled output
├── tests/                       # Test files
└── package.json

Running Tests

# Run all tests
npm test

# Run tests in watch mode
npm run test:watch

# Run tests with coverage
npm run test:coverage

Code Style

The project uses:

  • TypeScript with strict mode enabled
  • ESLint for linting
  • Prettier for code formatting
# Lint code
npm run lint

# Format code
npm run format

# Type check
npm run type-check

Contributing

Contributions are welcome! Please:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Make your changes
  4. Add tests for new functionality
  5. Ensure all tests pass (npm test)
  6. Lint and format code (npm run lint && npm run format)
  7. Commit your changes (git commit -m 'Add amazing feature')
  8. Push to the branch (git push origin feature/amazing-feature)
  9. Open a Pull Request

Contribution Guidelines

  • Write clear, descriptive commit messages
  • Add JSDoc comments for all public APIs
  • Include tests for new features
  • Update documentation as needed
  • Follow existing code style and patterns

Migration from v1.x

If you're upgrading from version 1.x to 2.0, see MIGRATION.md for detailed instructions.

Quick Migration Steps

  1. Update Package:

    npm install [email protected]
  2. Update Node.js (if needed):

    node --version  # Must be 18+
  3. Add New Configuration (optional):

    # Add to .env
    CACHE_ENABLED=true
    CACHE_TTL=300000
    MAX_PARALLEL_REQUESTS=5
    LOG_LEVEL=info
  4. Test Configuration:

    npm start
    # Should see: [INFO] Configuration loaded successfully
  5. Update Integration Code (if needed):

    // Update imports for strict types
    import { MergeRequest, User, ReviewerSuggestion } from 'gitlab-auto-reviewers';

Breaking Changes

  • Node.js 18+ required (was 16+)
  • Configuration validation now fails fast on startup
  • Error response format includes more structured information
  • Log format changed to structured JSON

See MIGRATION.md for complete details and troubleshooting.

Known Limitations

Large Merge Request Handling

GitLab API Data Limitations

When using GitLabAPIDataSource (webhook mode or API-based analysis), very large merge requests may encounter GitLab API limitations:

Limitations:

  • Diff Size Limits: GitLab API may truncate or limit diff data for merge requests with extensive changes
  • File Count Limits: Merge requests with hundreds of changed files may return partial file lists
  • API Rate Limits: High-frequency requests may be throttled by GitLab's rate limiting
  • Timeout Constraints: Very large merge requests may exceed API timeout thresholds

Impact:

  • Reviewer suggestions may be based on partial data
  • Some changed files may not be analyzed
  • Contributor analysis may be incomplete
  • CODEOWNERS matching may miss some files

Mitigation Strategies:

  1. Use LocalGitDataSource for Large MRs:

    # CLI mode with local repository (no API limits)
    npx gitlab-auto-reviewers cli --repo /path/to/repo --mr 123
  2. Split Large Merge Requests:

    • Break large changes into smaller, focused merge requests
    • Each MR should ideally change fewer than 50-100 files
  3. Monitor API Usage:

    • Check GitLab API rate limit headers
    • Implement request throttling if needed
    • Use caching to reduce API calls
  4. Expect Partial Results:

    • The system will continue to function with limited data
    • Reviewer suggestions will be based on available information
    • No errors will be thrown for partial data

When to Use Each Data Source:

| Scenario | Recommended Data Source | Reason | |----------|------------------------|--------| | Large MR (100+ files) | LocalGitDataSource | No API limits, complete data | | Webhook integration | GitLabAPIDataSource | Stateless, no repo clone needed | | CI/CD pipeline | LocalGitDataSource | Repo already cloned, faster | | Development | LocalGitDataSource | Faster, works offline | | Small MR (< 50 files) | Either | Both work well |

Documentation References:

  • Requirements 12.4: System allows limited data for large MRs
  • Requirements 12.5: Clear messaging about limitations
  • Design Document: Performance Considerations section

For more details, see TROUBLESHOOTING.md.

Documentation

License

MIT

Support

For issues, questions, or contributions, please visit:

Changelog

v2.0.0 (2024-12-04)

Major Release - Performance & Reliability Improvements

New Features:

  • In-memory caching with configurable TTL
  • Automatic retry logic with exponential backoff
  • Parallel data fetching for improved performance
  • Structured logging with multiple log levels
  • Configuration validation on startup
  • Performance metrics tracking
  • Enhanced error messages with context

Breaking Changes:

  • Node.js 18+ required (was 16+)
  • Configuration validation now fails fast
  • Error response format changed
  • Log format changed to structured JSON

Improvements:

  • Full TypeScript strict mode (zero any types)
  • Comprehensive type definitions
  • Better error handling and recovery
  • Improved observability and debugging
  • Enhanced documentation

See MIGRATION.md for upgrade instructions.

Documentation

Comprehensive documentation is available in the ../docs/ directory:

For Users

For Developers

For Testers

For Maintainers

Documentation Index

See docs/README.md for the complete documentation index and organization.