Skip to main content

qrp-mcp

A local cryptographic inventory for developers and AI agents that carries verifiable coverage and its own limits inside the CBOM.

Every signature in your wallet, contract and validator rests on elliptic-curve cryptography, and a large quantum computer breaks it. Plenty of tools will tell you what they found. This one also tells you what it read, what it could not read, and which question it is not answering — in the document itself, where an auditor can check it rather than take your word.

An MCP server that scans a local directory for cryptography that Shor's algorithm defeats — secp256k1, Ed25519, BLS, Schnorr, RSA — plus weak primitives and CI signing commands, and classifies each one: broken by a quantum computer, post-quantum, or neither.

Everything runs on your machine. No network calls, no account, no API key, nothing uploaded. A tool that reads your keys' surroundings has no business phoning home, so this one makes zero outbound connections — enforced by a test, not promised in a paragraph. The only process it starts is a local git, to pin what it read, with the scanned repository's own hooks and filters disarmed.

flowchart TD
    R["Your repository, on your machine, at a commit"] --> Q["qrp-mcp — offline, zero network calls"]
    Q --> F["Found<br/>file:line and family"]
    Q --> N["Not read<br/>each file with its reason"]
    F --> J["scan --out result.json"]
    N --> J
    J --> O["CBOM (CycloneDX 1.6)<br/>SARIF<br/>closure: what a change closed"]

Need a cryptographic inventory (a CBOM) for a post-quantum migration or an audit, without uploading your code? One command, no install step:

uvx qrp-mcp scan ~/code/my-project --out result.json

What comes back, run on this repository's own test fixtures -- the findings, and next to them what the scan did not read:

"verdict": "This scan read 24 of 27 files (88.89%); the remaining 3 (1 of 1, by extension
            — .b64 — being 100.0% of them) are listed with a reason each."
"summary": { "total_findings": 10, "quantum_vulnerable_count": 6, "pqc_ready_count": 1,
             "weak_count": 1, "pqc_readiness": "hybrid_partial", ... }

Why this matters for chains and wallets

Bitcoin and Ethereum authenticate with ECDSA over secp256k1. Solana, Cardano and Polkadot use Ed25519. Ethereum's consensus layer aggregates with BLS12-381. Taproot adds Schnorr.

All four are public-key schemes whose security rests on discrete-log hardness — and all four fall to the same quantum algorithm. The practical consequence is specific: once a public key is exposed, the private key becomes derivable. Reused addresses, on-chain public keys, and long-lived validator keys are where that exposure already exists today.

None of this is a prediction about dates. It is an inventory question: which of my code paths sign with what? That question has an answer right now, and this tool gives it.

Quick start

Add it to your MCP client — no installation step, uvx fetches and runs it:

{
  "mcpServers": {
    "qrp": {
      "command": "uvx",
      "args": ["qrp-mcp"]
    }
  }
}

Then ask your agent:

Scan ~/code/my-protocol for quantum-vulnerable cryptography.

As a Claude Code plugin

The same server, packaged with a skill, so there is no config file to edit:

/plugin marketplace add StanimirTenev/qrp-mcp
/plugin install qrp@quantumreadiness

Then /qrp:pqc-scan in any project. Both routes need uv on your PATH, since uvx is what fetches and runs the server.

Without an agent: write the result to a file

uvx qrp-mcp scan ~/code/my-protocol --out result.json

This produces the same result as the scan_repo tool, written to a file you can read before it goes anywhere. Nothing is sent. By default (from 0.40.0, as cbom since 0.16.0 and the tools) the quoted line is masked: everything in it but the algorithm name is starred out. --level full writes the line as it is, and --level trimmed removes the line altogether; all three keep each file and line number. The SHA-256 of the written bytes is printed, so anyone you send the file to can quote back exactly what they received.

