AgentStack
MCP verified MIT Self-run

Env Diff

mcp-adametherzlab-env-diff · by AdametherzLab

Compare .env files across environments, branches, and runtimes. Type-aware diffing, secret masking, git branch comparison, MCP server for AI agents. Zero dependencies.

No reviews yet
0 installs
2 views
0.0% view→install

Install

$ agentstack add mcp-adametherzlab-env-diff

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets Used
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Env Diff? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

[](https://github.com/AdametherzLab/env-diff/actions) [](https://www.npmjs.com/package/@adametherzlab/env-diff) [](https://www.typescriptlang.org/) [](LICENSE) []()

env-diff

> Compare .env files across environments, branches, and runtimes. Catch missing variables, type mismatches, and configuration drift before deployment.

Built by AdametherzLab with Claude.

Why env-diff?

Environment variable mismatches are one of the most common causes of deployment failures. A missing DATABASE_URL, a PORT that changed from number to string, a secret that exists in development but not production — these bugs are silent until they break production.

env-diff catches them all.

Features

  • Type-aware diffing — Catches when PORT=3000 (number) becomes PORT="3000" (string)
  • Git branch comparisonenv-diff .env:main .env:staging compares across branches
  • Secret masking — Automatically detects and masks API keys, tokens, and passwords
  • Multi-file matrix — Compare dev, staging, and prod simultaneously
  • Codebase scanning — Auto-generate .env.example from your source code
  • Sync mode — Generate patches to fix environment drift
  • Watch mode — Live drift detection during development
  • CI/CD ready — GitHub Action, strict mode, JSON output for automation
  • MCP server — Native integration for AI coding agents (Claude Code, Cursor)
  • Zero dependencies — Pure TypeScript, runs on Bun or Node.js 20+
  • Config file — Persistent settings via .envdiffrc.json

How env-diff compares

| Feature | env-diff | dotenv-linter | dotenv-diff | dotenvx | |---------|:--------:|:-------------:|:-----------:|:-------:| | Type-aware diffing | yes | no | no | no | | Git branch comparison | yes | no | no | no | | Secret masking | yes | no | no | yes | | Multi-file matrix | yes | no | no | no | | Codebase scanning | yes | no | no | no | | MCP server (AI agents) | yes | no | no | no | | GitHub Action | yes | no | no | no | | Watch mode | yes | no | no | no | | Sync mode | yes | no | no | no | | Zero dependencies | yes | yes | no | no | | Config file | yes | yes | no | yes | | CI/CD strict mode | yes | yes | no | yes |

Quick Start

Installation

npm install -g @adametherzlab/env-diff
# or
bun add -g @adametherzlab/env-diff
# or use directly
npx @adametherzlab/env-diff .env.example .env.production

Compare two files

env-diff .env.example .env.production

Compare across git branches

env-diff .env:main .env:staging
env-diff .env@abc123 .env@HEAD

Strict mode for CI

env-diff .env.example .env.production --strict
# Exits with code 1 if errors detected

CLI Reference

env-diff   [options]

Options:
  --strict           Exit with code 1 if errors detected
  --ignore      Ignore specific keys (repeatable)
  --no-value-diff    Only check key existence and types
  --format     Output: table (default), json, markdown, summary
  --mask             Mask detected secret values
  --watch            Re-diff on file changes
  --sync             Show patch to fix missing keys
  --sync-write       Apply sync patch to target file

Subcommands:
  --scan [dir]       Scan codebase for env var references
  --scan-write [dir] Generate .env.example from scan
  --matrix    Compare multiple files simultaneously
  --install-hook     Install pre-commit git hook

Output Formats

Table (default)

+──────────────+──────────────+──────────────+───────────────+
│ Key          │ .env.example │ .env.prod    │ Status        │
+──────────────+──────────────+──────────────+───────────────+
│ DATABASE_URL │ postgres://… │ (undefined)  │ removed       │
│ PORT         │ 3000         │ "3000"       │ type-mismatch │
│ API_KEY      │ (undefined)  │ sk-l****     │ added         │
+──────────────+──────────────+──────────────+───────────────+

✖ Environment check failed with errors

JSON

env-diff .env.example .env.prod --format json

Markdown

env-diff .env.example .env.prod --format markdown

Programmatic API

import { parseEnvFile, diffEnvMaps, parseProcessEnv } from "@adametherzlab/env-diff";

// Compare .env files
const template = parseEnvFile(".env.example");
const runtime = parseProcessEnv();
const result = diffEnvMaps(template, runtime, "Template", "Runtime");

if (result.hasErrors) {
  console.error("Missing required environment variables!");
  result.entries
    .filter(e => e.severity === "error")
    .forEach(e => console.error(`  - ${e.key}: ${e.status}`));
  process.exit(1);
}

Git Branch Comparison

Compare .env files across any git ref (branch, tag, commit):

# Compare main vs staging
env-diff .env:main .env:staging

# Compare current vs specific commit
env-diff .env@abc123 .env

# PR review: compare base branch vs HEAD
env-diff .env:origin/main .env:HEAD

Secret Masking

env-diff automatically detects sensitive keys and masks their values:

env-diff .env.example .env.production --mask
# API_KEY: sk-l**** | SECRET_TOKEN: rea****

Default patterns: *KEY*, *SECRET*, *TOKEN*, *PASSWORD*, *CREDENTIAL*, *AUTH*, *PRIVATE*

Configure custom patterns in .envdiffrc.json:

{
  "secretPatterns": ["*KEY*", "*SECRET*", "STRIPE_*", "AWS_*"]
}

Codebase Scanning

Auto-generate .env.example from your source code:

# Preview what variables your code uses
env-diff --scan ./src

# Generate .env.example
env-diff --scan-write ./src

Output:

# Referenced in: src/db.ts, src/config.ts
DATABASE_URL=

# Referenced in: src/server.ts
PORT=3000

Multi-File Matrix

Compare all environments simultaneously:

env-diff --matrix .env.dev .env.staging .env.prod

Sync Mode

Fix environment drift automatically:

# Preview missing keys
env-diff .env.example .env.local --sync

# Apply patch
env-diff .env.example .env.local --sync-write

Configuration

Create .envdiffrc.json in your project root:

{
  "ignoreKeys": ["NODE_ENV", "CI", "PATH"],
  "caseSensitive": true,
  "strict": true,
  "format": "table",
  "secretPatterns": ["*KEY*", "*SECRET*", "*TOKEN*"],
  "compareValues": true
}

Or add to package.json:

{
  "envdiff": {
    "ignoreKeys": ["NODE_ENV"],
    "strict": true
  }
}

CI/CD Integration

GitHub Actions (Recommended)

- uses: AdametherzLab/env-diff@v1
  with:
    left: '.env.example'
    right: '.env.production'
    strict: 'true'
    ignore: 'NODE_ENV,CI'
    mask-secrets: 'true'

Generic CI

steps:
  - run: npx @adametherzlab/env-diff .env.example .env.production --strict --mask

Pre-commit Hook

env-diff --install-hook

AI Agent Integration (MCP)

env-diff includes an MCP (Model Context Protocol) server for AI coding agents:

# Add to Claude Code, Cursor, or any MCP-compatible agent
env-diff-mcp

Available tools:

  • env_diff_compare — Compare .env files or content
  • env_diff_scan — Scan codebase for env references
  • env_diff_sync — Generate sync patches

Watch Mode

Live drift detection during development:

env-diff .env.example .env --watch
# Re-diffs automatically when either file changes

API Reference

| Function | Description | |----------|-------------| | parseEnvString(content, options?) | Parse raw .env content into typed EnvMap | | parseEnvFile(filePath, options?) | Read and parse .env file | | parseProcessEnv() | Wrap process.env into typed EnvMap | | diffEnvMaps(left, right, leftLabel, rightLabel, options?) | Compare two EnvMaps | | loadGitEnv(source, options?) | Load .env from git ref | | scanForEnvVars(directory, extensions?) | Scan code for env references | | syncEnvFiles(source, target, options?) | Generate sync patch | | compareMatrix(filePaths, options?) | Multi-file comparison | | watchEnvFiles(left, right, options?) | Live file watching | | isSecretKey(key, patterns?) | Check if key is a secret | | maskValue(value) | Mask a sensitive value | | formatTable(result) | Format as colored table | | formatJson(result) | Format as JSON | | formatMarkdown(result) | Format as markdown table |

Status & Severity

| Status | Severity | Meaning | |--------|----------|---------| | removed | error | Key missing in target | | type-mismatch | error | Same key, different types | | added | warning | New key in target only | | modified | warning | Same key & type, different value | | unchanged | info | Identical |

Changelog

See [CHANGELOG.md](CHANGELOG.md) for version history.

Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md)

License

MIT (c) AdametherzLab — Built with Claude

Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.