# Env Validator

**MCP Tool:** `env_validator`  
**Tier:** Tier 2 — Differentiated  
**Category:** validators  
**Endpoint:** https://obfus.link/mcp  
**Price:** $0.015 / call  
**Verification:** ✓ TDD verified  

> Audit .env files and diff against .env.example — the Pre-Deploy Gate

## Atomic Answer

Env Validator audits .env files for malformed lines, empty required keys, duplicate keys, unquoted whitespace, and unexpanded variable references. The Pre-Deploy Gate diff mode compares .env.local against .env.example and reports missing keys, extra keys, changed values with automatic secret masking, and type mismatches — catching configuration errors in CI before they crash a production deployment.

## Description

Validates .env files for malformed lines, empty required keys, duplicate keys, unquoted whitespace, and unexpanded variable references. The Pre-Deploy Gate diff mode compares .env.local against .env.example and reports missing keys (the deploy-crash class of bug), extra keys, changed values with automatic secret masking, and type mismatches. Every call also flags secret-looking keys.

## Agentic Reasoning

USE THIS WHEN: (1) You are running a pre-deploy CI gate and need to verify the deployment environment has every key declared in the .env.example template — pass mode: "diff", the actual env as envContent, and the example as referenceEnv; the missingKeys[] array is the gate signal that prevents the deploy-crashed-because-DATABASE_URL-wasn't-set class of bug. (2) You are auditing a .env file for committable hygiene before opening a PR — pass mode: "validate" and read errors[] (with line numbers) for malformed lines, duplicates, and unquoted whitespace values; the secretFlags[] array catches credentials that should never live in dotfiles regardless. (3) You are building a developer-onboarding tool that compares a contributor's local .env against the canonical example to tell them what to fill in — diff mode gives a structured missingKeys + extraKeys output you can render directly into the onboarding UI. DO NOT USE WHEN: you need to LOAD environment variables into a running process — this is a static validator, not a loader; use dotenv or your framework's built-in loader for that. Do not use to encrypt or store secrets — secretFlags identifies them; actual remediation requires a secrets manager. Do not use for non-dotenv config formats (YAML, JSON, TOML) — wrong tool; pass YAML through yaml_to_env first if you need to compare a YAML config against a .env example. OVER ALTERNATIVES: prefer this over a manual grep of "is this key present" (no type-mismatch detection, no secret masking, no recommendations), over dotenv-linter (CLI-only, no agentic JSON output, no diff mode), and over hand-coding the diff in a CI script (no consistent secret masking — committing the masking pattern to a tool means every team gets the same safety property without reinventing it).

## MCP Description

Validates .env files and diffs them against a reference (.env.example) before deployment. Two modes: (1) validate — audits a single .env for malformed KEY=VALUE lines, invalid keys, empty required-looking values (DATABASE_URL, API_KEY, JWT_SECRET), duplicate keys, unquoted whitespace, and unexpanded $VAR. (2) diff (★ Pre-Deploy Gate differentiator) — compares envContent vs referenceEnv and returns missingKeys, extraKeys, changedValues (secrets masked first-2/last-2), and typeMismatches. Every call also returns secretFlags identifying keys whose names suggest credentials, with remediation recommendations. Errors include line numbers for fast lookup. USE WHEN: building a pre-deploy CI gate, auditing committable .env hygiene, or building developer onboarding tooling. INPUT: mode ("validate" | "diff"), envContent, optional referenceEnv. COST: 1 unit.

## Input Schema

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `mode` | `validate` \| `diff` | yes | "validate" audits a single .env. "diff" compares envContent against referenceEnv (typically .env.example) and produces a Pre-Deploy Gate report. |
| `envContent` | `string` | yes | The .env file content to validate (typically .env.local in diff mode). |
| `referenceEnv` | `string` | no | Only used in diff mode. The reference .env content to compare against (typically .env.example). |

## Output Schema

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `diff` | `object` | no | Present only when mode is "diff". |
| `keys` | `array` | yes |  |
| `valid` | `boolean` | yes |  |
| `errors` | `array` | yes |  |
| `secretFlags` | `array` | yes |  |

## How To Use

1. **Pick a mode** — Diff (Pre-Deploy Gate) compares .env.local against .env.example. Validate audits a single .env without a reference.
2. **Paste your .env content** — Drop the actual deployment env (typically .env.local) into the left field. In diff mode, paste the reference (.env.example) into the right field.
3. **Run the audit** — The tool reports issues with line numbers, flags secret-looking keys, and in diff mode shows missing keys, extra keys, value changes (secrets masked), and type mismatches.
4. **Wire into CI** — The missingKeys[] array is the natural gate signal — if non-empty in your pre-deploy check, fail the build before the deployment crashes on a missing variable.
5. **Act on secret flags** — Move any flagged credentials out of committable dotfiles and into a real secrets manager (Vercel Env, AWS Secrets Manager, Doppler).

## FAQs

**Why does diff mode mask secret values but show non-secret values verbatim?**

The diff output is intended to be safe to log in CI output, paste into PR descriptions, or render in developer-onboarding tooling. Masking applies to any key whose name contains SECRET, PASSWORD, TOKEN, PRIVATE, CERT, CREDENTIAL, or API_KEY (case-insensitive). Non-secret keys (NODE_ENV, PORT, DATABASE_URL host changes, etc.) are surfaced verbatim because that's usually the actionable information you want to see.

**How is "type" inferred for type mismatches?**

Heuristic inference: "true" or "false" → boolean; values matching the numeric regex (-?\d+(\.\d+)?) → number; everything else → string; empty values are excluded from comparison. A mismatch is reported only when both sides infer a non-empty type and the types differ. PORT=3000 (number) vs PORT=eight (string) is a mismatch; PORT=3000 vs PORT=8080 is not.

**What is the "Pre-Deploy Gate" pattern?**

Wire the diff endpoint into your CI pipeline before the deploy step. Pass the production-bound env as envContent and the committed .env.example as referenceEnv. If diff.missingKeys is non-empty, fail the build — those keys would cause a runtime crash on the first request. If diff.typeMismatches is non-empty, fail also — a string where a number was expected typically crashes app startup.

**Why are duplicate keys flagged but not treated as critical errors?**

dotenv and most env loaders apply "last wins" semantics — duplicates are technically valid. But they're almost always a bug, often from a merge conflict that wasn't cleanly resolved. The tool flags them as warnings so they surface for review without breaking pipelines that intentionally use the pattern.

**Can I use this with formats other than .env?**

No. The parser is dotenv-specific (KEY=VALUE, # comments, quoted/unquoted values). For YAML config auditing, use yaml_to_env first to convert YAML into .env shape, then run env_validator. For JSON or TOML, this is the wrong tool — those formats have their own validators.

**Can I use this tool via the MCP API?**

Yes. The tool is registered on the obfus.link MCP server at https://obfus.link/mcp. Call it from any MCP-compatible agent with a Shared Payment Token. The MCP tool name matches the snake_case slug shown in the integration snippet.

## Tags

`env` · `dotenv` · `validator` · `pre-deploy` · `ci` · `diff` · `secrets` · `config`

---

*obfus.link — A Subether Labs Infrastructure Project*  
*Canonical URL: https://obfus.link/tool/env-validator*  
*JSON view: https://obfus.link/tool/env-validator/json*
