Featured

Deploy OpenClaw in 60 seconds — 20% off logoDeploy OpenClaw in 60 seconds — 20% off

Launch OpenClaw on Hostinger in about 60 seconds and keep your agent live 24/7. Our referral link gives you 20% off, no coupon code needed.

Launch on Hostinger
Run your Hermes agent on Hostinger, fully managed logoRun your Hermes agent on Hostinger, fully managed

Launch Hermes on Hostinger in one click, fully managed, no VPS knowledge needed. Use code ZACAARON10 for 10% off.

Launch on Hostinger
Crawl and scrape any site into clean data, 10% off logoCrawl and scrape any site into clean data, 10% off

Firecrawl crawls and scrapes any site into clean markdown for your agent. Get 1,000 free credits, and new users get 10% off their first purchase.

Try Firecrawl free
6,000+ web scrapers for your AI agent, start free logo6,000+ web scrapers for your AI agent, start free

Apify gives your agent live web data: 6,000+ prebuilt scrapers and actors, MCP-ready. Sign up free with $5 in usage credits.

Try Apify free
One API to scrape, enrich, and extract the internet. logoOne API to scrape, enrich, and extract the internet.

Context.dev gives your agents a single API to scrape, enrich, and extract live web data — no proxies, no parsers, no maintenance.

Start building free
SetupClaw: done-for-you OpenClaw for founders & exec teams logoSetupClaw: done-for-you OpenClaw for founders & exec teams

White-glove OpenClaw for founders and exec teams (4–50+ employees): we install, harden, integrate your tools, and maintain it — secured from day one.

Get it set up for you
SEO data APIs for your agent, $1 free credit logoSEO data APIs for your agent, $1 free credit

DataForSEO gives your agent live access to SERP results, keyword data, backlinks, and on-page SEO data through one API. New accounts get a $1 credit, good for up to 20,000 keyword or backlink lookups.

Try DataForSEO free
Reach 48,000+ AI builders

A flat monthly placement in front of developers actively installing AI tools. No lock-in, cancel anytime.

Advertise here

Works with

Claude CodeClaude DesktopCursorVS CodeClineCodex CLIOpenClaw+ any MCP client

Install to Claude Code

This server doesn't publish a one-line install command. Follow the setup in the source repository.

Summary

MCP server for compare-cli: contract version diff/redline and a drift gate as agent tools.

README.md

compare-cli

