kannaka-quantum
by kannaka-labs
README.md
# kannaka-quantum
[](https://glama.ai/mcp/servers/NickFlach/kannaka-quantum)
**Real quantum capabilities for [Kannaka](https://github.com/kannaka-labs/kannaka-memory), executed on actual quantum backends.**
Kannaka's memory is a *Holographic Resonance Medium* — recall is wave interference, and *"attention acts as gravity: wavefronts whose phase/amplitude align with the query are pulled forward."* That is, almost verbatim, the definition of **quantum amplitude amplification**. This package makes the correspondence literal: it runs Kannaka's recall — plus arbitrary circuits and a true-entropy source — on real quantum hardware.
It is a **multi-provider bridge** with **two surfaces over one core**:
- a **JSON CLI** — the Kannaka coding agent shells out to it to write & run quantum programs;
- an **MCP server** — any MCP client (Claude Code, the kannaka-tui harness, other agents) gets the same tools.
---
## Capabilities
| tool (MCP) / subcommand (CLI) | what it does |
|---|---|
| `quantum_devices` / `devices` | List QPUs + simulators across providers, with status, qubit counts, and cost. |
| `run_circuit` / `run` | Execute an **OpenQASM 3** circuit on a backend; returns measurement counts. |
| `quantum_random` / `qrng` | True quantum random bits from measurement collapse (not a PRNG) — a quantum entropy source for the medium's irrationality (Ξ) and dream noise. |
| `harvest` | Harvest raw bits from a **real** QPU into a local entropy reservoir (the free simulator is a PRNG and is refused). Spend-guarded. |
| `qrng-status` | Reservoir level, last-harvest provenance, and estimated refill cost. |
| `qrng-draw` | Draw bits from the reservoir — raw, or (`--expand`) seed a NIST SP 800-90A **HMAC-DRBG** and expand. Every draw carries a provenance chain back to a QPU `job_id`; an empty reservoir fails loudly (no silent PRNG fallback). |
| `calibrate` | Rank candidate qubits by retained P(1) after a delay on the native Rigetti route, so `bench --layout` runs on the best ones that day. |
| `resonance_recall` / `recall` | **The showcase.** Amplitude-encode candidate memory resonances into a quantum state and amplitude-amplify toward the strongest — Kannaka's recall, run as interference on a quantum computer. |
---
## Providers & routing
A single **device string** selects both the provider and the backend. The prefix routes:
| device string | provider | notes |
|---|---|---|
| `qbraid:…` | **qBraid** | Default. The free simulator `qbraid:qbraid:sim:qir-sv` (≤28 qubits) needs **no credits**. Real QPUs spend qBraid credits ($0.01 each). |
| `openquantum:…` | **OpenQuantum** (Quantum Rings) | Real QPUs only (IonQ / Rigetti / IQM / AQT) — **no free simulator**; every job spends "Spark" credits (1 credit = $2; free tier 25 credits / $50 per 90 days). Form: `openquantum:<backend>` e.g. `openquantum:iqm:garnet`. |
The free qBraid simulator is the **default device everywhere**, so casual and agent-driven use never spends money. Real hardware runs only when you name a hardware device *and* opt into spending (see [Spend safety](#spend-safety)).
### How each provider is integrated
- **qBraid** — via `qbraid.runtime.QbraidProvider`. `provider.get_device(id).run(qasm3, shots=…)`, then `job.result()`. Live per-task/per-shot/per-minute pricing is read from `device.metadata()['pricing']`.
- **OpenQuantum** — via the `openquantum-sdk` package over **OAuth2 client-credentials**:
```python
from openquantum_sdk import ManagementClient, SchedulerClient
from openquantum_sdk.auth import ClientCredentials
from openquantum_sdk.clients import ClientCredentialsAuth, JobSubmissionConfig
auth = ClientCredentialsAuth(ClientCredentials(client_id, client_secret))
mgmt = ManagementClient(auth=auth)
sched = SchedulerClient(auth=auth, management_client=mgmt)
cfg = JobSubmissionConfig(
backend_class_id="iqm:garnet", # the part after "openquantum:"
name="kannaka-quantum",
job_subcategory_id="phys:oth", # required workload tag
shots=256,
organization_id=org_id, # auto-discovered (see below)
auto_approve_quote=True,
)
job = sched.submit_job(cfg, file_content=qasm.encode("utf-8"))
output = sched.download_job_output(job)
```
The bridge wraps all of this — you only ever pass a device string and OpenQASM. See [OpenQuantum integration internals](#openquantum-integration-internals) for the full authoritative SDK surface (endpoints, auth, config fields, method map).
---
## Install
```bash
pip install kannaka-quantum # or: pip install -e . (from this directory)
```
Requires Python ≥ 3.10. Dependencies: `qbraid`, `qiskit`, `numpy`, `mcp`, and `openquantum-sdk`.
---
## Authentication
Configure whichever provider(s) you'll use. The free qBraid simulator works with a qBraid key alone; OpenQuantum is optional and only needed for its real QPUs.
**qBraid** — an API key, resolved in order:
1. `QBRAID_API_KEY`
2. a saved `~/.qbraid/qbraidrc` (`QbraidProvider(api_key=…).save_config()`)
3. `~/Downloads/QBraid.txt` (a workstation convenience; first `qbr_…` match)
**OpenQuantum** — client credentials, resolved in order:
1. `OPENQUANTUM_CLIENT_ID` + `OPENQUANTUM_CLIENT_SECRET`
2. a JSON SDK key at `OPENQUANTUM_SDK_KEY`
3. `~/.openquantum/sdk-key.json`
4. `~/Downloads/sdk-key-*.json` (workstation convenience)
If no OpenQuantum credentials are present, the bridge simply omits OpenQuantum from device listings and stays fully usable on qBraid.
---
## CLI
Every subcommand prints **one JSON object** to stdout (errors included), so a caller can parse it directly.
```bash
kannaka-quantum devices --online
kannaka-quantum run --qasm-file bell.qasm --shots 200
kannaka-quantum qrng --bits 16
kannaka-quantum recall --amplitudes 0.1,0.9,0.2,0.15 --labels alpha,beta,gamma,delta
# Entropy reservoir (real-QPU-only) + provenance-tracked DRBG
kannaka-quantum harvest --allow-spend # 2048 bits from a real QPU → reservoir
kannaka-quantum qrng-status # level, provenance, refill cost
kannaka-quantum qrng-draw --bits 256 --expand # HMAC-DRBG stream seeded by the reservoir
```
`run` reads OpenQASM 3 from `--qasm`, `--qasm-file`, or stdin (`-`). Spend options (`--allow-spend`, `--max-credits`, `--subcategory`) apply to `run`/`qrng`/`recall`/`harvest`.
### Entropy reservoir
`harvest` first runs a CHSH test on the device and records its Bell parameter `S` in the provenance line (a device that does not violate the classical bound that day is refused; `--no-certify` records `bell: null`), then runs `qrng` against a **real per-shot QPU** (default `openquantum:rigetti:cepheus-1-108q`, ~$0.000255/shot) and appends the raw bits to `~/.kannaka/entropy/reservoir.bin`, with a provenance line (`device`, `job_id`, `n_bits`, `cost_usd`, timestamp) in `reservoir.meta.jsonl`. The free simulator is a PRNG and is refused. `qrng-draw` returns raw reservoir bits, or with `--expand` seeds a NIST SP 800-90A HMAC-DRBG (stdlib only) and expands — every draw records the harvest(s) that seeded it, so the stream chains back to a QPU `job_id`. An empty reservoir fails loudly; there is no silent software-PRNG fallback.
### Example: resonance recall
```text
$ kannaka-quantum recall --amplitudes 0.1,0.9,0.2,0.15 --labels alpha,beta,gamma,delta
{"distribution": {"alpha": 2, "beta": 775, "gamma": 240, "delta": 7},
"quantum_top": "beta", "classical_top": "beta", "agree": true,
"qubits": 2, "candidates": 4, "amplified": true,
"device": "qbraid:qbraid:sim:qir-sv"}
```
Amplitude amplification sharpens the prepared resonance state toward the strongest memory — the recall ran on a quantum computer, and it agrees with the classical argmax. The iteration count is derived from the target's *initial* amplitude (`(π/2 − θ)/2θ`), not the textbook `(π/4)√N`, so an already-dominant memory isn't *over*-rotated and de-amplified.
---
## MCP server
```bash
kannaka-quantum mcp # stdio transport
```
Register with Claude Code:
```bash
claude mcp add kannaka-quantum -- python -m kannaka_quantum mcp
```
…then any agent can call `quantum_devices`, `run_circuit`, `quantum_random`, and `resonance_recall`. (Shipped as a Claude Code plugin too — see `.claude-plugin/` and `skills/kannaka-quantum/`.)
---
## OpenQuantum integration internals
The authoritative surface, verified against `openquantum-sdk` **0.3.7** (the docs' overview omits most of this). Everything below is wrapped by the bridge; you don't call it directly, but this is what an `openquantum:…` device routes through.
### Services & auth
OpenQuantum is three HTTP services behind a Keycloak identity provider:
| service | default base URL | role |
|---|---|---|
| Identity (Keycloak) | `https://id.openquantum.com` (realm `platform`) | OAuth2 client-credentials → bearer token |
| Management | `https://management.openquantum.com` | backends, organizations, categories |
| Scheduler | `https://scheduler.openquantum.com` | job submit / status / output |
```python
ClientCredentialsAuth(
creds, # ClientCredentials(client_id, client_secret)
keycloak_base="https://id.openquantum.com",
realm="platform",
scope=None,
leeway_seconds=30, # token-refresh clock skew
session=None,
)
```
Auth is **OAuth2 client-credentials with automatic token refresh** — construct it once and the clients reuse/refresh the bearer token. `client_id` is prefixed `s_…`. Both clients accept either an `auth=` object or a raw `token=`:
```python
SchedulerClient(base_url="https://scheduler.openquantum.com", token=None, auth=None, management_client=None)
ManagementClient(base_url="https://management.openquantum.com", token=None, auth=None)
```
A `SchedulerClient` will lazily build its own `ManagementClient` for organization auto-discovery if you don't pass one. The bridge passes an explicit shared `mgmt` so both clients reuse one token.
### `JobSubmissionConfig` fields
| field | type | the bridge sets |
|---|---|---|
| `backend_class_id` | `str` | the part after `openquantum:` (e.g. `iqm:garnet`) |
| `name` | `str` | `"kannaka-quantum"` |
| `job_subcategory_id` | `str` | `"phys:oth"` (required workload tag; override via `--subcategory` / `OPENQUANTUM_SUBCATEGORY`) |
| `shots` | `int` | the requested shot count |
| `organization_id` | `Optional[str]` | resolved from `mgmt.list_user_organizations(...)` |
| `auto_approve_quote` | `bool` | `True` — accept the live cost quote (already bounded by the pre-flight credit cap) |
| `configuration_data` | `Optional[Dict]` | — |
| `execution_plan` / `queue_priority` | enum / auto | left at the SDK's `AutoChoice` |
| `job_timeout_seconds`, `verbose` | `int` / `bool` | SDK defaults |
### `SchedulerClient` method map
```python
job = sched.submit_job(config, *, file_content=bytes | None, file_path=str | None) # -> JobRead
output = sched.download_job_output(job) # -> Any (counts)
sched.close()
```
The bridge submits in-memory (`file_content=qasm.encode("utf-8")`) rather than from a file. Other lifecycle methods the SDK exposes (not currently used): `get_job`, `list_jobs`, `cancel_job`, `prepare_job` / `get_preparation_result`, `upload_job_input`, `get_job_categories` / `get_job_subcategories`, `get_backend_class`.
> **Result shape note.** `download_job_output` returns provider-dependent JSON. The bridge's `_oq_counts` tries `counts` / `measurement_counts` / `histogram` / `meas` keys and a few accessor shapes, then falls back to attaching the raw output under `raw_output` so the parser can be tightened once a given backend's exact shape is observed. Backend qubit-ordering for `resonance_recall` is treated as big-endian-no-reverse (like AWS-routed devices) **pending a confirmed real recall** on an OpenQuantum QPU.
---
## Spend safety
The whole point is that *casual use is free and a careless run can't drain the budget.*
- **Free by default.** The default device is the free qBraid simulator; nothing spends until you name a hardware device.
- **Explicit opt-in.** A real-QPU run requires `allow_spend=True` (CLI `--allow-spend`) or `KANNAKA_QUANTUM_ALLOW_SPEND=1`. Otherwise it raises and points you back to the free simulator.
- **Credit ceiling.** Every paid run is bounded by `max_credits` (CLI `--max-credits`); over-cap pre-flight estimates raise instead of submitting. Defaults: qBraid 200 credits (≈ $2), OpenQuantum 1 credit (≈ $2). Override via `QBRAID_MAX_CREDITS` / `OPENQUANTUM_MAX_CREDITS`.
- **Per-minute devices need `max_seconds`.** qBraid's *native* Rigetti bills **per minute** (~12000 credits/min ≈ **$120/min**, prorated to actual execution time). The bridge refuses it unless you bound wall-clock time with `max_seconds` (CLI `--max-seconds`); the ceiling `rate*seconds/60` must fit under the credit cap (ADR-0002). It is the only route that executes `delay` instructions.
All three hazards (no-opt-in, over-cap, per-minute without `max_seconds`) raise before any job is submitted — verified at $0. A job that ends FAILED, or returns no counts, raises instead of coming back as an empty success.
### Cheap real QPUs
| device | provider | ~cost (256 shots) |
|---|---|---|
| `openquantum:iqm:garnet` | OpenQuantum | $0.00087/shot ≈ $0.22 |
| `openquantum:rigetti:cepheus-1-108q` | OpenQuantum | $0.000255/shot ≈ $0.07 |
| `aws:rigetti:qpu:cepheus-1-108q` | qBraid | 30 + 0.0425/shot credits ≈ $0.41 |
| ⚠️ `rigetti:rigetti:qpu:cepheus-1-108q` | qBraid (native) | **$120/min prorated — needs `--max-seconds`**; the only route that runs `delay` |
---
## Verified benchmark (simulator vs real hardware)
Same Bell state, 256 shots:
| run | device | result | leakage |
|---|---|---|---|
| simulator | `qbraid:qbraid:sim:qir-sv` | `00: 122, 11: 134` | 0% |
| real QPU | `aws:rigetti:qpu:cepheus-1-108q` | `00: 127, 11: 115, 01+10: 14` | 5.5% ($0.41) |
≈ 94.5% fidelity under real device noise.
---
## Development
```bash
pip install -e .
pytest # 6 network-free tests (no credentials or backend needed)
```
The core (`kannaka_quantum/core.py`) is provider-agnostic; `cli.py` and `mcp_server.py` are thin surfaces over it.
## Releasing
This repo doesn't tag releases yet. When it does, pushing a `v*` tag (e.g.
`v0.2.4`) also **updates the constellation marketplace**: the
[`notify-marketplace`](.github/workflows/notify-marketplace.yml) workflow sends a
`plugin-released` dispatch to
[kannaka-constellation-marketplace](https://github.com/kannaka-labs/kannaka-constellation-marketplace),
which opens a PR bumping `kannaka-quantum`'s version in its manifest and README.
Keep `pyproject.toml` and `.claude-plugin/plugin.json` versions in step with the
tag. The cascade is **dormant until** a `KANNAKA_CASCADE_PAT` secret (a PAT with
`contents: write` + `pull-requests: write` on the marketplace repo) is added to
this repo's Actions secrets; until then the workflow just logs a warning and
no-ops.
## License
Space Child License v1.0. See [LICENSE](./LICENSE).
This server cannot be deployed
Maintenance
ActivityActive
ResponsivenessResponsive