# io.github.Anselmoo/mcp-ooxml-ledger (oci · ghcr.io/anselmoo/mcp-ooxml-ledger:0.3.0)

Edit Office documents and prove no edit went unrecorded

- Trust score: 36/100 (low)
- Change this week: 0
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-09-20

## Components

- oci · `ghcr.io/anselmoo/mcp-ooxml-ledger:0.3.0`: 36/100 (this document), [markdown](https://verifymcp.io/servers/anselmoo-mcp-ooxml-ledger/ghcr-io-anselmoo-mcp-ooxml-ledger-0-3-0.md), [page](https://verifymcp.io/servers/anselmoo-mcp-ooxml-ledger/ghcr-io-anselmoo-mcp-ooxml-ledger-0-3-0)
- pypi · `mcp-ooxml-ledger`: 35/100, [markdown](https://verifymcp.io/servers/anselmoo-mcp-ooxml-ledger/mcp-ooxml-ledger.md), [page](https://verifymcp.io/servers/anselmoo-mcp-ooxml-ledger/mcp-ooxml-ledger)

## Channel facts

- Registry: `oci`
- Package: `ghcr.io/anselmoo/mcp-ooxml-ledger:0.3.0`
- Transport: `stdio`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-09-20.

- **Supply Chain Security**: 0/100
  - Malware scan not yet available for this package.
  - Known CVEs could not be checked: this artifact ships no SBOM, so there is no dependency list to read. Publishing one would let us assess it.
  - Install-script risk not yet assessed.
  - Dependency health could not be checked: this artifact ships no SBOM, so there is no dependency list to read. Publishing one would let us assess it.
- **Provenance & Transparency**: 48/100
  - Source repository is publicly reachable at the declared URL.
  - Provenance check failed: no build-provenance attestation is published.
  - Clear OSI-approved license (MIT).
  - Actively maintained (last published 6 days ago).
  - Publishes a security disclosure policy (SECURITY.md).
- **Schema Quality & AI Usability**: 59/100
  - AI-judged instruction clarity (good).
  - Context-footprint check failed: tool/resource definitions use about 2201 tokens (~157/item across 14 items; 14 tools + 0 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 0/100
  - Stability not yet verified: not enough scan history yet (needs a 30-day window).
- **Tool Coverage**: 71/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 0% of tool parameters carry a description.
  - Structured output schemas are declared (100% of tools); any adoption earns full credit.
- **Tool Safety**: 100/100
  - No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.
  - All 1 tool(s) whose name or description implies an irreversible operation declare an MCP destructiveHint annotation.
  - An AI judge read all 15 captured unit(s) of tool text and found none that tries to manipulate the model reading it.
- **Capabilities**: 100/100
  - Implements a current MCP spec version (2026-07-28).

**Unverified: 2 categories.** Categories scored 0 because we could not verify them: a data source with nothing on this package, evidence we could not reach, or a check we could not run. We only credit what we can confirm.

## Install

### How do I install the io.github.Anselmoo/mcp-ooxml-ledger server?

io.github.Anselmoo/mcp-ooxml-ledger runs locally as a container image, launched with docker run --rm -i ghcr.io/anselmoo/mcp-ooxml-ledger:0.3.0. Ready-made configuration for Claude, Cursor, VS Code, Codex and 3 more is on this page, copied from each client's own documentation.

### Claude

```bash
claude mcp add anselmoo-mcp-ooxml-ledger -- docker run --rm -i ghcr.io/anselmoo/mcp-ooxml-ledger:0.3.0
```

### Cursor

```json
{
  "mcpServers": {
    "anselmoo-mcp-ooxml-ledger": {
      "command": "docker",
      "args": [
        "run",
        "--rm",
        "-i",
        "ghcr.io/anselmoo/mcp-ooxml-ledger:0.3.0"
      ]
    }
  }
}
```

### VS Code

```json
{
  "servers": {
    "anselmoo-mcp-ooxml-ledger": {
      "command": "docker",
      "args": [
        "run",
        "--rm",
        "-i",
        "ghcr.io/anselmoo/mcp-ooxml-ledger:0.3.0"
      ]
    }
  }
}
```

### Codex

```bash
codex mcp add anselmoo-mcp-ooxml-ledger -- docker run --rm -i ghcr.io/anselmoo/mcp-ooxml-ledger:0.3.0
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "anselmoo-mcp-ooxml-ledger": {
      "type": "local",
      "command": [
        "docker",
        "run",
        "--rm",
        "-i",
        "ghcr.io/anselmoo/mcp-ooxml-ledger:0.3.0"
      ],
      "enabled": true
    }
  }
}
```

### Hermes

```yaml
mcp_servers:
  anselmoo-mcp-ooxml-ledger:
    command: "docker"
    args: ["run", "--rm", "-i", "ghcr.io/anselmoo/mcp-ooxml-ledger:0.3.0"]
```

### Netclaw

```json
{
  "McpServers": {
    "anselmoo-mcp-ooxml-ledger": {
      "Transport": "stdio",
      "Command": "docker",
      "Arguments": [
        "run",
        "--rm",
        "-i",
        "ghcr.io/anselmoo/mcp-ooxml-ledger:0.3.0"
      ]
    }
  }
}
```

### Other

```json
{
  "mcpServers": {
    "anselmoo-mcp-ooxml-ledger": {
      "command": "docker",
      "args": [
        "run",
        "--rm",
        "-i",
        "ghcr.io/anselmoo/mcp-ooxml-ledger:0.3.0"
      ]
    }
  }
}
```

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-09-13 (score 36)

First indexed and scored.

## MCP tools (14)

### `server_info` (~22 tokens)

Server info

Versions, allowed roots, and what this build can and cannot do.

Output parameters:

- `canon` (string)
- `caveat` (string)
- `editing_available` (boolean)
- `editing_formats` (array)
- `formats` (array)
- `read_only` (boolean)
- `receipt_schema` (string)
- `roots` (array)
- `tool` (string)

### `digest` (~50 tokens)

Canonical digest

Compute a document's canonical digest — stable across a no-op Office save, and the key a receipt is stored under. Needs no session.

Input parameters:

- `document` (string, required)
- `include_parts` (boolean)

Output parameters:

- `canon` (string)
- `digest` (string)
- `document` (string)
- `kind` (string)
- `name` (string)
- `parts`

### `verify` (~76 tokens)

Verify

Check a document against its receipt. Reports three distinct outcomes: verified, unknown (no receipt matches this digest) and failed (a receipt matched but a tier failed). Needs no session — the same check runs in CI via `ooxml-ledger verify`.

Input parameters:

- `document` (string, required)
- `original`
- `receipt`

Output parameters:

- `baseline_checked`
- `caveat` (string)
- `digest` (string)
- `disclosures` (array)
- `document` (string)
- `exit_code` (integer)
- `outcome` (string)
- `reasons` (array)
- `tiers` (object)

### `open_document` (~72 tokens)

Open document

Start an editing session: unpack the document to disk, record its baseline digest and part manifest, and sweep expired sessions. Reopening the same unchanged document resumes its live session instead of forking a second one.

Input parameters:

- `document` (string, required)
- `keep_baseline` (boolean)
- `ttl_seconds`

Output parameters:

- `baseline_digest` (string)
- `baseline_stored` (boolean)
- `canon` (string)
- `document` (string)
- `expires` (string)
- `kind` (string)
- `name` (string)
- `parts` (integer)
- `resumed` (boolean)
- `session_id` (string)
- `swept` (array)
- `swept_skipped` (array)

### `close_document` (~61 tokens)

Close document

End a session and delete its working directory WITHOUT sealing a receipt. Refuses when the journal holds recorded operations unless `discard` is set — closing over them would throw away the accountability record.

Input parameters:

- `discard` (boolean)
- `session_id` (string, required)

Output parameters:

- `closed` (boolean)
- `journal_unreadable`
- `operations_discarded`
- `removed_directory` (string)
- `session_id` (string)

### `describe_structure` (~91 tokens)

Describe structure

Report a session document's structure: which parts the digest covers, which it excludes, and the format's own units — paragraphs for docx, sheets for xlsx, slides (in <p:sldIdLst> order, never filesystem order) for pptx. Describes the session's working copy as opened; `verify` reports on the file on disk now.

Input parameters:

- `session_id` (string, required)

Output parameters:

- `baseline_digest` (string): The canonical digest of this document AS IT WAS WHEN THE SESSION WAS OPENED, and of the working copy these results were read from — not an attestation about the file on disk right now. Call `verify`…
- `document` (string)
- `document_may_have_changed_since_open` (boolean): True when the document FILE on disk no longer has the size and modification time it had when this session last touched it — so these results may describe a version that no longer exists. It reports w…
- `excluded_parts` (array)
- `included_parts` (integer)
- `kind` (string)
- `name` (string)
- `paragraphs`
- `parts` (integer)
- `session_id` (string)
- `sheets`
- `slides`
- `text_parts` (array)

### `find_text` (~214 tokens)

Find text

Case-insensitive substring search over every text-bearing part the digest covers, returning the best address this build can give for each hit: paragraph id or index and hash for docx, slide id for pptx, sheet and cell for xlsx. On pptx, real slides (in presentation order) are visited before slide layouts, masters and notes masters, so the default page surfaces slide content first. Each match's `text` is a bounded window around the hit, not the whole run — `text_length` and `match_offset` locate it in the full run, and `text_truncated` says whether it was cut; a large result set can also stop early on total response size, reported the same way as `max_results` paging: `truncated=True`. Results come from the session's working copy as opened; `verify` is what reports on the file currently on disk.

Input parameters:

- `max_results`
- `part`
- `query` (string, required)
- `session_id` (string, required)

Output parameters:

- `baseline_digest` (string): The canonical digest of this document AS IT WAS WHEN THE SESSION WAS OPENED, and of the working copy these results were read from — not an attestation about the file on disk right now. Call `verify`…
- `document_may_have_changed_since_open` (boolean): True when the document FILE on disk no longer has the size and modification time it had when this session last touched it — so these results may describe a version that no longer exists. It reports w…
- `matches` (array)
- `part`
- `query` (string)
- `session_id` (string)
- `truncated` (boolean)

### `list_receipts` (~51 tokens)

List receipts

List every receipt in the store beside a document, flagging the one whose result digest matches the document as it stands now, and naming every file that was skipped and why.

Input parameters:

- `document` (string, required)

Output parameters:

- `baselines` (array)
- `caveat` (string)
- `document` (string)
- `document_digest` (string)
- `receipts` (array)
- `skipped` (array)
- `store` (string)

### `export_receipt` (~60 tokens)

Export receipt

Write this document's receipt out as one self-contained sidecar file — the thing you attach to a submission, commit to git, or register alongside a DOI.

Input parameters:

- `dest`
- `document` (string, required)
- `overwrite` (boolean)

Output parameters:

- `bytes` (integer)
- `caveat` (string)
- `document` (string)
- `forced` (boolean)
- `gate` (string)
- `operations` (integer)
- `path` (string)
- `result_digest` (string)

### `commit_document` (~102 tokens)

Commit document

End a session by sealing its journal into a receipt, but only if the recorded operations account for every change to the document. If they do not, the commit is REFUSED. `force` overrides a failed gate VERDICT and the override is recorded in the receipt, where `verify` will surface it; it does not override a ledger that could not be read or replayed at all.

Input parameters:

- `force` (boolean)
- `session_id` (string, required)

Output parameters:

- `baseline_digest` (string)
- `caveat` (string)
- `document` (string)
- `forced` (boolean)
- `gate` (string)
- `gate_failures` (array)
- `notices` (array)
- `operations` (integer)
- `receipt_path` (string)
- `result_digest` (string)
- `session_id` (string)
- `structural`
- `visibility`

### `preview_edits` (~111 tokens)

Preview edits

Report what a batch of edits WOULD do, writing nothing. Runs the same engine against a throwaway copy of the document as it stands on disk right now — including every edit already applied in this session — so a green preview and the apply that follows it cannot disagree. `author` and `mode` are required because the engine's refusals depend on both.

Input parameters:

- `author` (string, required)
- `edits` (array, required)
- `mode` (string)
- `session_id` (string, required)

Output parameters:

- `caveat` (string)
- `outcomes` (array)
- `session_id` (string)
- `would_apply` (integer)

### `apply_edits` (~132 tokens)

Apply edits

Apply a batch of edits to the document and record each one in the session's journal. ALL-OR-NOTHING: the document is written only if every edit applied, so a failed batch leaves the file byte-identical and journals nothing. `mode` 'tracked' emits Word revision marks a reviewer can see; 'direct' rewrites the text and is recorded in the ledger alone, which the receipt discloses. Seal the session with `commit_document`.

Input parameters:

- `author` (string, required)
- `edits` (array, required)
- `mode` (string)
- `session_id` (string, required)

Output parameters:

- `applied` (integer)
- `baseline_digest` (string)
- `document_digest_changed` (boolean)
- `outcomes` (array)
- `parts` (array)
- `result_digest`
- `revision_ids` (array)
- `session_id` (string)

### `delete_paragraph` (~207 tokens)

Delete paragraph

Delete one whole paragraph and record it in the session's journal. Address it by `para_id` — the `w14:paraId` `find_text` returns — or by `para_index` TOGETHER WITH `para_hash`, because an index alone silently addresses a different paragraph once anything above it moves. `mode` 'tracked' marks the paragraph mark AND every run with `w:del`, so a reviewer can reject it back and nothing is actually removed; 'direct' removes it outright and is accounted for by the ledger alone, which the receipt discloses. Refused if the paragraph carries a section break, or holds an unaccepted revision by another author. Seal the session with `commit_document`.

Input parameters:

- `author` (string, required)
- `mode` (string)
- `note`
- `para_hash`
- `para_id`
- `para_index`
- `part` (string, required)
- `session_id` (string, required)

Output parameters:

- `after`
- `baseline_digest` (string)
- `before`
- `document_digest_changed` (boolean)
- `mode` (string)
- `note`
- `op` (string)
- `para_id`
- `para_index` (integer)
- `part` (string)
- `parts` (array)
- `result_digest` (string)
- `revision_ids` (array)
- `session_id` (string)

### `insert_paragraph` (~261 tokens)

Insert paragraph

Insert a new paragraph carrying `text`, BESIDE a paragraph you name, and record it in the session's journal. Pass exactly one anchor — `after_para_id` or `before_para_id`, the `w14:paraId` `find_text` returns. `para_hash` is OPTIONAL and recommended: the paraId already names one specific paragraph, and passing the hash `find_text` reported with it additionally refuses the call if that paragraph's text has moved on since you read it. There is deliberately NO raw index parameter. The new paragraph becomes a SIBLING of the anchor, which keeps it inside the same table cell, textbox or content control. `mode` 'tracked' marks the new paragraph and its run with `w:ins`, so rejecting removes the whole paragraph; 'direct' writes it unmarked and is accounted for by the ledger alone, which the receipt discloses. Seal the session with `commit_document`.

Input parameters:

- `after_para_id`
- `author` (string, required)
- `before_para_id`
- `mode` (string)
- `note`
- `para_hash`
- `part` (string, required)
- `session_id` (string, required)
- `text` (string, required)

Output parameters:

- `after`
- `baseline_digest` (string)
- `before`
- `document_digest_changed` (boolean)
- `mode` (string)
- `note`
- `op` (string)
- `para_id`
- `para_index` (integer)
- `part` (string)
- `parts` (array)
- `result_digest` (string)
- `revision_ids` (array)
- `session_id` (string)

## Diagnostics

Captured diagnostic sections: Provenance. The full working is on the page: https://verifymcp.io/servers/anselmoo-mcp-ooxml-ledger/ghcr-io-anselmoo-mcp-ooxml-ledger-0-3-0#diagnostics

## Score history

- 2026-09-20: 36
- 2026-09-19: 36
- 2026-09-18: 36
- 2026-09-17: 36
- 2026-09-16: 36
- 2026-09-15: 36
- 2026-09-14: 36
- 2026-09-13: 36

## Common questions

### What is the io.github.Anselmoo/mcp-ooxml-ledger server?

io.github.Anselmoo/mcp-ooxml-ledger is listed in the public MCP registry as io.github.Anselmoo/mcp-ooxml-ledger. Edit Office documents and prove no edit went unrecorded. This page covers its container image (ghcr.io/anselmoo/mcp-ooxml-ledger:0.3.0).

### Is the io.github.Anselmoo/mcp-ooxml-ledger server safe to use?

io.github.Anselmoo/mcp-ooxml-ledger scores 36 out of 100 on VerifyMCP. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

### What tools does the io.github.Anselmoo/mcp-ooxml-ledger server expose?

io.github.Anselmoo/mcp-ooxml-ledger exposes 14 tools: server_info, digest, verify, open_document, close_document, and 9 more. Their descriptions and schemas cost roughly 1,510 tokens of context every time the server is loaded.

### Is the io.github.Anselmoo/mcp-ooxml-ledger server still maintained?

io.github.Anselmoo/mcp-ooxml-ledger is still listed as active in the MCP registry. We last reached this channel on 20 September 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.

### What licence is the io.github.Anselmoo/mcp-ooxml-ledger server under?

io.github.Anselmoo/mcp-ooxml-ledger declares the MIT licence, which is OSI-approved. That covers the source only, and says nothing about the cost of any service it calls.

## Links

- Repository: https://github.com/Anselmoo/mcp-ooxml-ledger
- Changelog RSS feed: https://verifymcp.io/servers/anselmoo-mcp-ooxml-ledger/ghcr-io-anselmoo-mcp-ooxml-ledger-0-3-0.xml
- Changelog JSON feed: https://verifymcp.io/servers/anselmoo-mcp-ooxml-ledger/ghcr-io-anselmoo-mcp-ooxml-ledger-0-3-0.json
- HTML version of this page: https://verifymcp.io/servers/anselmoo-mcp-ooxml-ledger/ghcr-io-anselmoo-mcp-ooxml-ledger-0-3-0