That digest is the file's integrity, and the file holds its read times, so two runs over one commit print different ones. Beside it, findings sha256 is the fingerprint of the findings alone (findings_fingerprint in the JSON, in SARIF's run properties and in the CBOM as qrp:findings_fingerprint:sha256): the same on every run and at every --level that finds the same, different when a finding is added or removed. Its normalisation rules are written into the output beside it: each finding as family, raw value, classification and severity; each occurrence as category, path, line, family, role and key size; excerpts, confidence, owners, baseline state, mandate clauses, suppressed rows, coverage and the read window left out; both lists sorted, serialised as compact JSON with sorted keys, SHA-256 in hex. It says the result repeats; it says nothing about whether the result is complete.

uvx qrp-mcp cbom ~/code/my-protocol --out cbom.json
uvx qrp-mcp closure before.json after.json --out closure.json

cbom writes the same CycloneDX document as the export_cbom tool, masked by default because it is the document built to be sent. closure writes the prove_closure verdict for two saved scans, and names both inputs by their SHA-256, so the three files can be tied together by whoever receives them. Both print the SHA-256 of what they wrote.

A control on your own tree

uvx qrp-mcp control ~/code/my-protocol --seed 1 --out control.json

From 0.43.0. The tree is copied to a temporary directory, known cryptographic uses (9 styles) and lines that name an algorithm without using it (7 kinds) are planted into the copy, and the copy is scanned with the same instrument. The result says which planted lines were found, which were missed and which non-uses were reported as uses — robustness on known patterns, for this version. It is not a statement about what your tree contains, and it never makes the coverage claim stronger. scan --control-seed N carries the block in the result. The control.

A source scan against the build

uvx qrp-mcp scan ~/code/my-service --out scan.json      # before building
uvx qrp-mcp build-gap scan.json ~/code/my-service/bin/publish --out gap.json

From 0.44.0. Of K public-key-bearing packages or modules in the build, the source scan named J; the K - J list; the families on one side only; and a Go binary's DefaultGODEBUG crypto settings as recorded. It reads only tables the toolchain wrote (*.deps.json, .NET metadata names, go version -m, go tool nm), never code, and never a key size from the build — robustness on known patterns, not recall or coverage of the build. Source against build.

What it reads

Every file under the path is either read or named with the reason it was not. The full list of rules, file types and their limits is in What it looks at.

Kind Read as
Source code C and C++, C#, Visual Basic and F#, Go, Rust, Java, Kotlin, Scala and Groovy, Python, JavaScript and TypeScript, Ruby, PHP, Perl, Solidity, Move and Cairo
Scripts .sh/.bash/.zsh/.ksh, .bat/.cmd, PowerShell .ps1/.psm1/.psd1 — algorithms, and signing commands as a pipeline's are
CI/CD pipelines signing commands (gpg --sign, cosign sign, signtool, jarsigner, codesign, Secure Boot and kernel-module signing), with the key they name
Infrastructure as code Terraform/HCL, Kubernetes manifests and Helm (.tpl, .gotmpl), Dockerfiles (including the crypto libraries a RUN installs)
TLS, SSH and VPN configuration nginx, Apache, HAProxy, Caddy, Envoy, Istio, Traefik, Ingress-NGINX, Postfix, Dovecot, MySQL, PostgreSQL, Kafka, ZooKeeper, OpenVPN, WireGuard, strongSwan, OpenSSH, openssl.cnf, java.security, Vault, IBM MQ (.mqsc), AWS load-balancer policies, OPC UA
Device configuration FortiOS backups, Cisco IOS and Junos — read in part, and named as read in part with what was and was not read
Windows .reg exports (SCHANNEL), web.config/app.config/applicationHost.config, MSBuild .vcxproj/.props/.targets, WiX .wxs, certreq .inf, .snk strong-name keys
Certificates and keys PEM and DER (.pem, .der, .crt, .cer, .key, .pub, …), PEM inside any text file or source string, .p12/.pfx, Java keystores, SSH keys, authorized_keys, known_hosts, OpenPGP keys and signatures, JWKS, BIND DNSSEC key and zone files, Apple .plist
Manifests and lockfiles the dependencies that bring cryptography in, by ecosystem (npm, PyPI, Cargo, Go, Maven/Gradle, NuGet, RubyGems, CocoaPods, SwiftPM, deb/apk/rpm in a Dockerfile)
Not read, on purpose documentation (.txt, .md, .rst, .pod), binaries and images — counted and named, never silently left out

