Observed since 20 Oct, 19:27 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
Automated DOCX Redlining Engine
This directory contains the core Python implementation of Adeu. It provides the core Redline Engine, the developer SDK, the command-line interface (CLI), and the FastMCP server backend.
Adeu acts as a "Virtual DOM" for Microsoft Word. It translates complex DOCX XML into token-efficient CriticMarkup for LLMs, validates structural edits, and patches the XML safely to preserve document formatting, metadata, and styles. On Windows, it also interfaces directly with live Microsoft Word instances via COM.
Adeu is managed using uv and packaged via hatchling. It requires Python 3.12 or higher.
# Clone and enter the directory
cd python
# Install dependencies and sync the virtual environment
uv sync
# Run the test suite
uv run pytest
The adeu CLI provides a powerful suite of tools for interacting with documents locally.
Extract text as CriticMarkup. Use --clean-view to simulate "Accept All Changes".
# Extract full text
uvx adeu extract contract.docx -o output.md
# Extract only the structural heading outline
uvx adeu extract contract.docx --mode outline
# Extract the form fields ledger (content controls)
uvx adeu extract contract.docx --mode fields
# Strip navigation prose and headers for raw token efficiency
uvx adeu extract contract.docx --no-chrome
# Windows Only: Extract text from the actively open Word document
uvx adeu extract --live
Generate a word-level patch diff between two document versions.
# Compare two DOCX files
uvx adeu diff original.docx modified.docx
# Output raw JSON edits for programmatic use
uvx adeu diff original.docx modified.docx --json
Apply a JSON array of DocumentChange objects (or a modified markdown file) back to the DOCX.
# Apply a JSON batch of edits to a file
uvx adeu apply original.docx edits.json --author "AI Reviewer" -o redlined.docx
# Emit the batch result as machine-readable JSON on stdout (for agents/scripts)
uvx adeu apply original.docx edits.json --json
# Partial salvage mode: apply valid edits while reporting failing edits
uvx adeu apply original.docx edits.json --partial
# Terse error context: produce compact error messages
uvx adeu apply original.docx edits.json --terse-errors
# Windows Only: Apply edits directly to the live, open Word canvas
uvx adeu apply edits.json --live
Accept every tracked change in one operation, producing a finalized clean document. Mirrors the accept_all_changes MCP tool — including its default.
Comment removal is ON by default (--remove-comments): the output is meant to be distributable, and comments are internal review notes that must not travel to a counterparty. Use --no-remove-comments when the review conversation is still live.
# Writes contract_clean.docx next to the input; comments are DELETED
uvx adeu accept-all contract.docx
# Accept the tracked changes but keep the comments
uvx adeu accept-all contract.docx --no-remove-comments
# Explicit output path, machine-readable result on stdout
uvx adeu accept-all contract.docx -o final.docx --json
Every deleted comment is reported by id and author (removed_comment_details under --json). A comment whose anchored text an accepted deletion consumes is removed either way — Word does the same.
The library API is the other way round:
RedlineEngine.accept_all_revisions()defaults toremove_comments=False, because an SDK caller composing their own pipeline should not lose annotations implicitly.
Strip sensitive metadata, hidden text, and author names before external distribution.
# Full scrub (fails if unresolved track changes exist unless --accept-all is passed)
uvx adeu sanitize contract.docx --accept-all -o clean.docx
# Keep your redlines/comments, but anonymize the author and strip metadata
uvx adeu sanitize redline.docx --keep-markup --author "My Firm"
adeu serve)For high-throughput local agent drivers or CI harnesses, run adeu serve to maintain a warm process and document cache over stdin/stdout JSON-Lines:
uv run adeu serve
When an agent operates in a closed sandbox (a CI pipeline, a containerized coding agent) it cannot reach an MCP server. The CLI is the fallback: a strictly local, air-gapped command-line API that accepts the same JSON change schema as the MCP tools. The mapping is 1:1:
| MCP tool | CLI equivalent |
|---|---|
read_docx | adeu extract <doc> [--json] |
diff_docx_files | adeu diff <orig> <mod> [--json] |
process_document_batch | adeu apply <doc> <changes.json> [--json] |
accept_all_changes | adeu accept-all <doc> [--json] |
The I/O contract (see docs/cli-agent-spec.md for the full specification):
--json, a machine-readable JSON result. uvx adeu extract doc.docx > out.md always produces a clean file, even with --debug.0 = success (in --partial mode, at least one edit applied; check edits_skipped in JSON stats to detect skipped edits)1 = failure (in atomic mode, if any edit fails; in --partial mode, if all edits fail)adeu apply --json prints the engine's raw stats object — edits_applied, edits_skipped, per-edit reports with CriticMarkup previews, plus output_path — and suppresses the human-readable logs. A batch that fails validation prints {"error": "batch_validation_failed", "errors": [...]} and exits 1.
The SDK allows you to embed Adeu's Redline Engine directly into your own Python applications.
The engine processes a flat list of DocumentChange objects (ModifyText, AcceptChange, RejectChange, ReplyComment, InsertTableRow, DeleteTableRow).
from io import BytesIO
from adeu import RedlineEngine, ModifyText, AcceptChange
# 1. Load the document stream
with open("contract.docx", "rb") as f:
stream = BytesIO(f.read())
# 2. Define your edits
changes = [
ModifyText(
target_text="State of New York",
new_text="State of Delaware",
comment="Standardized jurisdiction.",
match_mode="all"
),
AcceptChange(target_id="Chg:12")
]
# 3. Initialize the engine and apply
engine = RedlineEngine(stream, author="AI Copilot")
stats = engine.process_batch(changes)
# 4. Save the result
with open("contract_redlined.docx", "wb") as f:
f.write(engine.save_to_stream().getvalue())
Read a document into CriticMarkup representation.
from io import BytesIO
from adeu import extract_text_from_stream
with open("contract.docx", "rb") as f:
stream = BytesIO(f.read())
# Extract raw text with {++ ++} and {-- --} tags intact
markdown_text = extract_text_from_stream(stream)
# Extract clean text simulating "Accept All Changes"
clean_text = extract_text_from_stream(stream, clean_view=True)
Run the metadata scrubber programmatically.
from adeu.sanitize import sanitize_docx
result = sanitize_docx(
input_path="draft.docx",
output_path="final.docx",
keep_markup=True,
author="Legal Team"
)
print(result.report_text)
The Python backend exposes Adeu's capabilities to AI agents via the Model Context Protocol (MCP), powered by FastMCP.
You can boot the server over stdio for agent consumption:
uvx --from adeu adeu-server
Adeu provides an initialization command to automatically inject the MCP server into your local Claude Desktop configuration.
# Installs to Claude Desktop using the global uvx path
uvx adeu init
# Local Developer Mode: Configures Claude to run the server from your current source tree
uv run adeu init --local
When the MCP server runs on Windows (sys.platform == 'win32'), it automatically enables the live_word.py tools. These tools utilize pywin32 to hijack the active Microsoft Word COM object.
If an agent leaves the file_path argument empty when calling read_docx or process_document_batch, the server will automatically target the document that the user currently has open on their screen.
When developing inside the python/ directory, please note the following invariants:
RedlineEngine never performs global document normalization on load or save. This strict behavior prevents the silent destruction of unrelated metadata (like <w:proofErr>) and minimizes XML diff noise.live_word.py and its associated tests, we intentionally omit pythoncom.CoUninitialize() and app.Quit() during teardown. FastMCP and pytest hold proxies unpredictably: forcing teardown causes fatal RPC Access Violations (0x800706be). We let the OS handle the apartment lifecycle.python-docx Paragraph.text properties silently ignore text inside <w:ins> tags. When writing tests to verify redlines, strictly use extract_text_from_stream(clean_view=True) to accurately evaluate the accepted text state.| Variable | Description | Default |
|---|---|---|
ADEU_DOC_CACHE_ENTRIES | Capacity for in-memory parsed document LRU cache | 3 |
ADEU_NO_CACHE | Set to 1 or true to disable disk-level projection caching | 0 |
ADEU_CACHE_DIR | Custom storage directory for disk projection cache | OS cache dir |
ADEU_AUTHOR | Fallback author name for tracked changes when unspecified | OS username (fallback: Adeu AI) |
Download counts and popularity will appear here as the collector receives them.
| Version | Published | Direct dependencies | Open version |
|---|---|---|---|
| 3.0.7 | 5 Oct 2026 | 10 |
This describes our collected data; it is not a security assessment.
Observed since 20 Oct, 19:27 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package:16288ceac53956453072a041213b73b45f9a1f3b7a037ee4c0c69294b819a43e