![npm version](https://www.npmjs.com/package/compare-cli) ![CI](https://github.com/DrBaher/compare-cli/actions/workflows/ci.yml) ![License: MIT](https://opensource.org/licenses/MIT) ![Node ≥ 20](https://nodejs.org/)

Clause-aware drift detection between two contract versions. Pre-signature gate for legal teams and agent pipelines. Single-file Node CLI, two runtime deps, deterministic by design, no LLM tier in v1. Part of the contract-ops CLI suite: template-vault-cli (storage) → draft-cli (fill placeholders) → nda-review-cli (review, redline, negotiate) → docx2pdf-cli (DOCX → PDF) → sign-cli (signing + audit). compare-cli is the pre-signature drift gate. Showcase site.

compare negotiated.docx ready-to-sign.pdf
# exit 0 = safe to sign
# exit 2 = substantive drift, DO NOT sign without review
# exit 3 = cosmetic / typographic drift only (informational)
# exit 4 = clauses moved, content identical

Part of the contract-ops CLI suite. draft-cli (fill placeholders) → nda-review-cli (review, redline, negotiate) → docx2pdf-cli (DOCX → PDF) → sign-cli (signing + audit). Storage: template-vault-cli. Drift detection: compare-cli (this CLI). Showcase site.

Agent pipelines: see mcp/README.md for compare-cli-mcp, the MCP server wrapping this CLI. Three tools (compare_files, compare_with_negotiation, compare_demo), stdio transport, JSON-first responses. Design contract: docs/mcp.md.

---

Why

You negotiated a contract over several rounds with counterparty's counsel. A few days later their paralegal sends you a ready-to-sign.pdf. Is the PDF the same text you agreed to, or did something quietly shift between "final version" and "version we put in the signing envelope"?

compare-cli answers that question with an exit code your CI can gate on:

  • Exit 0: every clause matches. Safe to sign.
  • Exit 2: substantive drift — a clause's text changed, a clause was

added, or a clause was removed. The exact change is in the report. Do not sign without review.

  • Exit 3: cosmetic-only (whitespace, curly quotes, em-dashes) or

typographic-only (case, $1,000 vs $1000, Oxford comma) drift. Informational; the agreement didn't change.

  • Exit 4: clauses moved but content is identical. Order shifted; the

agreement didn't change.

The CLI works on .docx, .pdf, .md, and plain text — including cross-format comparisons (negotiated .docx vs ready-to-sign .pdf).

Install

npm install -g compare-cli

Or run without installing:

npx -p compare-cli@latest -- compare --demo

(The package is compare-cli; the installed command is compare. The -p … -- compare form tells npx which package to fetch and which bin to run, since the two names differ.)

Requires Node ≥ 20. (Pinned by pdfjs-dist@^5.7.284, which we share with sign-cli.)

Run this

compare --demo

Runs against two bundled fixtures (a negotiated NDA and a candidate where the term silently shifted from "two (2) years" to "three (3) years") and exits 2. You see the headline contract — substantive drift detected, report written, exit code asserted — without authoring a file.

compare --demo --json

Same comparison, structured JSON output to stdout.

Where to go next

| If you are… | Start here | |---|---| | A new user evaluating the gate | Run this above, then the End-to-end transcript | | An LLM agent driving the CLI | AGENTS.mdcompare --catalog jsoncompare <base> <candidate> --json | | Gating in CI | compare --check (exit-code only) or --sarif for code-scanning | | Wiring via MCP | the compare-cli-mcp package — see docs/mcp.md | | Adding a new CLI to the suite | The build-a-CLI playbook — the conventions every suite CLI follows |

End-to-end transcript

# You negotiated this:
cat > negotiated.md <<'EOF'
## 1. Purpose
This agreement governs information exchange between Acme and Globex.

## 2. Term
The term is two (2) years from the Effective Date.

## 3. Notices
All notices shall be delivered to the addresses on the cover page.
EOF

# They sent back this:
cat > ready-to-sign.md <<'EOF'
## 1. Purpose
This agreement governs information exchange between Acme and Globex.

## 2. Term
The term is three (3) years from the Effective Date.

## 3. Notices
All notices shall be delivered to the addresses on the cover page.
EOF

# Gate on it:
compare negotiated.md ready-to-sign.md
# → substantive drift, exit 2
echo "exit: $?"

# Or feed the base from nda-review-cli's negotiation.json:
compare --from-negotiation negotiation.json ready-to-sign.pdf

# Strict mode: treat typographic drift ($1,000 vs $1000) as substantive too
compare negotiated.md ready-to-sign.md --strict

In a CI pipeline:

compare negotiated.docx received/$(date +%F).pdf || {
  status=$?
  case $status in
    0) echo "✓ safe to sign" ;;
    2) echo "✗ substantive drift — do not sign" ;;
    3) echo "⚠ cosmetic drift only — informational" ;;
    4) echo "⚠ clauses moved but content identical" ;;
    *) echo "✗ I/O or arg error" ;;
  esac
  exit $status
}

Command reference

USAGE
  compare BASE CANDIDATE [options]
  compare --from-negotiation NEG.json CANDIDATE [options]
  compare --demo [--json]

ARGS
  BASE        what was agreed (.docx | .pdf | .md | .txt | - for stdin)
  CANDIDATE   what is being put forward (same formats, or -)

OPTIONS
  --from-negotiation PATH   read base text from nda-review-cli's negotiation.json
  --require-signoffs        with --from-negotiation, require both parties to have signed off
  --only-clauses PATTERNS   comma-separated; only include matching clause titles in the report + exit code
  --ignore-clauses PATTERNS comma-separated; exclude matching clause titles from the report + exit code
  --strict                  treat typographic drift as substantive (exit 2)
  --strict-cosmetic         treat cosmetic drift as substantive (exit 2)
  --json                    emit structured JSON to stdout
  --sarif                   emit SARIF v2.1.0 to stdout (for code-scanning / CI annotations)
  --no-intra-diff           disable inline word-level diff inside substantive clauses
  --why                     print structured explanation to stderr
  --silent, -q              suppress stderr
  --check                   suppress all output; communicate via exit code only (implies --silent)
  --output, -o PATH         write report to PATH instead of stdout (ignored with --check)
  --completion bash|zsh     emit shell completion script
  --demo                    run a zero-file 30-second demo
  --version, -V             print version
  --help, -h                show this help

Exit codes

