@quantakrypto/mcp
v0.10.0
Published
quantakrypto MCP — post-quantum readiness for AI coding agents via the Model Context Protocol. Zero runtime dependencies (stdio JSON-RPC implemented in-house).
Readme
@quantakrypto/mcp
A Model Context Protocol (MCP) server that gives AI coding agents post-quantum
readiness superpowers. It scans code for classical (quantum-vulnerable) asymmetric
cryptography and recommends NIST post-quantum / hybrid migrations, all backed by
@quantakrypto/core.
- Zero runtime dependencies. The MCP / JSON-RPC 2.0 protocol is implemented
from scratch on Node built-ins (
node:readline,node:http,node:process). The only dependency is@quantakrypto/core. - Two transports. A
stdiotransport (thequantakrypto-mcpbin) for local agents like Claude, and a hostablehttptransport for running quantakrypto as a remote service (see HOSTING.md). quantakrypto also runs a hosted, OAuth-gated instance atmcp.quantakrypto.comyou can connect to directly — see Hosted HTTP server. - Transport-agnostic core. All protocol logic lives in a pure, unit-tested
McpServerclass; transports only do I/O.
Install / register with an MCP client
The published package exposes a quantakrypto-mcp binary that speaks MCP over stdio:
# Claude Code / Claude Desktop
claude mcp add quantakrypto npx @quantakrypto/mcpEquivalently, in an MCP client config:
{
"mcpServers": {
"quantakrypto": {
"command": "npx",
"args": ["@quantakrypto/mcp"]
}
}
}The bin is quantakrypto-mcp (→ dist/stdio.js). You can also run it directly:
node dist/stdio.jsProtocol
MCP stdio transport is newline-delimited JSON: exactly one JSON-RPC 2.0
message per line on stdin/stdout (this is not HTTP-style Content-Length
framing). Supported methods:
| Method | Notes |
| --- | --- |
| initialize | Replies with protocolVersion, capabilities.tools.listChanged = false, and serverInfo { name: "quantakrypto", version }. |
| notifications/initialized | Notification; no response. |
| ping | Replies {}. |
| tools/list | Lists all tools with JSON-Schema inputSchema. |
| tools/call | Runs a tool, returns { content: [...], isError? }. |
Unknown methods return JSON-RPC error -32601; bad params return -32602;
unparseable input returns -32700; non-request objects return -32600.
Tools
Each tool returns MCP content: { content: [{ type: "text", text }], isError? }.
scan_path
Scan a file or directory for quantum-vulnerable cryptography.
{
"type": "object",
"properties": {
"path": { "type": "string", "description": "Path to scan." },
"format": { "type": "string", "enum": ["summary", "json"] }
},
"required": ["path"]
}Returns a readiness summary (or the raw ScanResult JSON when format: "json").
inventory_crypto
Produce a 0–100 readiness score plus counts by algorithm, category, and severity.
{
"type": "object",
"properties": { "path": { "type": "string" } },
"required": ["path"]
}explain_finding
Explain a finding and its remediation. Provide a ruleId, an algorithm, or both.
{
"type": "object",
"properties": {
"ruleId": { "type": "string" },
"algorithm": { "type": "string", "description": "RSA, ECDH, ECDSA, …" }
}
}suggest_hybrid
Recommend a PQC / hybrid migration from an algorithm or free-text context.
{
"type": "object",
"properties": {
"algorithm": { "type": "string" },
"context": { "type": "string" }
}
}list_rules
List the quantakrypto detector catalog (ids + descriptions). No input.
{ "type": "object", "properties": {} }generate_cbom
Scan a path and emit a CycloneDX 1.6 Cryptographic Bill of Materials (CBOM)
of the classical cryptographic assets found, for compliance / supply-chain
tooling. Reads the filesystem, so it is gated like scan_path over HTTP.
{
"type": "object",
"properties": { "path": { "type": "string" } },
"required": ["path"]
}Copilot tools — migrate through the engine
These let an AI coding agent do a PQC migration through the deterministic engine ("the model proposes, the engine disposes"): the agent plans, edits, and re-verifies against the same detectors the CLI uses, so nothing is claimed fixed that the scanner still flags.
plan_migration— scan a path and return a prioritized, phased plan (harvest-now-decrypt-later first, then signatures, then transport/certs), each group with its PQC target and locations. Reads the filesystem, so it is gated likescan_pathover HTTP.{ path }.get_fix_examples— before/after migration code for a classicalalgorithm(or a finding'sruleId). No filesystem access.verify_fix— run the detectors over acodesnippet (pluslanguageorfilename) and report any classical crypto that remains. The agent's fix-confirmation loop. No filesystem access.check_dependency— look a packagename(+ecosystem, default npm) up in the vulnerable-dependency database. No filesystem access.score_delta— readiness-score / HNDL change between two finding sets (before,afterfromscan_path --format json). No filesystem access.triage_findings— deterministic, offline, key-free. Emits a triage REQUEST bundle (rubric + verdict schema + per-finding metadata + fingerprints) for the host agent to reason over. It never calls a model. No filesystem access.apply_triage— deterministically attach the host agent's verdicts to their findings (matched by fingerprint) and re-sort by exposure. Never suppresses; malformed verdicts are ignored. No filesystem access.remediate_findings— deterministic, offline, key-free. Emits a fix REQUEST bundle (rubric + fix schema + per-finding metadata + fingerprints) for the host agent to fix: propose the corrected file, verify withverify_fix, keep only verified fixes. Never merges. No filesystem access.
Triage on the MCP plane keeps the "engine disposes" guarantee: the server stays offline and never holds an API key — the host agent (which already has the code open) does the reasoning, and
apply_triagerecords it deterministically. The BYOK client that calls a provider directly lives only inqscan --triage(for CI, where there is no host agent).
Resources & prompts
Beyond tools, the server exposes MCP resources and a prompt (advertised in
the initialize capabilities, all offline/static):
resources/list+resources/read—quantakrypto://rules(the full rule catalog as JSON) andquantakrypto://guide/migration(a Markdown migration guide).prompts/list+prompts/get— themigrateprompt (optionalpatharg): a ready-made "scan → triage → remediate → verify, draft PR only" workflow.
Hosted HTTP server (safe-by-default)
Just want to use it? quantakrypto runs a hosted, OAuth-gated instance at
https://mcp.quantakrypto.com/mcp— no install, no token to manage:claude mcp add --transport http quantakrypto https://mcp.quantakrypto.com/mcpIt signs you in (Google / GitHub / email) and issues a 30-day token. Being multi-tenant, it exposes only the content-based tools — the filesystem/network tools (
scan_path,inventory_crypto,generate_cbom,plan_migration,probe_endpoint) are withheld; run the MCP locally for those. Source and ops:quantakrypto/mcp-gateway. The rest of this section is for running the package's ownhttp.tsyourself.
The same McpServer can be served over HTTP (a Streamable-HTTP-style JSON-RPC
endpoint) for remote deployments. The stdio transport trusts the local user and
is fully featured; the HTTP transport is hardened, because a hosted endpoint
is reachable by untrusted peers:
- Binds to
127.0.0.1by default (not0.0.0.0). Override viaQUANTAKRYPTO_MCP_HOST. Binding to a non-loopback host without a token is refused at startup (it would be an open, unauthenticated tool relay). - Bearer-token auth. Set
QUANTAKRYPTO_MCP_TOKENand every/mcprequest must sendAuthorization: Bearer <token>, else401. With no token set, only the loopback bind is allowed. - Filesystem tools are disabled by default.
scan_path,inventory_crypto,generate_cbomandplan_migrationread arbitrary server paths, so over HTTP they are exposed only whenQUANTAKRYPTO_MCP_ALLOW_FS=1. The knowledge / copilot tools that take no path (explain_finding,suggest_hybrid,list_rules,get_fix_examples,verify_fix,check_dependency,score_delta,triage_findings,apply_triage,remediate_findings) are always available.tools/listandtools/callboth reflect the gating. - The networked probe tool is disabled by default.
probe_endpoint(active TLS/SSH probing) is the only tool that opens a socket. Over HTTP it is exposed only whenQUANTAKRYPTO_MCP_ALLOW_NETWORK=1— a hosted server should not probe arbitrary hosts. On the local stdio transport it is always available. It still requires the per-call ownership attestation (i_own_this=true) and refuses ranges/CIDRs regardless of transport. - Filesystem tools are root-confined. Even with
QUANTAKRYPTO_MCP_ALLOW_FS=1, every scanned path must resolve inside theQUANTAKRYPTO_MCP_ROOTallow-list (:-separated; the process CWD by default)...traversal and out-of-root absolute paths (e.g./etc/passwd) are rejected — the server is not an arbitrary-file-read oracle. - Origin validation.
POST /mcprejects a browser request whoseOriginhost is not loopback (or allow-listed viaQUANTAKRYPTO_MCP_ALLOW_ORIGIN), defending the default no-token loopback config against DNS-rebinding / localhost-CSRF. Non-browser clients (noOrigin) are unaffected. - Limits + work budgets. A 1 MiB request-body cap (
413only on the cap,400on a transport error), a per-request tool timeout that aborts the underlying scan (QUANTAKRYPTO_MCP_TIMEOUT_MS, default 30000 →504), a response-size cap (QUANTAKRYPTO_MCP_MAX_RESPONSE_BYTES, default 4 MiB), and per-scan work budgets (QUANTAKRYPTO_MCP_MAX_FILES/QUANTAKRYPTO_MCP_MAX_BYTES) so a single call cannot exhaust host resources.
| Env var | Default | Purpose |
| --- | --- | --- |
| QUANTAKRYPTO_MCP_HOST (or HOST) | 127.0.0.1 | Bind interface. Non-loopback requires a token. |
| PORT | 3000 | Listen port. |
| QUANTAKRYPTO_MCP_TOKEN | (unset) | When set, requires Authorization: Bearer <token>. |
| QUANTAKRYPTO_MCP_ALLOW_FS | (off) | 1/true exposes the filesystem tools over HTTP. |
| QUANTAKRYPTO_MCP_ALLOW_NETWORK | (off) | 1/true exposes the networked probe_endpoint tool over HTTP. |
| QUANTAKRYPTO_MCP_ROOT | (cwd) | :-separated allow-list of directories the FS tools may scan. |
| QUANTAKRYPTO_MCP_ALLOW_ORIGIN | (loopback) | Comma-separated extra Origin hosts allowed on /mcp. |
| QUANTAKRYPTO_MCP_TIMEOUT_MS | 30000 | Per-request deadline; aborts the in-flight scan on timeout. |
| QUANTAKRYPTO_MCP_MAX_RESPONSE_BYTES | 4194304 | Response-body size cap. |
| QUANTAKRYPTO_MCP_MAX_FILES | 25000 (cap 250000) | Max files a single scan may read. |
| QUANTAKRYPTO_MCP_MAX_BYTES | 268435456 (cap 2 GiB) | Max cumulative bytes a single scan may read. |
# Local, knowledge tools only (default safe posture)
node dist/http.js
# Local with the filesystem tools enabled
QUANTAKRYPTO_MCP_ALLOW_FS=1 node dist/http.js
# Reachable from the network: a token is mandatory
QUANTAKRYPTO_MCP_HOST=0.0.0.0 QUANTAKRYPTO_MCP_TOKEN="$(openssl rand -hex 32)" node dist/http.jsEndpoints:
POST /mcp— one JSON-RPC 2.0 message; the JSON-RPC response is theapplication/jsonbody. Notifications get202with no body. Anmcp-session-idheader is echoed or minted on each request.GET /health— liveness probe returning{ "status": "ok" }(no auth).
curl -s localhost:3000/health
curl -s localhost:3000/mcp \
-H 'content-type: application/json' \
-H 'authorization: Bearer YOUR_TOKEN' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'See HOSTING.md for the full production design (auth, multi-tenant
sessions, rate limiting, scaling). A sample request/response transcript lives in
examples/transcript.jsonl.
Programmatic use
import { createQuantakryptoServer } from "@quantakrypto/mcp";
const server = createQuantakryptoServer();
const res = await server.handle({ jsonrpc: "2.0", id: 1, method: "tools/list" });Development
npm run build # tsc -b
npm test # node --import tsx --test test/*.test.tsTests drive McpServer.handle directly (and the stdio loop via in-memory
streams) — no process spawning.
License
Apache-2.0
Support & training
Questions, commercial support, or post-quantum readiness training for your team — visit quantakrypto.com or email [email protected].
