# Post Quantum Mcp

> MCP server for post-quantum cryptography (ML-KEM, ML-DSA, SLH-DSA) with hybrid X25519+ML-KEM-768 key exchange. Research/prototyping tooling using liboqs.

- **Type:** MCP server
- **Install:** `agentstack add mcp-scottdhughes-post-quantum-mcp`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [scottdhughes](https://agentstack.voostack.com/s/scottdhughes)
- **Installs:** 0
- **Category:** [Integrations](https://agentstack.voostack.com/c/integrations)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [scottdhughes](https://github.com/scottdhughes)
- **Source:** https://github.com/scottdhughes/post-quantum-mcp

## Install

```sh
agentstack add mcp-scottdhughes-post-quantum-mcp
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## 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](https://github.com/open-quantum-safe/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](https://openquantumsafe.org/). 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

- Python 3.10+
- [liboqs](https://github.com/open-quantum-safe/liboqs) shared library
- [uv](https://github.com/astral-sh/uv) (recommended) or pip

### Installation

#### 1. Install liboqs

**macOS (Homebrew with shared library):**
```bash
# 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:**
```bash
sudo apt-get install liboqs-dev
```

**Alternative:** Use the bundled install script which automates the above:
```bash
bash scripts/install-liboqs.sh
```

#### 2. Clone and Install

```bash
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`):**
```json
{
  "mcpServers": {
    "pqc": {
      "type": "stdio",
      "command": "/path/to/post-quantum-mcp/run.sh",
      "args": [],
      "env": {}
    }
  }
}
```

**Claude Desktop (`claude_desktop_config.json`):**
```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)**
```json
// 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):**
```json
// 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).

```json
// 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**
```json
// 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)**
```json
// 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.

```json
// 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.

```json
// 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.

```json
// 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.

```json
// 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.

```json
// 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
```json
// 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
```json
// 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](https://github.com/scottdhughes)
- **Source:** [scottdhughes/post-quantum-mcp](https://github.com/scottdhughes/post-quantum-mcp)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/mcp-scottdhughes-post-quantum-mcp
- Seller: https://agentstack.voostack.com/s/scottdhughes
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