Coverage on three public repositories

What coverage.scope says on three trees this project did not write, measured on 4 Nov 2026 with the code of this release (the repositories at OpenSSH 7fe3b24, certbot 56ee049, Vault 41e571b). coverage_pct is the share of the files present that were read; read_in_full_pct leaves out the files read only in part (a device configuration, a certificate block that did not parse).

Repository Files present Read coverage_pct Read in part read_in_full_pct Findings Weak
OpenSSH 873 741 84.88% 5 84.31% 70 54
certbot 1,250 850 68.00% 0 68.00% 39 28
Vault 9,281 5,434 58.55% 9 58.45% 74 62

These are reading figures, not detection figures. How well the rules find what is there is a different question; the measurements made of it, each with its date and version, are in How it is measured, and no recall or precision figure is cited here as current.

Documentation

What it is not

It reads source, configuration, CI pipelines, infrastructure-as-code, Kubernetes manifests, build files, certificates and key inventories. It does not read documentation, binaries or images; build-gap reads only the name tables a toolchain wrote into a build, never its code.

Every file under the path is accounted for in one of four ways: scanned, unreadable, skipped because the tool does not claim that type — counted by extension, so the coverage figure has a base, and from 0.27.3 named one by one in the coverage block (not_examined → paths) — or a link not followed, named in symlinks_not_followed. files_scanned + unreadable_files + files_skipped_by_type plus the linked files always equals files_present; until 0.34.0 this sentence said three ways and left the links out. A directory the scan cannot enter or list is named in unreadable_directories; its files cannot be counted, so the scan then says it cannot account for every file instead of claiming it read them all. A scan that read seven files out of nine is a different report from one that read seven out of four hundred, and only one of them is worth trusting.

A free inventory tool, not a readiness assessment. It deliberately does not do:

  • risk scoring or prioritisation,
  • migration planning — a replacement names what a finding becomes, not when or in what order,
  • network or host scanning, or reading a system certificate store,
  • tracking change over time — prove_closure compares two scans you give it; nothing keeps a history.

Those live in the Quantum Readiness Platform, the product this tool is extracted from. Nothing here is crippled to push you there — what it does, it does completely.

It also does not tell you that you are about to be hacked. It tells you what you are using.

License

Apache-2.0.

Metadata

Release files for qrp-mcp 0.44.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 qrp-mcp 0.44.0
File Size Uploaded Provenance Actions
qrp_mcp-0.44.0.tar.gz 1.0 MB Without provenance Details for qrp_mcp-0.44.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for qrp-mcp 0.44.0
File Interpreter ABI Platform Actions
qrp_mcp-0.44.0-py3-none-any.whl Python 3 none any Details for qrp_mcp-0.44.0-py3-none-any.whl

Total release size: 1.4 MB

Release files / qrp_mcp-0.44.0.tar.gz

Download URL qrp_mcp-0.44.0.tar.gz
Size 1.0 MB
Tags Source
SHA-256 checksum
How to use checksums
82bb5d6a971c95b9090e16dda56cffdf171daf2691a85b73e9f4465fb5d579b5
BLAKE2b-256 checksum
How to use checksums
78b4d271a22733847d0c971f448b7ccebc33ec1ce104729f5bdb451126b4efcb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Release files / qrp_mcp-0.44.0-py3-none-any.whl

Download URL qrp_mcp-0.44.0-py3-none-any.whl
Size 381.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6ed36c0c488dfafa7c7656878ad22cf0173312821414e953ef07c634fb938c83
BLAKE2b-256 checksum
How to use checksums
38f115d7b4b2deb831efae259bfa062cdf5f58a47c1a0917ab2c86aae70e9ac4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Security for qrp-mcp 0.44.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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

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.44.0 This release

2 release files No 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