Spec Driven Development
MCP Server that facilitates spec-driven development workflows, not just Vibe Coding.
제작자가 쓴 설명(영어 원문)
QRNG-seeded random bytes, seeds, and ML-KEM-768 keys with signed provenance receipts.
이 세 가지는 절대 하나의 점수로 합치지 않아요. 의견, 측정, 인기는 서로 다른 것이니까요.
이 서버는 아직 쉬운 말로 된 요약을 쓰지 못했어요. 아래는 레지스트리에서 읽어 온 사실이에요.
쓰고 있는 AI 앱을 고른 다음 설정을 복사하세요.
필요한 것
어떤 앱을 쓰세요?
위에서 앱을 고르세요. 기억해 두었다가 다음부터는 버튼에 “…에 설치”라고 표시해요.
웹, 데스크톱, 모바일의 Claude에서 쓸 수 있어요:
https://api.qeaas.eu/mcp터미널에서 이 명령어를 실행하세요
claude mcp add --transport http qeaas https://api.qeaas.eu/mcp프로젝트의 .cursor/mcp.json 또는 ~/.cursor/mcp.json에 붙여 넣으세요
{
"mcpServers": {
"qeaas": {
"url": "https://api.qeaas.eu/mcp"
}
}
}브라우저가 앱을 열지 물어본 다음, 앱이 설정을 보여 주고 확인을 요청해요. 키 값은 비워 두니 직접 입력하세요.
프로젝트의 .vscode/mcp.json에 붙여 넣으세요
{
"servers": {
"qeaas": {
"type": "http",
"url": "https://api.qeaas.eu/mcp"
}
}
}브라우저가 앱을 열지 물어본 다음, 앱이 설정을 보여 주고 확인을 요청해요. 키 값은 비워 두니 직접 입력하세요.
ChatGPT는 인터넷에 있는 서버에만 연결할 수 있어요:
https://api.qeaas.eu/mcp메뉴 이름은 요금제나 시기에 따라 조금 다를 수 있어요.
선택한 앱은 이 기기의 쿠키에만 저장돼요. 계정은 필요 없어요.
이 설정은 제작자의 레지스트리 정보로 만들었어요. README와 다르면 README를 따르세요.
아직 이 서버의 도구 목록을 읽지 않았어요. 엔드포인트는 차례대로 돌아가며 점검해요.
누구나 볼 수 있는 정보를 점검했고, 코드는 읽지 않았어요. 해당하지 않는 항목은 개수에서 뺐어요. · 2026년 11월 7일 점검
게시자(qeaas.eu)가 저장소 소유자(PeterJasSK)가 아니에요. 다른 사람이 등록했을 수 있어요
아직 GitHub에서 이 저장소를 읽어 오지 않았어요
아직 GitHub에서 이 저장소를 읽어 오지 않았어요
아직 점검하지 않았어요. 엔드포인트는 차례대로 돌아가며 점검해요
아직 점검하지 않았어요. 엔드포인트는 차례대로 돌아가며 점검해요
아직 점검하지 않았어요. 엔드포인트를 점검할 때 도구 목록을 읽어요
레지스트리에서 이 카테고리의 활성 서버 전체와 비교했어요. 스타는 게시자가 저장소를 소유한 경우에만 세요.
해당하는 기본 점검 1개 중 0개를 통과했어요. 코드는 읽지 않았어요. 키나 토큰을 넣기 전에 서버가 어떤 권한을 요구하는지 확인하고, 꼭 필요한 권한만 있는 키를 쓰세요.
레지스트리에 필수 키가 나와 있지 않아요. 다만 처음 쓸 때 로그인을 요구하는 서버도 있어요.
제작자의 클라우드에서 실행돼요. 설치 없이 인터넷으로 연결하지만, 보내는 내용은 제작자의 서버를 거쳐요.
GitHub 저장소는 마지막으로 – 변경됐고, 최신 버전(1.0.0)은 3개월 전 레지스트리에 올라왔어요.
Claude Desktop, Claude Code, Cursor, VS Code처럼 MCP를 지원하는 앱에서 쓸 수 있어요. URL로 연결되기 때문에, 원격 MCP 서버를 지원하는 앱(예: 개발자 모드의 ChatGPT)에서도 쓸 수 있어요.
같은 카테고리에는: Spec Driven Development, Remote Desktop Commander, Signoff
같은 카테고리에서 다른 제작자가 만든 서버예요. 스타 순으로 정렬했어요.
카드 보는 법:★ GitHub 스타i세 기둥: 리뷰 · 점검 · 사용 정도i업데이트 = 최신 버전을 레지스트리에 공개한 날i
MCP Server that facilitates spec-driven development workflows, not just Vibe Coding.
Remote Desktop Commander: use files, terminal and processes on your own computers from any AI app.
Five gates that make an agent's 'done' provable: run them, read the verdict, audit the record.
제작자의 저장소에서 쓰인 그대로 가져왔어요. PopNx MCP가 검토하거나 보증한 내용이 아니에요. HTML, 이미지, 스크립트는 제거했어요. 링크를 누르면 이 사이트를 벗어나요.
Want an API key? Email peter.jas@cnl.sk.
FastAPI service that turns preloaded QRNG (quantum random number generator) bits into served randomness, dice rolls, cryptographic seeds, and post-quantum ML-KEM key material — each issue carrying a signed, offline-verifiable provenance receipt.
Monorepo layout: api/ (this document — FastAPI service), web/ (Next.js explainer + demo), shared/ (docs, spikes), claude/ (epic build plans). The web app is a thin client over the API; everything substantive happens here.
Honest framing, stated once and meant everywhere. QRNG does not "defeat quantum
attackers." Raw QRNG bits are *never served*. They are entropy that **seeds a standards
HMAC-DRBG** (NIST SP 800-90A). Every byte this API returns —
/random,/dice,/v1/random/bytes,
ML-KEM seeds — is DRBG output. The quantum part is the *entropy source*; any quantum
*resistance* comes from ML-KEM-768 (FIPS 203), not from the randomness being "quantum."
┌──────────── admin (X-Admin-Token) ────────────┐
│ │ QRNG .txt │ POST /admin/ingest │ POST /admin/keys (0/1 bits) ▼ ▼ POST /admin/keys/revoke ┌─────────────┐ AES-256-GCM ┌───────────────────────────────┐ │ pool.parse │ ───────────────▶ │ Postgres (Neon) │ │ + encrypt │ │ entropy_pool (ciphertext) │ └─────────────┘ │ drbg_root (ciphertext) │ │ api_keys / usage_log / │ │ issue_log │ └───────────────┬───────────────┘ │ decrypt slice on reseed ▼ client ┌───────────────────────────────────────┐ ─────────▶ entropy gate │ keyed_drbg.output(n) │ request (503 if low) │ root_key ← reseeded from pool │
db.connect); there is no long-lived pool object. DRBG state is never read-modify-written per request — see §4.WEB_ORIGIN (comma-separated).main.py).Source map (api/qeaas/):
| Module | Responsibility |
|---|---|
main.py | FastAPI app, all route handlers, CORS, entropy header middleware |
generation.py | The single served-randomness choke point + provenance metadata builder |
keyed_drbg.py | Serverless-safe DRBG wrapper: reseed schedule, Redis-counter mixing |
drbg.py | Pure NIST SP 800-90A HMAC-DRBG (SHA-256) |
pool.py | Entropy pool: parse 0/1, AES-256-GCM encrypt/decrypt, HKDF sub-keys, burn() |
db.py | Parameterized psycopg helpers for all five tables |
redis_client.py | Lazy Upstash client: atomic counter + rate-limit ops |
gate.py | Low-entropy gate (entropy_level, require_entropy dependency) |
auth.py | Admin-token guard, API-key hashing + validation |
ratelimit.py | Per-IP / per-key rate limits, anon daily ceiling, per-key quota |
dice.py | Rejection-sampled dice (no modulo bias) |
kem.py | QRNG-seeded ML-KEM-768 keygen + encapsulation |
receipts.py | Ed25519 receipt signing + verification |
errors.py | Flat {"error": " "} envelope for every failure |
schemas.py | Pydantic request/response models |
Every served byte flows through one choke point, generation.random_bytes(n) → keyed_drbg.output(n). Nothing bypasses it.
A. Ingest (admin, offline of the request path). POST /admin/ingest → pool.ingest_bits_bytes() → pool.parse_bits_bytes() packs the 0/1 text MSB-first into bytes (discarding a trailing partial byte, rejecting any non-0/1 char) → pool.encrypt_chunk() AES-256-GCM-encrypts it → db.insert_pool_chunk() stores (ciphertext, nonce, tag, plaintext_len, source_label) in `entropy_pool`. Plaintext never touches disk; the upload buffer is burn()-ed.
B. Serve (per request). keyed_drbg.output(n):
maybe_reseed() — loads the warm root-key cache (_load_cache), bootstrapping the root key from the pool on very first use (_bootstrap_root_key). If the reseed schedule is due (§4), pool.pull_reseed_material(32) decrypts the next unconsumed 32-byte slice from entropy_pool, encrypts it as the new drbg_root row, advances consumed_offset, and burn()s the plaintext.redis_client.incr_counter() — atomic INCR drbg:counter, returns a globally unique integer.HmacDrbg is instantiated with the decrypted root_key and generate(n, additional = counter.to_bytes(8) + additional) is called — the counter guarantees two concurrent requests can never produce identical output even with identical root key.db.bump_outputs_since_reseed() increments the reseed odometer.C. Wrap (per endpoint). generation.new_issue_meta(size) mints a request_id (uuid4), reads entropy_epoch (= drbg_root.reseed_counter), timestamps, and calls receipts.sign(...) to produce the Ed25519 receipt. Keyed endpoints then write db.insert_usage_log() (abuse spotting) and db.insert_issue_log() (metadata-only provenance — no output bytes are ever stored).
See the deep-dive comment at the end of this file / in the chat analysis for the exact call graph.
They protect against completely different failure modes and have opposite consistency needs.
Holds everything that must survive and must be transactional & durable. Five tables:
| Table | Holds | Notes |
|---|---|---|
entropy_pool | AES-256-GCM ciphertext of QRNG bits + nonce, tag, plaintext_len, consumed_offset, source_label | The vault. No plaintext-bytes column exists. consumed_offset tracks how much of each chunk has been spent. |
drbg_root | AES-256-GCM ciphertext of the current DRBG root seed + reseed_counter, outputs_since_reseed, rotated_at | The live DRBG key, rotated ("reseeded") from the pool on schedule. reseed_counter == entropy_epoch in receipts and drbg_reseeds in /health. |
api_keys | key_hash (HMAC-SHA256, peppered), owner, tier, daily_quota_bytes, revoked, created_at | Plaintext keys never stored. Read fresh every request so revocation is instant. |
usage_log | (ts, principal, endpoint, nbytes) | Abuse-spotting ledger for keyed issues. Anon /random//dice are not logged here. |
issue_log | (request_id, principal, endpoint, size, epoch_id, ts) | Metadata-only provenance. No output-bytes column exists, ever — verify provenance, not the secret. |
Durability matters: lose the pool ciphertext or the root key and the service can no longer prove provenance or reseed. Postgres is ACID; this is where correctness lives.
Holds only fast, disposable, atomically-mutated counters that would be a correctness hazard in Postgres under serverless concurrency:
| Key | Purpose | Op |
|---|---|---|
drbg:counter | Output uniqueness. Monotonic integer mixed into every DRBG call so two concurrent serverless invocations can't emit the same bytes. | INCR |
rl:ip:{ip}:{minute} | Per-IP rate limit (anon routes) | INCR + EXPIRE 60 |
rl:key:{hash}:{minute} | Per-key rate limit | INCR + EXPIRE 60 |
anon:daily:{day} | Global anon output ceiling (5 MB/day) | INCRBY + EXPIRE, DECRBY on refund |
quota:key:{hash}:{day} | Per-key daily byte quota | INCRBY + EXPIRE, DECRBY on refund |
Why not put these in Postgres? On stateless serverless you cannot safely read-modify-write shared state per request — two concurrent requests would race. Redis INCR/INCRBY are atomic, so there is no read-modify-write. These values are *meant* to expire (per-minute, per-day) and losing them is harmless — throttling fails open on a Redis outage (logs a warning, allows the request), because the reseed-frequency floor (§4) still guarantees the pool can't be drained.
One-line summary: Postgres = durable secrets + audit that must be correct forever; Redis = ephemeral atomic counters that must be fast and race-free but are disposable.
drbg.py). Not thread-safe — each request gets its own instance.keyed_drbg.py): output(n) = HMAC-DRBG(root_key, INCR(drbg:counter), n).root_key rotates from the pool on whichever fires first:RESEED_INTERVAL_SECONDS), orRESEED_OUTPUT_LIMIT (100 000) but only if ≥ RESEED_MIN_INTERVAL_SECONDS (5 minutes) has elapsed. Each reseed pulls RESEED_PULL_BYTES (32) from the pool.THRESHOLD (64 KiB) of unconsumed pool bytes, /health reports degraded and all gated routes 503 low_quantum_entropy (gate.require_entropy).One env-held MASTER_KEY (256-bit hex). pool.derive_subkey(name) (HKDF-SHA256, RFC 5869 one-block Expand) derives exactly four named sub-keys — there are no other secrets:
MASTER_KEY (env / KMS only — never written to Postgres)
└── HKDF-SHA256 ├── "pool-encryption-key" → entropy_pool AES-256-GCM ├── "drbg-root-encryption-key" → drbg_root.root_key AES-256-GCM ├── "api-key-pepper" → API-key hashing (HMAC-SHA256) └── "receipt-signing-key" → Ed25519 receipt signing seed
AES-256-GCM is authenticated: a flipped ciphertext byte fails the tag check and decryption raises — the service fails closed on tampered storage. Sensitive plaintext (decrypted slices, the warm root-key cache, upload buffers) is held in bytearray and best-effort burn()-ed after use (CPython cannot *guarantee* zeroization; serverless teardown keeps in-process secrets short-lived by design).
| Mechanism | Header | Applies to |
|---|---|---|
| None (anonymous) | — | /health, /random, /dice, /v1/verify, /v1/pubkey |
| API key | X-API-Key: | /v1/random/bytes, /v1/kem/* |
| Admin token | X-Admin-Token: | /admin/* |
hash_api_key(key) = HMAC-SHA256(pepper, key); only the hash is stored. require_api_key reads the row fresh every request, so revoked = true앞부분만 보여 드려요. 나머지는 저장소에서 읽어 보세요