Kernel API overview
The Nuclei kernel is a standalone WebSocket service. The desktop frontend is just its first client — anything that can open a WebSocket and speak JSON can parse circuits, run simulations, and submit hardware jobs. This section documents that protocol as a public API.
Connection
Section titled “Connection”| Property | Value |
|---|---|
| URL | ws://localhost:9742 |
| Port fallback | If 9742 is taken, the kernel scans upward through 9742–9761 (range of 20) and binds the first free port |
| Framing | JSON text frames — one request or response object per frame |
| Max inbound message | 1 MiB (1_048_576 bytes); larger frames close the connection |
| Heartbeat | WebSocket ping every 30 s; connection dropped after a 20 s pong timeout |
| Auth | None — the kernel binds to localhost only |
Requests on one connection are processed strictly in order: the handler
fully finishes (and sends every response for) request N before reading
request N + 1. For concurrent work, open multiple connections — each
connection gets its own isolated Executor (parse/execute state never
bleeds between clients), while hardware state (provider connections, job
registry) is shared process-wide.
Running the kernel standalone
Section titled “Running the kernel standalone”cd kernel && python server.pyOn success the kernel prints exactly one ready line to stdout:
Nuclei kernel ready on ws://localhost:9742This line is the port-discovery contract: when the default port was taken, the chosen port appears in this line, on its own line, flushed — parse it rather than assuming 9742.
The streaming model
Section titled “The streaming model”A request does not get a reply. It produces an ordered sequence of
response messages on the same connection, ending with a request-specific
final message (result for execute, python_result for run_python,
snapshot for parse — though a failed parse appends one error after
it — and a single reply for every hardware_* request). Streamed output / stderr messages may interleave before the
terminal message, so a robust client loops until it sees the terminal type
— see client examples.
The canonical example — execute on a Bell circuit produces two messages,
snapshot then result:
{ "type": "execute", "code": "from qiskit import QuantumCircuit\n\nqc = QuantumCircuit(2, 2)\nqc.h(0)\nqc.cx(0, 1)\nqc.measure([0, 1], [0, 1])\n", "shots": 1024, "language": "python"}[ { "type": "snapshot", "data": { "framework": "qiskit", "qubit_count": 2, "classical_bit_count": 2, "depth": 3, "gates": [ { "type": "H", "targets": [0], "controls": [], "params": [], "layer": 0 }, { "type": "CNOT", "targets": [1], "controls": [0], "params": [], "layer": 1 }, { "type": "Measure", "targets": [0], "controls": [], "params": [], "layer": 2 }, { "type": "Measure", "targets": [1], "controls": [], "params": [], "layer": 2 } ] } }, { "type": "result", "data": { "state_vector": [ { "re": "<approx:0.70710678:0.0000001>", "im": "<approx:0:0.0000001>" }, { "re": "<approx:0:0.0000001>", "im": "<approx:0:0.0000001>" }, { "re": "<approx:0:0.0000001>", "im": "<approx:0:0.0000001>" }, { "re": "<approx:0.70710678:0.0000001>", "im": "<approx:0:0.0000001>" } ], "probabilities": { "00": "<approx:0.5:0.000001>", "11": "<approx:0.5:0.000001>" }, "measurements": "<any>", "bloch_coords": [ { "x": "<approx:0:0.000001>", "y": "<approx:0:0.000001>", "z": "<approx:0:0.000001>" }, { "x": "<approx:0:0.000001>", "y": "<approx:0:0.000001>", "z": "<approx:0:0.000001>" } ], "execution_time_ms": "<any>", "shot_count": 1024, "metrics": {} } }]Values like "<any>" and "<approx:0.5:0.000001>" are matcher markers, not
protocol values: every example in this section is a fixture file that the
kernel test suite replays against the real handler
(kernel/tests/test_docs_fixtures.py), and markers absorb nondeterminism
(sampled counts, timings). The shapes and orderings you read here are
machine-checked on every CI run.
Message catalog
Section titled “Message catalog”Request type | Terminal response | Reference |
|---|---|---|
parse | snapshot (an error follows it on failure) | Execution messages |
execute | result | Execution messages |
run_python | python_result | Execution messages |
environment | environment | Execution messages |
hardware_connect | hardware_connected | Hardware messages |
hardware_set_credentials | hardware_connected | Hardware messages |
hardware_clear_credentials | hardware_connected | Hardware messages |
hardware_connected_providers | hardware_connected_providers | Hardware messages |
hardware_list_jobs | hardware_jobs | Hardware messages |
hardware_list_backends | hardware_backends | Hardware messages |
hardware_submit | hardware_job_submitted | Hardware messages |
hardware_status | hardware_job_update | Hardware messages |
hardware_results | hardware_result | Hardware messages |
hardware_cancel | hardware_job_cancelled | Hardware messages |
Any other type (and any frame that is not valid JSON) produces a bare
error message — see errors. Payload schemas
are in schemas. The TypeScript mirror of the
whole protocol — the types the frontend itself compiles against — lives at
src/types/quantum.ts.