Skip to main content

assurance-mcp

PyPI Tests Python License

Give your agent a way to find out what it missed.

An agent cannot audit its own reading. Ask one whether it saw everything and it will tell you yes, because from the inside a complete answer and an answer built on two thirds of the data feel identical. These tools answer that from the outside, in arithmetic, with no model involved.

Read-only by construction. No writes, no deletes, no network, no telemetry. Proven by test_the_server_never_writes in this repository: no tool opens a file for writing, and no requests, urllib, shutil, os.remove, os.replace or symlink_to call exists in the package.

Install

python3 -m venv .venv
source .venv/bin/activate
pip install assurance-mcp

Python 3.10 or newer. Pulls in assurance-core for the decision logic and assurance-cli for the filesystem I/O.

Configure your MCP client

Cursor (~/.cursor/mcp.json), Claude Desktop, or any MCP client:

{
  "mcpServers": {
    "assurance": {
      "command": "/absolute/path/to/.venv/bin/python",
      "args": ["-m", "assurance_mcp.server"],
      "env": {}
    }
  }
}

Restart the client. You should see four tools.

Tools

Tool What it answers Needs a folder?
check_set_coverage_tool Did the run cover everything it was supposed to, over any two sets of keys? No
check_coverage_tool Which periods are present in a folder of dated files, and which are not? Yes
check_staleness_tool Do a document's figures still match a source file the caller names? Yes
list_dated_files_tool Which reporting periods does this folder hold? Yes

check_set_coverage_tool — the one that fits your problem

The other three are folder-shaped, which answers one question well and most questions not at all. This one takes two lists the agent already holds. Keys are anything you can name.

You:    Before you answer, check what you retrieved against what the question spans.

Agent:  check_set_coverage_tool(
          expected = ["acme/msa.md", "acme/amendment-1.md", "acme/amendment-2.md", "acme/amendment-3.md"],
          found    = ["acme/msa.md", "acme/amendment-1.md", "globex/msa.md"],
          scope    = "documents this question spans",
          where    = "the retrieved set",
          derivation = "metadata filter tenant=acme, top_k=3")

        → { "complete": false, "read": 2, "required": 4,
            "summary": "2 of 4 documents this question spans — not in the retrieved set:
                        acme/amendment-2.md, acme/amendment-3.md — metadata filter tenant=acme, top_k=3",
            "missing": [{"key": "acme/amendment-2.md", ...}, {"key": "acme/amendment-3.md", ...}],
            "unexpected": ["globex/msa.md"] }

Agent:  I've read 2 of the 4 documents this question spans. Amendment 2 and amendment 3 were not
        retrieved, and the terms may have changed in them — I shouldn't answer yet. I also pulled a
        Globex document into an Acme question, which I've discarded.

That is a different sentence from any an agent produces on its own, and it is the sentence that stops a wrong answer from being delivered confidently.

Use it for: retrieved chunks against documents the question spans · files reviewed against git diff --name-only · controls with evidence against controls in scope · partitions loaded against partitions declared · eval cases run against cases declared · records processed against records enumerated.

expected is your declaration and is never inferred here. A denominator the tool invents is a denominator nobody can argue with.

check_coverage_tool — a folder of dated files

You:    Check coverage on ~/reports

Agent:  check_coverage_tool("/Users/you/reports")

        → { "complete": false,
            "summary": "22 of 24 months from 2024-01 to 2025-12 in reports —
                        not in this folder: March 2025, July 2025 —
                        Range inferred from filenames: earliest 2024-01, latest 2025-12.",
            "coverage": { "read": 22, "required": 24,
                          "missing": [{"key": "2025-03", "label": "March 2025"},
                                      {"key": "2025-07", "label": "July 2025"}] } }

Agent:  22 of 24 months are present. March 2025 and July 2025 are not in this folder.

Monthly, quarterly, weekly, daily and numbered runs (INV-0001, run_042) are all recognised. The derivation is returned with the ratio so the agent can surface a denominator you can disagree with, rather than only a result.

Works from a cold start — no prior state, no database, no model, no key.

Hard limits (honest)

  • CSV and TSV only for profiling — no XLSX dependency in this package
  • Staleness needs recorded facts — pass recorded_facts, or the document must be readable tabular data; otherwise the answer is uncheckable, never silence
  • No cross-document inference. Comparing figures across files that merely look related produced 21 false positives on a real corpus, so this package refuses to do it
  • The caller names the folder boundary — paths cannot escape it via .. or a symlink
  • check_set_coverage_tool never invents your expected set, which is the whole point of it

Also in this family

Run the tests

pip install -e ".[dev]" && python -m pytest -q

Licence

Apache-2.0. See LICENSE. Upstream is I-Ops; this repo is a publication, never a source.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

assurance_mcp-0.2.0.tar.gz (15.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

assurance_mcp-0.2.0-py3-none-any.whl (11.5 kB view details)

Uploaded Python 3

File details

Details for the file assurance_mcp-0.2.0.tar.gz.

File metadata

  • Download URL: assurance_mcp-0.2.0.tar.gz
  • Upload date:
  • Size: 15.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for assurance_mcp-0.2.0.tar.gz
Algorithm Hash digest
SHA256 1f959938084c172ff9595282e774e06061bbae7b3e8924da711a52868cc7f410
MD5 32f01dc51e02a3a369b56adbac07fd1c
BLAKE2b-256 297ad7302eba248d433a0c63a8d779322388dc9ed515bc484bc9d2837c2f5c6c

See more details on using hashes here.

Provenance

The following attestation bundles were made for assurance_mcp-0.2.0.tar.gz:

Publisher: publish.yml on i-ops-hq/assurance-mcp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file assurance_mcp-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: assurance_mcp-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 11.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for assurance_mcp-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a5987afa9a62877b7d77a5181b36d86f12005e39ebd8edfc338e3f3807907610
MD5 337eaa58a5f0f2646461b25e6ea9ad8e
BLAKE2b-256 ca801c1eab6068bd733c1924562b1d1db7d75f927ced6c31ecaec2d554b9adfb

See more details on using hashes here.

Provenance

The following attestation bundles were made for assurance_mcp-0.2.0-py3-none-any.whl:

Publisher: publish.yml on i-ops-hq/assurance-mcp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.4.1

2 files

0.4.0

2 files

0.3.0

2 files

0.2.3

2 files

0.2.2

2 files

0.2.1

2 files

This release

0.2.0 This release

2 files

0.1.1

2 files

0.1.0

2 files

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