| Code | Meaning | |------|-----------------------------------------------------------------| | 0 | No drift detected, safe to sign | | 1 | I/O error — input not found, unreadable, malformed .docx/.pdf | | 2 | Substantive drift (or --strict/--strict-cosmetic was set and tripped) | | 3 | Cosmetic-only or typographic-only drift (informational) | | 4 | Clause(s) moved but content identical |

Stable across minor versions. Documented in AGENTS.md and COMPARE_SCHEMA.md.

What counts as which class?

  • cosmetic — whitespace runs, line wraps, curly vs straight quotes,

em-dashes vs hyphens, NBSP vs space, ellipsis vs ...

  • typographic — number formatting ($1,000 vs $1000,

5.0% vs 5%), Oxford comma flips, case-only differences (Acme vs ACME)

  • substantive — any word change, addition, deletion, or clause

reorganization (will not vs will, two years vs three years, clauses added or removed)

  • moved — clauses whose text is byte-identical but whose position in

the ordered clause sequence changed

The exact rules — including what is deliberately not normalized away (singular/plural, tense, negation, list punctuation) — are locked in COMPARE_SCHEMA.md §5–§6.

--json output shape

Stable across minor versions. Top-level keys: ok, exit_class, exit_code, base, candidate, summary, differences, warnings. See COMPARE_SCHEMA.md §10 for the full shape.

--why output

Structured key=value lines on stderr describing detection tiers, alignment method, class counts, exit decision, and strict-mode state. Same posture as draft-cli's --why.

--from-negotiation

Reads nda-review-cli's negotiation.json and extracts the latest agreed text as BASE. Three-tier resolution (preferred → fallback): top-level status: converged|signed_off|finalized, per-round agreed: true (minimum schema), per-round clause_status all "agreed" (historical fallback). See COMPARE_SCHEMA.md §9.

Pair with --require-signoffs when running unattended: it errors (exit 2) unless both signoffs.a and signoffs.b are non-empty in the state file. nda-review-cli populates these when the negotiate sign-off checkpoint is satisfied — a human-review gate before any agreement is acted on.

Clause filters

--only-clauses Term,Payment,Indemnification keeps only matching clauses in the report and exit-code calculation; --ignore-clauses Acknowledgments,Notices drops matching ones. Patterns are case-insensitive substrings, matched against numbering-stripped clause titles. Both flags can combine (--ignore-clauses runs after --only-clauses). The number of suppressed differences is surfaced in the human report and as summary.suppressed_by_filter in --json / SARIF output, so the suppression is auditable.

--sarif (CI / code-scanning)

--sarif emits a SARIF v2.1.0 document. Each substantive difference is a result with level: error; cosmetic/typographic are warning; added/removed/moved are note. Designed for GitHub Actions code- scanning upload — substantive drift appears as inline annotations on the candidate file in the PR review UI.

compare base.docx contracts/2026/acme.docx --sarif > compare.sarif
# upload via: github/codeql-action/upload-sarif@v3 with sarif_file=compare.sarif

--check (exit-code-only mode)

--check suppresses both stdout and stderr; the exit code is the only output. Use for CI gates and short shell pipelines:

compare base.docx cand.docx --check && echo "safe to sign"

Implies --silent. --output is also skipped under --check (you said you only care about the exit code).

If no agreed round exists, the CLI exits 2 with a clear error.

Working with PDFs

Text extraction from .pdf is layout-lossy. When either side is a PDF, the report surfaces a warning:

warning: candidate was extracted from PDF; layout-sensitive differences
         may surface as false positives

If extraction returns zero characters (a scanned PDF without an OCR layer), compare-cli exits 1 with a clear message rather than silently reporting no drift.

Part of the contract-ops suite

cli.drbaher.com

Pipeline (in order):

placeholders in templates before negotiation begins.

the negotiation.json hash-chained state file. --from-negotiation reads its output.

upstream step that turns the agreed .docx into the .pdf you put in the signing envelope.

signing flow; compare-cli is the gate that runs before it.

Auxiliaries:

— clause-aware template storage; produces info --json payloads that downstream tools consume. Implements the same clause-detection rule (docs/clause-detection.md) compare-cli does; divergences tracked in template-vault-cli/docs/clause-detection-divergence.md.

Documentation

source of truth for what the CLI does. Implementation and tests are written against this file.

  • AGENTS.md — for LLM consumers and agent pipelines.

Stable output shapes, exit codes, failure diagnosis.

License

MIT © DrBaher

See related servers & alternatives →

Related MCP servers

Browse all →

Related guides

Hand-picked reading to help you choose and use Other servers.