Install
$ agentstack add mcp-scottdhughes-post-quantum-mcp ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Post-Quantum Cryptography MCP Server
[](https://opensource.org/licenses/MIT) [](https://www.python.org/downloads/) [](https://openquantumsafe.org/) [](https://modelcontextprotocol.io/)
> Research and Prototyping Only. This server uses liboqs, which is explicitly not recommended for production use or for protecting sensitive data. When using store_as mode (recommended), secret keys are redacted from tool output and held in a session-scoped keyring. Without store_as, secret keys and shared secrets appear in tool output, which may enter model context, client logs, or transcripts. Set PQC_REQUIRE_KEY_HANDLES=1 to enforce handle-only mode for all secret-key operations. Suitable for experimentation, education, and interoperability testing.
A Model Context Protocol (MCP) server that provides post-quantum cryptographic operations using Open Quantum Safe's liboqs. Enables AI assistants like Claude to perform quantum-resistant cryptographic operations including key generation, encryption, signing, and verification.
Why Post-Quantum Cryptography?
Current cryptographic systems (RSA, ECC, ECDSA) will be broken by quantum computers running Shor's algorithm. NIST has standardized new quantum-resistant algorithms:
| Standard | Algorithm | Type | Status | |----------|-----------|------|--------| | FIPS 203 | ML-KEM (formerly CRYSTALS-Kyber) | Key Encapsulation | Finalized 2024 | | FIPS 204 | ML-DSA (formerly CRYSTALS-Dilithium) | Digital Signature | Finalized 2024 | | FIPS 205 | SLH-DSA (formerly SPHINCS+) | Hash-based Signature | Finalized 2024 |
This MCP server makes these algorithms accessible to AI agents for research, development, and integration.
Features
- Key Encapsulation Mechanisms (KEMs) available via liboqs: ML-KEM, FrodoKEM, HQC, BIKE, Classic McEliece
- Signature algorithms available via liboqs: ML-DSA, Falcon, SLH-DSA, MAYO, CROSS, UOV
- Full MCP Integration: Works with Claude Desktop, Claude Code, Cursor, and any MCP client
- Supports NIST-standardized algorithms: Implements FIPS 203, 204, and 205 algorithms
- Security Analysis: Compare classical vs quantum security levels
Quick Start
Prerequisites
Installation
1. Install liboqs
macOS (Homebrew with shared library):
# Homebrew only provides static library, build from source for shared:
git clone --depth 1 --branch 0.15.0 https://github.com/open-quantum-safe/liboqs.git
cd liboqs && mkdir build && cd build
cmake -DBUILD_SHARED_LIBS=ON -DCMAKE_INSTALL_PREFIX=$HOME/.local ..
make -j4 && make install
Ubuntu/Debian:
sudo apt-get install liboqs-dev
Alternative: Use the bundled install script which automates the above:
bash scripts/install-liboqs.sh
2. Clone and Install
git clone https://github.com/scottdhughes/post-quantum-mcp.git
cd post-quantum-mcp
# Install all dependencies (creates .venv automatically)
uv sync --all-extras
3. Configure Claude Code / Claude Desktop
Add to your MCP configuration:
Claude Code (~/.claude.json):
{
"mcpServers": {
"pqc": {
"type": "stdio",
"command": "/path/to/post-quantum-mcp/run.sh",
"args": [],
"env": {}
}
}
}
Claude Desktop (claude_desktop_config.json):
{
"mcpServers": {
"pqc": {
"command": "/path/to/post-quantum-mcp/run.sh"
}
}
}
The server can also be run directly via python -m pqc_mcp_server.
Available Tools
pqc_list_algorithms
List all available post-quantum algorithms.
Input: { "type": "kem" | "sig" | "all" }
Output: List of available algorithms with NIST standard mappings
pqc_algorithm_info
Get detailed information about a specific algorithm.
Input: { "algorithm": "ML-KEM-768" }
Output: Key sizes, security level, performance characteristics
pqc_generate_keypair
Generate a quantum-resistant key pair.
Input: { "algorithm": "ML-DSA-65" }
Output: Base64-encoded public and secret keys
pqc_encapsulate
Perform key encapsulation (create shared secret).
Input: { "algorithm": "ML-KEM-768", "public_key": "" }
Output: Ciphertext and shared secret
pqc_decapsulate
Recover shared secret from ciphertext.
Input: { "algorithm": "ML-KEM-768", "secret_key": "", "ciphertext": "" }
Output: Shared secret
pqc_sign
Sign a message with a post-quantum signature.
Input: { "algorithm": "ML-DSA-65", "secret_key": "", "message": "Hello, quantum world!" }
Output: Base64-encoded signature
pqc_verify
Verify a post-quantum signature.
Input: { "algorithm": "ML-DSA-65", "public_key": "", "message": "...", "signature": "" }
Output: { "valid": true/false }
pqc_hash
Hash a message using quantum-safe hash functions.
Input: { "message": "data", "algorithm": "SHA3-256" | "SHA3-512" | "SHAKE128" | "SHAKE256" }
Output: Digest in hex and base64
pqc_security_analysis
Analyze security properties of an algorithm.
Input: { "algorithm": "ML-KEM-768" }
Output: NIST level, classical/quantum security equivalents, Grover/Shor resistance
Hybrid Key Exchange (X25519 + ML-KEM-768)
Suite: mlkem768-x25519-sha3-256 — borrows the KEM combiner from the LAMPS composite ML-KEM draft (id-MLKEM768-X25519-SHA3-256). The sha3-256 in the suite name refers to the KEM combiner hash; HKDF key derivation uses SHA-256 (via cryptography HKDF). The sealed-envelope layer is this project's own protocol built on top of that combiner.
This is an anonymous sealed-box construction providing hybrid confidentiality with ciphertext integrity. It is not forward-secret against recipient key compromise, and it is not sender-authenticated.
pqc_hybrid_keygen
Generate a hybrid keypair bundle.
Recommended: with store_as (secret keys redacted)
// Input
{"store_as": "alice"}
// Output — no secret keys
{
"suite": "mlkem768-x25519-sha3-256",
"handle": "alice",
"classical": {"algorithm": "X25519", "public_key": "DeRN3xLbEglMdXKO7P98cAvc...", "fingerprint": "a1b2c3d4..."},
"pqc": {"algorithm": "ML-KEM-768", "public_key": "gDsL8UgEVcMeJgUOQgSlAotx...", "fingerprint": "e5f6a7b8..."}
}
Without store_as (raw keys returned — not recommended):
// Input
{}
// Output — secret keys exposed in tool output
{
"suite": "mlkem768-x25519-sha3-256",
"classical": {
"algorithm": "X25519",
"public_key": "DeRN3xLbEglMdXKO7P98cAvc...",
"secret_key": "YEYD9j5c2hpTei0ferXWbAFb..."
},
"pqc": {
"algorithm": "ML-KEM-768",
"public_key": "gDsL8UgEVcMeJgUOQgSlAotx...",
"secret_key": "MQB2U0EzNGmloLuiTYG3BTcr..."
}
}
pqc_hybrid_encap / pqc_hybrid_decap
Building-block key encapsulation. Returns a combined shared secret derived via the suite's SHA3-256 combiner.
pqc_hybrid_seal / pqc_hybrid_open
Encrypt/decrypt plaintext using hybrid encapsulation + AES-256-GCM. Full-header AAD binding. Deterministic nonce (not transmitted in envelope).
// Seal input
{
"plaintext": "Hello, quantum world!",
"recipient_classical_public_key": "",
"recipient_pqc_public_key": ""
}
// Seal output
{
"envelope": {
"version": "pqc-mcp-v3",
"mode": "anon-seal",
"suite": "mlkem768-x25519-sha3-256",
"x25519_ephemeral_public_key": "6+b1Y8AkgEycKL5wL2cIeSMv...",
"pqc_ciphertext": "DF+PYy4zx+OmnW8wLD3EL+4M...",
"ciphertext": "NnEap2fDq5+xTCwvHdKfy5Xj..."
}
}
// Open input
{
"envelope": { "...envelope from seal..." },
"classical_secret_key": "",
"pqc_secret_key": ""
}
// Open output
{
"suite": "mlkem768-x25519-sha3-256",
"plaintext": "Hello, quantum world!",
"plaintext_base64": "SGVsbG8sIHF1YW50dW0gd29ybGQh"
}
Example Hybrid Prompts
> "Generate a hybrid keypair and seal a message for me"
> "Perform a hybrid key exchange and show me the shared secret"
> "Encrypt 'classified data' using hybrid PQC and then decrypt it"
Authenticated Hybrid Envelopes
Adds sender authentication to the hybrid confidentiality layer using ML-DSA-65 (FIPS 204) signatures. The sender signs a canonical binary transcript covering the entire envelope. The recipient verifies sender identity before decryption.
This is a sender-authenticated sealed-envelope construction. It is still not forward-secret against later recipient long-term key compromise. The sealed-envelope layer is this project's own protocol.
pqc_hybrid_auth_seal
Encrypt + sign. Requires sender ML-DSA-65 signing keys + recipient hybrid keys.
Recommended: with key handles
// Input
{
"plaintext": "Authenticated message",
"recipient_key_store_name": "bob",
"sender_key_store_name": "alice-signing"
}
// Output
{
"envelope": {
"version": "pqc-mcp-v3",
"mode": "auth-seal",
"suite": "mlkem768-x25519-sha3-256",
"sender_signature_algorithm": "ML-DSA-65",
"sender_public_key": "0ji6POTItnZUX8rELwVwWSOV...",
"sender_key_fingerprint": "0f617ece2f1d04c0...",
"recipient_classical_key_fingerprint": "c1deade4a5300a9a...",
"recipient_pqc_key_fingerprint": "bb0e084213d6ac74...",
"x25519_ephemeral_public_key": "5LEikNANeJNhZSiq...",
"pqc_ciphertext": "ybgWc3ruG3JwXmr4...",
"ciphertext": "6OYdADdh0eH/LviD...",
"signature": "BOniPALs1kfhWcRh..."
}
}
Alternative: with raw keys (not recommended)
// Input
{
"plaintext": "Authenticated message",
"recipient_classical_public_key": "",
"recipient_pqc_public_key": "",
"sender_secret_key": "",
"sender_public_key": ""
}
pqc_hybrid_auth_open
Verify sender + decrypt. Requires either expected_sender_public_key or expected_sender_fingerprint. Signature is verified before decryption — auth failures are distinct from decrypt failures.
// Open with expected sender public key
{
"envelope": { "...envelope from auth_seal..." },
"classical_secret_key": "",
"pqc_secret_key": "",
"expected_sender_public_key": ""
}
// Or open with expected sender fingerprint
{
"envelope": { "...envelope from auth_seal..." },
"classical_secret_key": "...",
"pqc_secret_key": "...",
"expected_sender_fingerprint": "0f617ece2f1d04c0481aa0fe..."
}
// Output
{
"suite": "mlkem768-x25519-sha3-256",
"plaintext": "Authenticated message",
"plaintext_base64": "QXV0aGVudGljYXRlZCBtZXNzYWdl",
"sender_key_fingerprint": "0f617ece2f1d04c0481aa0fe...",
"sender_signature_algorithm": "ML-DSA-65",
"authenticated": true
}
pqc_hybrid_auth_verify
Verify sender signature on an authenticated envelope WITHOUT decrypting. No secret keys needed. Checks sender binding, fingerprint consistency, ML-DSA-65 signature, and timestamp freshness.
// Input
{
"envelope": { "...envelope from auth_seal..." },
"expected_sender_fingerprint": "0f617ece2f1d04c0..."
}
// Output
{
"verified": true,
"sender_key_fingerprint": "0f617ece2f1d04c0...",
"sender_signature_algorithm": "ML-DSA-65",
"version": "pqc-mcp-v3",
"mode": "auth-seal",
"replay_seen": false,
"timestamp": "1711929600"
}
pqc_envelope_inspect
Inspect envelope metadata without decrypting. No secret keys needed. Returns version, suite, fingerprints, and field sizes.
// Input
{"envelope": { "...any sealed or authenticated envelope..." }}
// Output
{
"version": "pqc-mcp-v3",
"mode": "auth-seal",
"suite": "mlkem768-x25519-sha3-256",
"authenticated": true,
"sender_key_fingerprint": "0f617ece2f1d04c0...",
"ciphertext_size": 1234,
"plaintext_size_approx": 1218,
"pqc_ciphertext_size": 1088,
"signature_size": 3309
}
pqc_fingerprint
Compute SHA3-256 fingerprint of a public key. Returns lowercase hex.
// Input
{"public_key": ""}
// Output
{"fingerprint": "a1b2c3d4e5f6...", "algorithm": "SHA3-256"}
pqc_benchmark
Benchmark a PQC algorithm: timed keygen, encap/sign, decap/verify, and key/ciphertext/signature sizes.
// Input
{"algorithm": "ML-KEM-768", "iterations": 10}
// Output — timing and size measurements
Key Generation Flow
1. Sender: generate ML-DSA-65 signing keys via pqc_generate_keypair
2. Recipient: generate hybrid keys via pqc_hybrid_keygen
3. Exchange public keys out-of-band
4. Sender: pqc_hybrid_auth_seal with both key sets
5. Recipient: pqc_hybrid_auth_open with expected sender identity
Example Authenticated Prompts
> "Generate an ML-DSA-65 signing keypair and a hybrid recipient keypair, then send an authenticated encrypted message"
> "Open this authenticated envelope and verify it came from the expected sender"
> "Seal a message to Bob and sign it with my ML-DSA key, then have Bob open it using my fingerprint"
Key Handles (Secret Redaction)
Opt-in mode where secret keys are stored process-locally and never appear in tool output. Handles are process-global and lost on server restart.
Generating with handles
// pqc_hybrid_keygen with store_as
{"store_as": "alice"}
// Output — no secret keys
{
"suite": "mlkem768-x25519-sha3-256",
"handle": "alice",
"classical": {"algorithm": "X25519", "public_key": "...", "fingerprint": "..."},
"pqc": {"algorithm": "ML-KEM-768", "public_key": "...", "fingerprint": "..."}
}
Using handles in downstream tools
// pqc_hybrid_seal with store name instead of raw keys
{
"plaintext": "Hello via handle!",
"recipient_key_store_name": "alice"
}
// pqc_hybrid_auth_seal with two store names
{
"plaintext": "Authenticated via handles",
"recipient_key_store_name": "alice",
"sender_key_store_name": "bob-signing"
}
Generic PQC tools (pqc_sign, pqc_verify, pqc_encapsulate, pqc_decapsulate) also accept key_store_name.
Providing both a store name and raw keys for the same role is an error.
Key Store Management
pqc_key_store_save: Save a keygen output by name for convenient reference. Session-scoped, no persistence.pqc_key_store_load: Load a stored key by name. Returns public material only for handle entries.pqc_key_store_list: List all stored keys with metadata (names, types, fingerprints). No secret material shown.pqc_key_store_delete: Delete a stored key by name.
Security Features
v3 Envelope Protocol
v3 envelopes are mode-bound: every envelope carries an explicit mode field (anon-seal or auth-seal) that is bound into HKDF info, AAD, and the auth transcript. This provides true cross-mode separation — ciphertext produced by one mode cannot be decrypted by the other, blocking auth-stripping downgrade attacks at the AEAD layer. AAD uses length-prefixed framing (self-delimiting) in v3. Authenticated envelopes include a signed timestamp field in the canonical transcript; on verification/open, the server checks freshness (default: 24 hours, configurable via max_age_seconds). Clock skew tolerance is 5 minutes.
Replay Protection
The server maintains a signature-digest cache (SHA3-256 of envelope signature bytes) with TTL. pqc_hybrid_auth_verify performs a read-only replay check. pqc_hybrid_auth_open performs check-before-decrypt and mark-after-success. The cache persists to ~/.pqc/state/replay-cache.json and survives server restarts. Max 50,000 entries with oldest-first eviction.
Envelope Size Validation
All envelopes are validated before any cryptographic processing: max 1MB per base64 field (ciphertext, pqc_ciphertext, signature, sender_public_key, x25519_ephemeral_public_key), max 50 fields total. Prevents memory bombs and resource exhaustion.
Server Security Policy
Set PQC_REQUIRE_KEY_HANDLES=1 to enforce handle-only mode: the server rejects any tool call that passes raw secret keys, forcing use of store_as/key_store_name for all secre
…
Source & license
This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: scottdhughes
- Source: scottdhughes/post-quantum-mcp
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.