ChangeX: provenance-first change tracking for AI document edits. Meta package — installs the core CLI (changex) and the MCP server (changex-mcp).
Project description
📝 ChangeX
An AI just edited your document. Do you actually know what it changed?
Everyone hands documents to AI now — "tighten the intro," "fix the citations," "redo the abstract." It gives the file back looking polished, and you have no real way to see what it actually touched. Fine for a grocery list. Not fine for a manuscript, a contract, or anything with your name on it — where a flipped number, a citation to a paper that doesn't exist, or a sentence the model quietly invented can ride along unnoticed in a wall of text. Re-reading 30 pages to find it isn't a plan.
ChangeX records every edit the AI makes —
.docx · .xlsx · .csv · .pptx · .md · .doc —
as real Word tracked changes you accept or reject one at a time, with a tamper-evident log of who did
what, when, and why. Less "diff between two files," more flight recorder for your document. 🛟
ChangeX's default view: every AI edit inline in the document's own outline, plus a who/why change-log.
🚀 Quickstart
# 1) install the tool
uv tool install changex # or: pipx install changex · pip install changex
# 2) connect it to every AI app you have — Claude Code, the Claude Desktop app, Cursor, Gemini
changex connect all # then ⌘Q + reopen the Claude Desktop app once
# (the ChangeX Viewer app does this for you automatically on first launch)
# 3) ask your assistant, e.g.:
# "Use changex to open report.docx, tighten the intro as tracked changes,
# save it, then show me a review of what changed."
That's it — every edit lands as a real Word tracked change you can accept/reject, with full provenance. No MCP, a local/offline model, or a human editing by hand? → Without tools below.
🔄 Updating — what to update, and how
There's only one thing to update: the changex package. The MCP server (changex-mcp) and every CLI command ship inside it — you never update those separately.
1. Update the package — use the same installer you installed with:
| If you installed with… | …update with |
|---|---|
uv tool install changex |
uv tool upgrade changex |
pipx install changex |
pipx upgrade changex |
pip install changex |
pip install -U changex |
uvx changex (zero-install) |
nothing — uvx always runs the latest |
Confirm it worked: changex --version.
Still on the old version after upgrading? PyPI's install index can lag a release by a few minutes, so
pipmay grab the previous version (and leave a sub-package likechangex-corebehind). Force a clean upgrade of all of them —pip install -U --no-cache-dir changex changex-core changex-mcp changex-api— or justuv tool upgrade changex, which handles it cleanly.
2. The MCP server updates automatically. Because changex-mcp is part of the package, step 1 upgrades it too. Your Claude registration is just a pointer to the changex-mcp binary, so do not re-run claude mcp add to "update" it — that doesn't update anything, it only creates duplicate entries. It picks up the new version next time it launches.
Registered the MCP as
uvx changex-mcp(zero-install) instead of the binary? That form is pinned to a cached version — get the newest withuvx changex-mcp@latest, or switch to the installed binary (below).
Only touch claude mcp to (re)connect or fix duplicates. Register once with -s user so it works in every folder and never duplicates. If you already added it in several folders without -s user, reset to a single clean entry:
claude mcp remove changex # repeat in each folder you added it to
claude mcp add -s user changex -- changex-mcp
claude mcp list # changex → ✓ Connected
🧭 How it works
There are two ways to capture an AI's edits — pick based on what your model can do:
| Path | Use it when | Provenance |
|---|---|---|
| 🤖 From your AI (MCP) | a tool-capable desktop client (Claude Desktop/Code, Cursor, Cline) | full — who / vendor / turn / prompt, per edit |
🪄 Without tools (open/seal) |
any model, offline/local, a script, or a human | what-changed (who/why is degraded — said out loud) |
Either way you get a portable, hash-chained .changex journal plus a tracked document to review.
🤖 Path A — from your AI (full provenance)
With the MCP server connected (Quickstart step 2), just ask in plain language. The model edits through ChangeX (open_tracked → get_outline → edit → save_tracked), so every change is a real Word revision — nothing silently rewritten.
"Use changex to open
~/Documents/Q3-report.docx. Tighten the executive summary, fix the heading levels, and replace the passive voice in section 2 — make every change a tracked revision authored by you, save it, then show me a review of what changed."
⚠️ Each Claude app is set up separately — this trips everyone up:
- Claude Code (terminal / IDE) —
claude mcp add -s user changex -- changex-mcp(Quickstart step 2). This is the only thingclaude mcp list ✓ Connectedreflects. - Claude Desktop app — has its own config;
claude mcp adddoes not touch it. Add changex there (absolute path) and fully restart the app → docs/CLAUDE-SETUP.md §B. - claude.ai / ChatGPT in a browser — can't read local files at all; use a desktop app, or Path B on a downloaded copy.
So if claude mcp list says ✓ Connected but a chat says "I can't find changex / upload the file," you're talking to a different Claude than the one you configured — set it up for that app too, see 🔌 Set up your app below. Why local-only →
📎 Easiest in Claude Desktop — just upload the doc. Drag your .docx into the chat and say "use changex to tighten the intro and fix the heading, then give me the tracked file." The upload lands where the changex MCP can read it (no Full Disk Access needed — it sidesteps the macOS privacy wall entirely). changex saves the tracked .docx + .changex and Claude hands them back as downloads.
🪄 Path B — without tools, from any model or a human
No MCP, no tool-calling, no SDK. Three steps:
changex open report.docx— snapshot the original.- Let anything edit
report.docxin place — Claude, ChatGPT, a local llama, a script, or you. changex seal report.docx— ChangeX diffs against the snapshot and reconstructs the changes intoreport.changex+ a Word-openablereport.tracked.docx.
This path sees only before-and-after bytes, so it records a faithful what-changed but degraded who/why (agent / turn / prompt are null) — and ChangeX says so. For full provenance, use Path A.
🔌 Set up your app
Installed the ChangeX Viewer app? It auto-connects every installed app on launch (macOS & Windows) — Claude Code, the Claude Desktop app, Cursor, and the Gemini CLI. Just open it once, then ⌘Q + reopen Claude Desktop. No command needed. The button in Viewer ▸ Settings ▸ Use ChangeX in your AI apps re-runs it any time.
Or one command writes the config for you:
changex connect all # ⚡ connect EVERY installed local app at once
changex connect # list every app it can set up
changex connect claude-desktop # writes the Desktop app config (then ⌘Q + reopen)
changex connect cursor # writes ~/.cursor/mcp.json
changex connect chatgpt # prints the ChatGPT connector runbook (token + commands)
changex connect <app> merges the right MCP entry into that app's config — backing the file up first and using the absolute changex-mcp path so GUI apps find it. Targets: claude-code · claude-desktop · cursor · cline · gemini · chatgpt · claude-web.
Or wire it by hand — ChangeX plugs in three ways (local MCP = the app spawns changex-mcp; remote MCP = the app dials a URL; REST/function tools). Pick your app:
| Your app | How it connects | Reads local files? |
|---|---|---|
| Claude Code (terminal / IDE) | local MCP — one command | ✅ |
| Claude Desktop app | local MCP — its own config + restart | ✅ |
| ChatGPT (desktop or web) | remote MCP connector, or a custom-GPT Action | ✅ (server runs on your Mac) |
| claude.ai (web) | remote MCP connector | ✅ (server runs on your Mac) |
| Cursor / Cline | local MCP — config block | ✅ |
| Gemini (CLI / API) | local MCP / function tools | ✅ |
| Ollama / LM Studio | local MCP if supported, else the no-tools path | ✅ |
💡 GUI apps run with a minimal
PATH, so in their config files use the absolute path fromwhich changex-mcp(commonly/opt/homebrew/bin/changex-mcp). CLI clients launched from your shell usually find a barechangex-mcp.
🟧 Claude Code (terminal / IDE)
One command:
changex connect claude-code— or by hand:
claude mcp add -s user changex -- changex-mcp # once; works in every folder, no duplicates
claude mcp list # changex → ✓ Connected
This is the only thing claude mcp list reflects — it does not configure the Claude Desktop app (below).
🟧 Claude Desktop app (separate from Claude Code!)
One command:
changex connect claude-desktop, then ⌘Q + reopen. Or by hand:
- Get the absolute path:
which changex-mcp→ e.g./opt/homebrew/bin/changex-mcp. - Add to
~/Library/Application Support/Claude/claude_desktop_config.json:{ "mcpServers": { "changex": { "command": "/opt/homebrew/bin/changex-mcp", "args": [] } } }
- Fully quit & reopen the app (⌘Q — not just close the window). The 🔨 tools icon should list
open_tracked,edit,save_tracked, …
🟩 ChatGPT (desktop or web)
One command:
changex connect chatgptprints the token + exact commands below.
ChatGPT dials a URL (it can't reach localhost), so run the HTTP server and expose it with a tunnel — the server runs on your Mac, so it still edits your local files:
export CHANGEX_MCP_TOKEN=$(openssl rand -hex 32)
changex-mcp --http # serves http://127.0.0.1:9000/mcp
cloudflared tunnel --url http://127.0.0.1:9000 # or: ngrok http 9000 → an https URL
- MCP connector (Settings → Connectors, developer mode): add an MCP server → URL
https://<tunnel>/mcp, headerAuthorization: Bearer <CHANGEX_MCP_TOKEN>. - Custom GPT → Actions: instead run
changex-apiand importhttps://<tunnel>/openapi.jsonin the GPT's Actions → Import from URL.
🟦 claude.ai (web)
Same as the ChatGPT connector — run changex-mcp --http + a tunnel + a token, then Settings → Connectors → Add custom connector: URL https://<tunnel>/mcp, auth header Authorization: Bearer <CHANGEX_MCP_TOKEN>. (A web tab can't read local files itself; the tunneled server does the file I/O on your Mac.)
🟪 Cursor / Cline
One command:
changex connect cursor(orchangex connect cline). Or by hand:
Add to .cursor/mcp.json (project) or ~/.cursor/mcp.json (global) — Cline uses the same block in its MCP settings:
{ "mcpServers": { "changex": { "command": "changex-mcp", "args": [] } } }
🟨 Gemini (CLI / API)
One command (CLI):
changex connect gemini. Or by hand:
CLI — add to ~/.gemini/settings.json:
{ "mcpServers": { "changex": { "command": "changex-mcp", "args": [] } } }
API — load integrations/gemini-functions.json (function declarations) and route each call to the matching changex-api endpoint.
⬛ Ollama / LM Studio (local models)
- Speaks MCP? (LM Studio, recent builds) — register the same stdio block:
{ "mcpServers": { "changex": { "command": "changex-mcp", "args": [] } } }
- Doesn't? (plain Ollama) — use the no-tools path:
changex open report.docx→ let the model rewrite the file →changex seal report.docx. Same as Path B above.
Flags, security (loopback vs
--public+ token), the OpenAI Agents SDK, and REST/function-tool schemas: docs/CALL-FROM-YOUR-APP.md.
👀 Review the changes
changex seal prints these with your real paths — or run them yourself:
changex review report.changex --out review.html # 🐙 GitKraken-style commit graph
changex log report.changex # 🌿 git-log of every edit (--oneline)
changex rewind report.changex original.docx --to 3 --out phase3.docx # ⏪ the doc at any earlier phase
changex verify report.changex # 🔒 hash-chain tamper check
changex view report.changex --doc report.tracked.docx # 🌐 live local page (accept/reject)
changex preview report.changex --out preview.html # 🔎 self-contained HTML (any platform)
# …or just open report.tracked.docx in Word — real native track changes 🖊️
Because the .changex journal is an append-only, hash-chained log of edits — each op is a
"commit" (hash ⭢ prev_hash) stamped with author + timestamp — ChangeX gives you a git-like
history of any document:
- 🐙
changex review→ a GitKraken-style commit graph. Every document part (paragraph) is its own coloured lane — a continuous follow line you can trace down the graph through every edit that touched it. Each commit shows its hash, op kind, the part, the redline (red delete / green insert), the author avatar, the timestamp, and the rationale. The same graph shows in the ChangeX Viewer app andchangex view. - ⏪
changex rewind→ time-travel. Rebuild the document as it was at any earlier phase:--to <seq|hash>replays the baseline + the first N edits (--to 0= the clean baseline). - 🌿
changex log→ the terminal view (--onelinetoo).
$ changex log "Q3 Launch Brief.changex" --oneline
d27c085 text.replace by the end of the quarter → by September 30 (Claude, 2026-06-08 09:12)
3edcc9f text.insert + across three regions (GPT-4o, 2026-06-08 09:31)
671985a text.replace all of our customers worldwide → enterprise … (Claude, 2026-06-08 10:02)
3a93438 text.replace approximately fifty thousand dollars → $48,000 (Sam, 2026-06-08 11:20)
852ec26 text.replace reduce risk → minimize downtime (GPT-4o, 2026-06-08 13:46)
f39f63e style.change Normal → Title (Gemini, 2026-06-08 14:05)
99be3fa text.replace redesigned dashboard → redesigned analytics … (Claude, 2026-06-08 16:41)
$ changex rewind "Q3 Launch Brief.changex" original.docx --to 3 --out phase3.docx
✓ rewound to seq 3 (671985a54) — 3 of 7 edits applied
changex preview renders any file to a self-contained HTML page — a .changex journal
as a redline, or a source-code/text file with syntax highlighting (Pygments). It's the
engine behind the macOS Quick Look extension and the Windows preview handler below, so a
double-click preview looks the same everywhere.
💡 Paths with spaces need quotes: changex open "My Report.docx".
📦 What it tracks
| Format | How changes show up |
|---|---|
📄 .docx |
Native Word track changes — accept/reject in Word (text, paragraph, style, run-format, paragraph move) |
📊 .xlsx / .csv |
Non-destructive review copy — colored cells, comments, a Changes sheet (original untouched) |
📽️ .pptx |
Revision overlay + a generated "Revisions" summary slide |
📝 .md |
Inline HTML redline (Markdown has no native track-changes) |
🗂️ .doc (legacy) |
Auto-converted to .docx (LibreOffice), then native Word revisions — best-effort |
Every format also writes the portable .changex journal. Honest per-format limits: docs/FIDELITY.md. Live MCP and the open/seal path are docx-only; other formats are captured with scripted changex track (see Example prompts below).
🖼️ See it on every format
| Markdown — inline redline | CSV — side-by-side redline |
|---|---|
| Excel — review + provenance | PowerPoint — review |
📖 More
✍️ Example prompts (copy-paste)
Talk to ChangeX in plain language through your AI — each prompt notes what it does:
Tighten + restyle — "Open
report.docxwith changex. Replace every "utilize" with "use", fix the two run-on sentences in the intro, and bold the section headings — all as tracked revisions. Save and show me the review."
Proofread, one change each — "Using changex, proofread
notes.docxfor grammar only. Make each fix a separate tracked change with a one-line rationale, then give me the change-log grouped by paragraph."
Move a section (exercises
node.move) — "Opencontract.docx, move the "Termination" clause to just after "Payment" as a tracked move, and don't touch anything else."
Scripted edits (any format, no model) — hand changex track a small ops.json for that one file, e.g. a spreadsheet:
[
{ "kind": "cell.set", "sheet": "Q4", "ref": "B3", "before": "95", "after": "120", "rationale": "cloud spend rose" },
{ "kind": "formula.set", "sheet": "Q4", "ref": "C3", "before": "=B3*1.1", "after": "=B3*1.15", "rationale": "higher growth" }
]
changex track budget.xlsx ops.json --out budget.tracked.xlsx --changex budget.changex
changex view budget.changex --doc budget.tracked.xlsx
(For .docx, ops are text.replace / node.insert / style.change / format.run / node.move by node_id — see docs/CHANGEX_FORMAT.md.)
🖥️ CLI commands
Run changex (or changex help) for the full list:
╔═╗╦ ╦╔═╗╔╗╔╔═╗╔═╗═╗ ╦
║ ╠═╣╠═╣║║║║ ╦║╣ ╔╩╦╝
╚═╝╩ ╩╩ ╩╝╚╝╚═╝╚═╝╩ ╚═
provenance-first change tracking for AI document edits
Track & review
track apply ops to a doc (.docx/.xlsx/.csv/.pptx/.md/.doc) → tracked file + .changex
review render the changes as a GitKraken-style commit graph (HTML)
log git-log of every edit (--oneline)
rewind reconstruct the document at any earlier phase (git checkout)
preview render ANY file to self-contained HTML (redline, or highlighted code/text)
view serve an interactive localhost review page (accept / reject)
verify check a .changex hash chain + baseline
Passive — any model, even offline
open snapshot the baseline before anything edits the file
seal diff the edited file → reconstruct the tracked changes
Connect to your apps
connect wire ChangeX into your AI apps (`connect all` = every installed one at once)
Diagnose & set up (macOS)
doctor diagnose install + file-access (Full Disk Access)
quicklook manage the Finder Quick Look preview for .changex & code files
Extras
shell interactive Python shell with changex_core preloaded
help show this command list
changex shell opens a Python REPL with changex_core preloaded; changex --version prints the version.
💻 Desktop app (optional) + downloads
ChangeX ships an optional Tauri desktop viewer — a small, double-clickable window over the same review UI as changex view.
It opens on two views you flip between:
- Commit graph — a GitKraken-style timeline where every edit is a commit and each paragraph rides its own coloured lane, so you can trace one part through all its edits.
- Document — your tracked
.docxshown as the document itself: the real text, in order, with the AI's insertions and deletions marked inline (hover a change for who/when). Drop a.changexnext to its tracked.docxand the app finds the doc and opens this view on its own.
You usually don't need the app. changex view (zero-install local page) and the single-file HTML report already give the full accept/reject review on every platform. The desktop window mostly buys you a native icon to double-click for non-technical reviewers — plus that read-the-document-in-context view above.
Installers attach to tagged releases: macOS .dmg is signed + notarized; Windows .msi and Linux .AppImage/.deb are unsigned. Build/sign details: docs/CI-AND-SECRETS.md.
🔎 Finder / Explorer preview — press Space to see the redline
Preview a .changex journal (or any source file, syntax-highlighted) right from your file
manager — no app to open.
- macOS — Quick Look. Grab
ChangeX-QuickLook.dmgfrom the latest release (signed + notarized), or just open ChangeX Viewer ▸ Settings ▸ Enable and it installs + turns on the preview for you. Then select a.changex(or.py,.ts,.json, …) in Finder and press Space. The helper is a background agent — no Dock icon. Manage it any time withchangex quicklook status|enable|disable. - Windows — Explorer preview pane. Grab
ChangeX-Windows-Preview.zipfrom the latest release and runinstall.ps1(it registers a preview handler that shells out tochangex preview). Select a file and open the preview pane (Alt+P). Requirespip install "changex[preview]".
Both reuse the same changex preview engine, so the preview looks identical across platforms.
🛟 Troubleshooting
"can't open my file" / Operation not permitted (macOS) — even via Claude
This is macOS privacy (TCC), not a changex bug: macOS blocks the controlling app (Claude
Desktop, Terminal, iTerm, VS Code…) from ~/Downloads, ~/Documents, and ~/Desktop. The
changex-mcp server inherits that app's permission, so it's blocked exactly when the app is.
Run changex doctor — it names the exact app to grant, shows which folders are blocked, and links you straight to the settings pane:
changex doctor # diagnose
changex doctor --open-settings # also open Full Disk Access
Fix (one-time): quit the app (⌘Q) → System Settings → Privacy & Security → Full Disk Access → turn ON that app (e.g. Claude) → reopen it. In the ChangeX Viewer app, the Grant access button opens this pane for you.
Or skip permissions entirely: in Claude Desktop, upload the document into the chat and ask changex to edit it — the upload lands where changex can read it. Or move the file out of those protected folders.
MCP server shows ✗ Failed to connect (with uvx / npx)
The first uvx changex-mcp / npx -y … downloads the package + all deps into a fresh environment, which can exceed the MCP health-check timeout — so claude mcp list says Failed to connect even though the server is fine. Fix — register the installed binary at user scope:
claude mcp remove changex # drop any old uvx / per-folder entry
claude mcp add -s user changex -- changex-mcp
claude mcp list # changex should now show ✓ Connected
Prefer the zero-install uvx form? Warm the cache first: uv tool install changex-mcp.
WARNING: Cache entry deserialization failed, entry ignored on pip install
This is a pip HTTP-cache warning, not a changex failure — pip skipped a stale cache entry; the install still succeeds. To clear it:
python3 -m pip cache purge
python3 -m pip install -U changex --break-system-packages --no-cache-dir
If pip still reports an older version afterwards, the new one may not be on PyPI yet (the index CDN can lag a few minutes) — wait, or install from source (git clone … && uv sync).
error: externally-managed-environment (PEP 668)
Your system Python refuses a global pip install. Use an isolated installer: uv tool install changex (or pipx install changex). If you must use pip, add --break-system-packages.
Legacy .doc won't open · paths with spaces
.docis converted to.docxvia LibreOffice — install it and ensuresofficeis onPATH(best-effort, lossy for exotic legacy features).- Paths with spaces must be quoted:
changex open "My Report.docx". - Browser chats can't read local files — use a desktop client, or
open/sealon a downloaded copy.
ℹ️ About
ChangeX is a provenance-first change tracker for AI document edits. It records what changed, in what order, and who/why — as a portable, hash-chained .changex journal — and projects that onto whatever review surface the format supports: native Word track-changes for .docx, a non-native overlay for .xlsx / .csv / .pptx / .md. It's local-first (no network calls in the core) and vendor-neutral (MCP + CLI behave the same across Claude, ChatGPT, Gemini, and local models). Design principle: honesty over hype — a degraded/reconstructed result is never presented as full provenance.
Repository description (GitHub "About" field): Provenance-first change tracking for AI document edits — native Word track-changes + a portable, hash-chained
.changexjournal. Works with any model (MCP + CLI). docx · xlsx · csv · pptx · md.
📦 Published packages
All on PyPI (MIT) — pip install changex pulls them all:
| Package | What it is |
|---|---|
| umbrella — installs the CLI and the MCP server | |
| the engine — model, journal, adapters, renderers, CLI | |
| the MCP server (stdio + remote HTTP) | |
| FastAPI REST + OpenAPI wrapper |
🤝 Contributing: see CONTRIBUTING.md · follow the Code of Conduct · 🗺️ Docs: Install · Architecture · .changex format · Fidelity · CI & secrets · 📜 License: MIT — © 2026 Ariorad Moniri
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file changex-0.1.24.tar.gz.
File metadata
- Download URL: changex-0.1.24.tar.gz
- Upload date:
- Size: 35.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
03b232e8ae45d80d39dbc761bd1f0464efbefd2271e93d21b1e11964e5a0acb6
|
|
| MD5 |
92d50453fb1d4fb1f62d0962d420038c
|
|
| BLAKE2b-256 |
7199f49f2c914189c30431eb8aa57f71052b279ddf95e0ffb2eddf6e9e786215
|
File details
Details for the file changex-0.1.24-py3-none-any.whl.
File metadata
- Download URL: changex-0.1.24-py3-none-any.whl
- Upload date:
- Size: 13.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fb0932ea814d67e0abdb2ace4404909aa0295d4ebd310f1e79d8f1766254f9bb
|
|
| MD5 |
5b50886c0510a1426cc550198b3280ee
|
|
| BLAKE2b-256 |
065155dea579af3cae9c0638382c9898c3dcd3d57e8fb478d8336679c8fc3821
|