Skip to main content

evidence-ledger-mcp

Under active development. Both the schema and the server may change in breaking ways between versions until v1.0. Pin the version you use.

This repository holds two separate contributions:

  1. The evidence ledger schema (schema/): a format for structured records that make every citation in a work (a manuscript, software or other) checkable. It stands on its own: any tool or agent can write and check ledgers with it, without our server. Status: draft v0.4.0, may still change in breaking ways.
  2. The evidence ledger MCP server (src/, Python package evidence-ledger-mcp): a tool through which agents write and check ledgers that follow the schema. Status: early; it creates, appends to, searches, validates and withdraws records in JSON Lines ledgers (roadmap 0.1) and exports them at the levels full, masked or locator (roadmap 0.2), and writes an HTML summary grouped by claim that prints to PDF (roadmap 0.3). Checks are planned.

The two have separate version numbers. Schema releases are tagged schema-vX.Y.Z; the server currently supports schema v0.4.0 and reports it through schema_info. The schema will move to a repository of its own before v1.0.

The evidence ledger schema in schema/ is licensed under Creative Commons Attribution 4.0 International (CC BY 4.0); see schema/LICENSE. Attribution: Matthias Kloft. This licence applies to the schema, not to ledger contents or third-party source material. The MCP server and its associated documentation are licensed under the MIT licence; see LICENSE. The schema retains its separate CC BY 4.0 licence, including the copy bundled with the server.

Purpose

When an LLM agent or a person adds a citation, the ledger records what is claimed, which source backs it, where in the source, a short quote, and why the citation is needed. Co-authors, scripts or a second model can then check each citation against its source later, whichever tool wrote the work. The idea follows Moravcsik's active citation (2014): contestable claims come with the evidence that supports them.

The schema

schema/evidence-ledger.schema.json (JSON Schema 2020-12) describes one record and, in $defs/header, the ledger header. A ledger is a list of records, kept next to the work it covers.

Header. A ledger can start with a header that records schema_version, the work it covers (title, type: manuscript, software, dataset or other, and an optional location), and optional description, created and notes. The ledger file then takes one of these shapes:

  • JSON or YAML: an object {"ledger": <header>, "records": [<record>, ...]}.
  • JSON Lines: the first line is {"ledger": <header>}; every following line is one record.
  • A plain list of records, without header, stays valid.

File format. The schema is format-neutral: it validates parsed records, so a ledger can be JSON, JSON Lines or YAML. The MCP server stores ledgers as JSON Lines (.jsonl, one record per line), because new records are appended as single lines, concurrent additions rarely conflict, and agents write JSON reliably. The schema also supports records written by hand in YAML; the server reads JSON Lines and exports JSON or JSON Lines. When writing YAML, quote dates (date: "2026-10-30"), since unquoted dates are not read as text.

Each record contains:

  • Claim: claim, claim_id (records backing the same claim share it), claim_type, and an anchor that finds the claim in the work (an ID marker, or the exact text).
  • Source: a citation key, and a doi, isbn or url (or no_identifier_reason).
  • Evidence: locator (page, section, figure or table), quote, quote_hash, relation (supports, partially_supports, background, method, contrasts), a justification and an optional note.
  • Provenance: who wrote the record (person or agent, and which model) and when.

Every claim counts as contestable by default and then needs locator, quote, hash and justification. Marking a claim as not contestable needs a contestable_reason. Evidence that contradicts a claim is recorded with relation: contrasts, not dropped.

note (per record) and notes (in the header) are free-text comments, the JSON counterpart of comments in a YAML file. They are exported with the ledger, so they must never contain source text; source text belongs only in quote, quote_prefix, quote_suffix and quote_focus.

quote_hash is sha256-n2: plus the SHA-256 of the UTF-8 quote after normalization n2: Unicode NFKC, casefold, NFKC again, keep only letters and digits. Legacy sha256-n1: hashes omit the second NFKC and remain valid and checkable. The hash then survives differences between copies of a source, such as whitespace, hyphenation and quote styles.

quote_focus optionally marks the phrase within quote that carries the claim. It must occur exactly once, cover whole whitespace-delimited words, and contain at most 25 words. It is source text and is removed from masked and locator exports.

Masked exports accept max_words from 1 to 25. With a focus they keep a centred window, shifting at the quote edges to use the budget; otherwise they keep the start and end. Cuts are marked with “…”; quotes shorter than the budget stay whole. A focus longer than the budget is refused. Without max_words, masking still keeps only the first and last words (at most three each and half the quote), even with a focus. The export header records level and max_words.

How to use it

  1. When you cite a source, write one record per claim–source pair into the ledger.
  2. Validate the ledger against the schema with any JSON Schema 2020-12 validator, e.g. in Python with jsonschema.

A minimal record:

- id: R-0001
  claim_id: C-0001
  claim: "Keeping a ledger cut unchecked citations from 40 to 3 per manuscript."
  claim_type: empirical
  contestable: true
  anchor: {exact: "cut unchecked citations from 40 to 3"}
  key: exampleLedgerStudy2026
  no_identifier_reason: "Invented source for this example"
  locator: {page: 4}
  quote: "Ledger records reduced unchecked citations from 40 to 3 per manuscript"
  quote_hash: sha256-n2:3b8d67a25018dccc865ee88b24c10aa4a5b553e41ff28ebc46936a71eee7db3c
  relation: supports
  justification: "The quoted sentence states both counts."
  retrieved_via: pdf
  provenance: {by_type: agent, by: Claude Code, model: claude-opus-5-5, date: "2026-10-30"}

Quotes from copyrighted sources belong in a private ledger. A public ledger should keep only locators and hashes.

Running the MCP server

Requires Python 3.11 or newer. From a source checkout with uv installed:

uv sync
uv run evidence-ledger-mcp

The server uses stdio. Configure an MCP client to run uv with arguments run, --directory, the absolute path to this checkout, and evidence-ledger-mcp. Pass absolute ledger paths to tools; relative paths resolve against the server's working directory.

Available tools are schema_info, validate_record, create_ledger, add_record, get_record, find_records, validate_ledger, withdraw_record, export_ledger and summarize_ledger. Create a ledger with a work containing title and type, then pass records and a separate provenance object to add_record. The server assigns record IDs, assigns claim IDs unless supplied, computes n2 quote hashes and fills in the provenance date.

export_ledger defaults to level="full", format="jsonl" and excluding withdrawn records. Keep full exports private. Use level="masked" with optional max_words (1–25) for excerpts, or level="locator" to remove quoted source text. Exports retain other record metadata, including note and header notes, and always remove locator.chunk. A publication check rejects copied source text in other metadata at masked and locator levels; it does not replace publication approval. The output must be a new file.

summarize_ledger writes a self-contained HTML report grouped by claim, with full, masked and locator levels. Print it from a browser to produce a PDF; the server does not write PDFs directly. Masked summaries use the default start/end masking and do not accept max_words.

Where the fields come from

Field or rule Basis
contestable (full evidence for contestable claims) Active citation: only citations that support contestable empirical points need full documentation, not background references or uncontested facts (Moravcsik, 2014, pp. 50–51)
anchor.exact, anchor.prefix, anchor.suffix, quote_prefix, quote_suffix W3C Web Annotation Text Quote Selector: a passage is identified by an exact copy plus the text before and after it (Sanderson et al., 2017, §4.2.4)
relation Loosely follows CiTO, the Citation Typing Ontology (Peroni & Shotton, 2012); the mapping onto CiTO terms is not yet checked. supports and contrasts also match scite's citation classes (Nicholson et al., 2021)
Claim, passage and justification in one record Annotation for Transparent Inquiry links passages in a publication to annotations and underlying sources (Karcher & Weber, 2019)
provenance Records who asserted what and when, in the spirit of nanopublications (Groth et al., 2010); a record could be exported in that form
claim_id, importance, retrieved_via, found_via, quote_hash, no_identifier_reason, withdrawn Our own proposals; to the best of our knowledge they do not follow an earlier source

References

Metadata

Release files for evidence-ledger-mcp 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for evidence-ledger-mcp 0.1.0
File Size Uploaded Provenance Actions
evidence_ledger_mcp-0.1.0.tar.gz 30.4 kB With provenance Details for evidence_ledger_mcp-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for evidence-ledger-mcp 0.1.0
File Interpreter ABI Platform Actions
evidence_ledger_mcp-0.1.0-py3-none-any.whl Python 3 none any Details for evidence_ledger_mcp-0.1.0-py3-none-any.whl

Total release size: 55.7 kB

Release files / evidence_ledger_mcp-0.1.0.tar.gz

Download URL evidence_ledger_mcp-0.1.0.tar.gz
Size 30.4 kB
Tags Source
SHA-256 checksum
How to use checksums
c527bb1f997e1f2a9ae7c083bfe64144d0583db7b43e7db09b19d98bb4e0897e
BLAKE2b-256 checksum
How to use checksums
26df0019af3bcbef37313ec7132989ecdc7f61ec28b82da6ceecf0c42e572a55
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 30, 2026.

Transparency log

Release files / evidence_ledger_mcp-0.1.0-py3-none-any.whl

Download URL evidence_ledger_mcp-0.1.0-py3-none-any.whl
Size 25.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
758b23a0b20f07ed262f1a359276c5b05c601028387f91962793fdf2e9d411fa
BLAKE2b-256 checksum
How to use checksums
77c3ebe4ca958d40208e6137460fa9ec1a60db1cf2fe09a6f45ce9bb7986130d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 30, 2026.

Transparency log

Security for evidence-ledger-mcp 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for evidence_ledger_mcp-0.1.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 30, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page