# Quantum Computing Tool (`competent_chill/quantum-computing-tool`) Actor

- **URL**: https://apify.com/competent\_chill/quantum-computing-tool.md
- **Developed by:** [Jiri Spitalsky](https://apify.com/competent_chill) (community)
- **Categories:** Integrations
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-usage

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Quantum Computing Tool for Apify

A small provider-independent Apify Actor for AI agents that need to validate OpenQASM,
simulate circuits with Qiskit Aer, or manage asynchronous jobs on a real quantum provider.

```text
AI agent / MCP client
        |
        v
Apify Quantum Computing Actor
        |-- SIM -> local Qiskit Aer
        |-- IBM -> IBM Quantum Runtime Sampler V2
        `-- VLQ -> explicit adapter skeleton
```

The Actor reads one JSON request and writes one stable JSON envelope to both:

- the `OUTPUT` record in the default key-value store;
- one item in the default dataset, which is convenient for Apify's MCP server.

### Operations

| Operation | Targets | Behavior |
| --- | --- | --- |
| `validate_circuit` | `SIM`, `IBM`, `VLQ` | Parses and inspects QASM without execution. |
| `simulate_circuit` | `SIM` | Runs a measured circuit synchronously with Aer. |
| `run_quantum_job` | `IBM`, `VLQ` | Submits and immediately returns a persistent provider job ID. |
| `get_quantum_job` | `IBM`, `VLQ` | Retrieves normalized status and completed results. |
| `list_backends` | `SIM`, `IBM`, `VLQ` | Discovers reliable backend capabilities. |

The current POC implements SIM and IBM. VLQ is an intentional interface skeleton: because no
authoritative VLQ submission contract was supplied, it returns
`VLQ_ADAPTER_NOT_IMPLEMENTED` and never guesses an endpoint or sends a placeholder request.

### GHZ simulation

Input:

```json
{
  "operation": "simulate_circuit",
  "target": "SIM",
  "qasm": "OPENQASM 2.0; include \"qelib1.inc\"; qreg q[3]; creg c[3]; h q[0]; cx q[0],q[1]; cx q[1],q[2]; measure q -> c;",
  "shots": 10000,
  "seed": 42
}
```

Representative response (counts vary without a seed):

```json
{
  "ok": true,
  "operation": "simulate_circuit",
  "target": "SIM",
  "status": "COMPLETED",
  "backend": "aer_simulator",
  "result": {
    "shots": 10000,
    "counts": {"000": 5017, "111": 4983}
  },
  "metadata": {
    "memory_estimate": {
      "statevector_bytes": 128,
      "safe_to_simulate": true
    }
  },
  "warnings": []
}
```

The complete example is in `examples/simulate-ghz.json`.

### Memory safety

The Actor definition requests 4608 MiB by default, enforces a 4096 MiB minimum, and caps runs
at **4608 MiB (4.5 GiB)**. Before every simulation, the Actor computes:

```text
statevector_bytes = 16 * 2^num_qubits
method_state_bytes = statevector_bytes
estimated_peak_bytes = 1.5 GiB runtime reserve + 2 * method_state_bytes
```

The reserve covers Python, Qiskit, Aer, loaded libraries, circuit storage, and Actor SDK
overhead. The factor of two allows for simulator working buffers. A simulation is rejected
with `SIMULATION_MEMORY_LIMIT` when the peak estimate exceeds 4.5 GiB. Under this policy the
generic statevector ceiling is 26 qubits; 27 qubits is rejected. The same conservative gate
is applied even if a more memory-efficient Aer method was requested, so a method-selection
mistake cannot bypass the Actor's safety contract.

For explicit `density_matrix`, `method_state_bytes` is instead `16 * 4^num_qubits`; its
conservative ceiling is 13 qubits. This closes the otherwise dangerous gap between
statevector and density-matrix scaling. SIM backend discovery reports the ceiling per method.

Validation still accepts circuits above the simulation ceiling (up to a separate 128-qubit
parser safety cap) and reports `safe_to_execute_under_actor_limit: false` without executing
them. The parser cap prevents pathological register declarations from allocating enormous
objects before validation.

### IBM asynchronous workflow

First discover backend names:

```json
{
  "operation": "list_backends",
  "target": "IBM",
  "ibm_token": "<Apify secret input>"
}
```

Then submit. A backend is deliberately required so an agent cannot accidentally select or
pay for a device it did not name:

```json
{
  "operation": "run_quantum_job",
  "target": "IBM",
  "backend": "<backend from list_backends>",
  "qasm": "OPENQASM 2.0; include \"qelib1.inc\"; qreg q[3]; creg c[3]; h q[0]; cx q[0],q[1]; cx q[1],q[2]; measure q -> c;",
  "shots": 1000,
  "ibm_token": "<Apify secret input>"
}
```

The adapter transpiles to the selected backend's ISA, invokes IBM Runtime Sampler V2 in job
mode, and returns `SUBMITTED` with `job_id`. The Actor does not wait in the QPU queue.

Retrieve later:

```json
{
  "operation": "get_quantum_job",
  "target": "IBM",
  "job_id": "<returned job ID>",
  "ibm_token": "<Apify secret input>"
}
```

Provider states are normalized to `SUBMITTED`, `QUEUED`, `RUNNING`, `COMPLETED`, `FAILED`,
or `CANCELLED`. Completed Sampler V2 bit-array results become ordinary integer counts.

`ibm_channel` defaults to `ibm_quantum_platform`; `ibm_cloud` and an optional
`ibm_instance` are also accepted. The token field is marked `isSecret` in the Apify input
schema, represented as a Pydantic `SecretStr`, never logged, never stored by this code, and
removed from validation/provider error text.

### OpenQASM and validation

OpenQASM 2.0 uses Qiskit's built-in `qasm2.loads`. OpenQASM 3.x uses `qasm3.loads` with the
official optional importer package. Validation returns:

- qubits, classical bits, depth, and total operation count;
- operation breakdown and measurement presence/count;
- exact statevector and conservative peak-memory estimates;
- the safe-to-simulate decision, errors, and warnings.

Shot-based simulation and QPU submission require at least one measurement. The input model
also rejects invalid combinations before circuit parsing, including `simulate_circuit + IBM`,
`run_quantum_job + SIM`, and `get_quantum_job` without `job_id`.

### Local development (without Docker)

Python 3.11-3.13 and `uv` are supported:

```bash
uv sync
uv run pytest
uv run ruff check .
uv run quantum-tool examples/simulate-ghz.json
```

Or stream JSON:

```bash
printf '%s' '{"operation":"list_backends","target":"SIM"}' | uv run quantum-tool -
```

The Dockerfile is supplied for Apify deployment, but Docker is not needed for local testing.
It uses Apify's Python 3.12 base image and sets BLAS/OpenMP thread counts to one to reduce
uncontrolled memory/CPU amplification. Production dependencies are installed from the
hash-checked `requirements.lock` exported from `uv.lock`.

### Apify and MCP

The `.actor` directory contains explicit input, output, and dataset schemas. Deploy with the
Apify CLI, then expose the deployed Actor through the hosted Apify MCP server as a specific
Actor tool or call it through `call-actor`. The input schema becomes the tool contract and the
single dataset item supplies structured output inference/retrieval.

Do not put credentials in example files, source control, QASM, or logs. Supply IBM/VLQ values
through fields marked as Apify secret inputs.

### Repository layout

```text
.actor/                  Actor definition and discovery schemas
examples/                GHZ and IBM request examples
src/quantum_tool/
  circuit.py             QASM parsing, analysis, and memory policy
  models.py              Strict request schema and combination checks
  service.py             Stable operation dispatch/envelopes
  main.py                Apify lifecycle and storage output
  providers/
    base.py              Provider interface
    sim.py               Qiskit Aer adapter
    ibm.py               IBM Runtime Sampler V2 adapter
    vlq.py               Non-invented VLQ boundary
tests/                   Unit, Aer integration, safety, and adapter tests
```

### POC limitations

- VLQ needs documented authentication, discovery, submission, and retrieval semantics.
- Real IBM calls require a user token, service access, and available backend; automated tests
  mock the provider boundary and never submit paid QPU work.
- This is shot/count oriented. It does not return statevectors and does not yet accept QPY or
  structured Qiskit JSON.
- The memory estimate is intentionally conservative rather than a promise of maximum Aer
  capacity.

### License

Apache-2.0.

# Actor input Schema

## `operation` (type: `string`):

Exactly one operation to perform. QPU submission returns immediately with a job ID.

## `target` (type: `string`):

SIM runs locally with Aer; IBM and VLQ use independent provider adapters.

## `qasm` (type: `string`):

OpenQASM 2.0 or 3.x source. Required for validate\_circuit, simulate\_circuit, and run\_quantum\_job.

## `backend` (type: `string`):

Required for real-QPU submission; optional as an IBM list\_backends filter.

## `shots` (type: `integer`):

Number of samples for simulation or provider submission.

## `job_id` (type: `string`):

Required for get\_quantum\_job.

## `seed` (type: `integer`):

Optional deterministic seed for SIM shot sampling.

## `simulator_method` (type: `string`):

Aer method. The conservative statevector memory gate applies before every simulation regardless of this selection.

## `ibm_token` (type: `string`):

BYOK credential for IBM operations. Encrypted by Apify and never logged by this Actor.

## `ibm_channel` (type: `string`):

IBM Quantum Runtime authentication channel.

## `ibm_instance` (type: `string`):

Optional IBM Cloud instance CRN or service instance selector.

## `vlq_credentials` (type: `string`):

Reserved encrypted BYOK value for the future documented VLQ client integration.

## Actor input object example

```json
{
  "operation": "simulate_circuit",
  "target": "SIM",
  "qasm": "OPENQASM 2.0;\ninclude \"qelib1.inc\";\nqreg q[3];\ncreg c[3];\nh q[0];\ncx q[0],q[1];\ncx q[1],q[2];\nmeasure q -> c;",
  "shots": 1000,
  "simulator_method": "automatic",
  "ibm_channel": "ibm_quantum_platform"
}
```

# Actor output Schema

## `result` (type: `string`):

Direct structured JSON response for API and agent consumers.

## `dataset` (type: `string`):

The same response as a one-item dataset for Apify MCP and storage workflows.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "qasm": `OPENQASM 2.0;
include "qelib1.inc";
qreg q[3];
creg c[3];
h q[0];
cx q[0],q[1];
cx q[1],q[2];
measure q -> c;`
};

// Run the Actor and wait for it to finish
const run = await client.actor("competent_chill/quantum-computing-tool").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "qasm": """OPENQASM 2.0;
include \"qelib1.inc\";
qreg q[3];
creg c[3];
h q[0];
cx q[0],q[1];
cx q[1],q[2];
measure q -> c;""" }

# Run the Actor and wait for it to finish
run = client.actor("competent_chill/quantum-computing-tool").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "qasm": "OPENQASM 2.0;\\ninclude \\"qelib1.inc\\";\\nqreg q[3];\\ncreg c[3];\\nh q[0];\\ncx q[0],q[1];\\ncx q[1],q[2];\\nmeasure q -> c;"
}' |
apify call competent_chill/quantum-computing-tool --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,competent_chill/quantum-computing-tool"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/yeia7aG6AIOcIuPcA/builds/026Lz1cN3ZnRSXD3H/openapi.json
