MCP server exposing Qiskit 2.3.1 quantum computing functionality
Project description
mcp-qiskit
MCP server exposing Qiskit 2.3.1 quantum computing functionality through the Model Context Protocol. Enables LLMs to create, manipulate, and execute quantum circuits via standardized MCP tools and resources.
mcp-name: io.github.daedalus/mcp-qiskit
Overview
This project provides a Model Context Protocol (MCP) server that exposes Qiskit quantum computing functionality to Large Language Models (LLMs). It allows AI assistants to:
- Create and manipulate quantum circuits
- Execute circuits on quantum simulators or real backends
- Analyze circuit properties (depth, gates, operations)
- Visualize circuits in various formats
- Manage quantum backends
Why Use This?
- LLM Integration: Enables AI assistants to perform quantum computing tasks without external tooling
- Standardized Interface: MCP provides a consistent tool-based interface for quantum operations
- Qiskit 2.3.1 Compatible: Specifically designed for Qiskit 2.3.1 with all its features
- Extensible: Easy to add new tools or backends
Installation
Prerequisites
- Python 3.11 or higher
- Qiskit 2.3.1
- A running MCP client (Claude Desktop, Cursor, etc.)
Install from PyPI
pip install mcp-qiskit[qiskit]
The [qiskit] extra installs the required Qiskit dependencies. Other extras available:
# Install with development dependencies
pip install mcp-qiskit[dev,test]
# Install with MCP server dependencies
pip install mcp-qiskit[mcp]
Install from Source
git clone https://github.com/daedalus/mcp-qiskit.git
cd mcp-qiskit
pip install -e ".[all]"
Quick Start
As a Python Library
from mcp_qiskit import create_quantum_circuit, add_gate, add_measurement, run_circuit
# Create a 2-qubit circuit with 2 classical bits
circuit = create_quantum_circuit(2, 2)
# Apply a Hadamard gate on qubit 0
circuit = add_gate(circuit, "h", [0])
# Apply CNOT gate (control: qubit 0, target: qubit 1)
circuit = add_gate(circuit, "cx", [0, 1])
# Measure all qubits
circuit = add_measurement(circuit, [0, 1])
# Execute on Aer simulator
result = run_circuit(circuit, "aer_simulator", shots=1024)
print(f"Measurement results: {result['counts']}")
As an MCP Server
Claude Desktop
Add to your claude_desktop_config.json:
{
"mcpServers": {
"mcp-qiskit": {
"command": "mcp-qiskit",
"env": {}
}
}
}
Cursor
Add to your Cursor settings under MCP Servers:
{
"mcpServers": {
"mcp-qiskit": {
"command": "mcp-qiskit",
"args": []
}
}
}
Other MCP Clients
# Run as stdio server
mcp-qiskit
# Or use the Python module directly
python -m mcp_qiskit
MCP Tools Reference
Circuit Creation Tools
create_quantum_circuit_tool
Creates an empty quantum circuit with specified number of qubits and classical bits.
Parameters:
num_qubits(int): Number of quantum bitsnum_classical_bits(int): Number of classical bits for measurements
Returns: Dictionary representing the circuit
Example:
circuit = create_quantum_circuit_tool(num_qubits=3, num_classical_bits=3)
# Returns: {"num_qubits": 3, "num_clbits": 3, "operations": [], "name": "circuit"}
add_gate_tool
Adds a quantum gate to a circuit.
Parameters:
circuit(dict): The circuit to modifygate_name(str): Name of the gate (e.g., "h", "x", "cx", "rx")qubits(list[int]): List of qubit indices to apply the gate toparams(list[float], optional): Parameters for parameterized gates
Supported Gates:
- Single-qubit:
h,x,y,z,s,t,sdg,tdg,i,id - Parameterized:
rx,ry,rz,u1,u2,u3,p - Multi-qubit:
cx,cy,cz,swap
Example:
circuit = add_gate_tool(circuit, "h", [0]) # Hadamard on qubit 0
circuit = add_gate_tool(circuit, "cx", [0, 1]) # CNOT from 0 to 1
circuit = add_gate_tool(circuit, "rx", [0], [0.5]) # RX with parameter
add_measurement_tool
Adds measurement operations to qubits.
Parameters:
circuit(dict): The circuit to modifyqubits(list[int]): Qubit indices to measureclbits(list[int], optional): Classical bit indices to store results
Example:
circuit = add_measurement_tool(circuit, [0, 1]) # Measure q0->c0, q1->c1
circuit = add_measurement_tool(circuit, [0, 1], [1, 0]) # Measure q0->c1, q1->c0
Analysis Tools
get_circuit_depth_tool
Returns the depth (number of layers) of the circuit.
Parameters:
circuit(dict): The circuit to analyze
Returns: Integer representing circuit depth
list_available_gates_tool
Lists all available quantum gates in Qiskit.
Returns: List of gate name strings
get_gate_definition_tool
Gets detailed information about a quantum gate.
Parameters:
gate_name(str): Name of the gate
Returns: Dictionary with gate properties:
name: Gate namenum_qubits: Number of qubits the gate operates onnum_parameters: Number of parameters (0 for fixed gates)params: List of parameter values
Visualization Tools
draw_circuit_tool
Renders a circuit in various formats.
Parameters:
circuit(dict): The circuit to drawoutput_format(str): Output format - "ascii", "text", "mpl", "latex"
Returns: String representation of the circuit
Example Output (ASCII):
┌───┐
q_0: ┤ H ├──■──
└───┘┌─┴─┐
q_1: ────┤ X ├
└───┘
c: 2/═══════╪═══
0 1
Backend Tools
list_backends_tool
Lists available quantum backends.
Parameters:
filters(dict, optional): Filter criteria (e.g.,{"status": "ONLINE"})
Returns: List of backend information dictionaries
get_backend_status_tool
Gets status information for a backend.
Parameters:
backend_name(str): Name of the backend
Returns: Dictionary with:
name: Backend namestatus: Status (ONLINE/OFFLINE)num_qubits: Number of qubits
get_backend_configuration_tool
Gets detailed configuration for a backend.
Parameters:
backend_name(str): Name of the backend
Returns: Dictionary with:
name: Backend namenum_qubits: Number of qubitscoupling_map: Qubit connectivity (if applicable)basis_gates: List of available basis gatesmax_shots: Maximum allowed shots
Execution Tools
run_circuit_tool
Executes a single quantum circuit.
Parameters:
circuit(dict): Circuit to executebackend_name(str, optional): Backend name (default: "aer_simulator")shots(int, optional): Number of measurement shots (default: 1024)seed(int, optional): Random seed for reproducibility
Returns: Dictionary with:
status: "COMPLETED" or error messagebackend: Backend usedshots: Number of shotscounts: Measurement outcome counts (if shots > 0)statevector: Statevector (if shots=None)time_taken: Execution time in seconds
Example:
result = run_circuit_tool(circuit, "aer_simulator", shots=1000, seed=42)
# Returns: {"status": "COMPLETED", "counts": {"00": 512, "11": 488}, ...}
run_circuits_tool
Executes multiple circuits in a batch.
Parameters:
circuits(list[dict]): List of circuits to executebackend_name(str, optional): Backend nameshots(int, optional): Number of shotsseed(int, optional): Random seed
Returns: List of result dictionaries
Example:
circuits = [circuit1, circuit2, circuit3]
results = run_circuits_tool(circuits, shots=100)
# Returns list of 3 result dictionaries
transpile_circuit_tool
Transpiles a circuit for optimization or specific backend.
Parameters:
circuit(dict): Circuit to transpileoptimization_level(int, optional): 0-3 (default: 1)basis_gates(list[str], optional): Target basis gates
Returns: Transpiled circuit dictionary
Example:
transpiled = transpile_circuit_tool(circuit, optimization_level=2)
MCP Resources
resource://backends
Provides a list of available quantum backends. Updated dynamically based on available providers.
resource://gates
Provides a list of all available quantum gates in Qiskit.
Usage Examples
Create a Bell State
# Create 2-qubit circuit
circuit = create_quantum_circuit(2, 2)
# Create Bell state: |Φ+⟩ = (|00⟩ + |11⟩) / √2
circuit = add_gate(circuit, "h", [0])
circuit = add_gate(circuit, "cx", [0, 1])
circuit = add_measurement(circuit, [0, 1])
# Execute
result = run_circuit(circuit, "aer_simulator", shots=1000)
print(result["counts"]) # Approximately {"00": 500, "11": 500}
Run Grover's Algorithm
def create_grover_circuit(num_qubits, iterations):
circuit = create_quantum_circuit(num_qubits, num_qubits)
# Initial superposition
for i in range(num_qubits):
circuit = add_gate(circuit, "h", [i])
# Grover iterations
for _ in range(iterations):
# Oracle (marked state |11...1⟩)
for i in range(num_qubits):
circuit = add_gate(circuit, "x", [i])
circuit = add_gate(circuit, "cx", list(range(num_qubits - 1)), [num_qubits - 1])
for i in range(num_qubits):
circuit = add_gate(circuit, "x", [i])
# Diffusion operator
for i in range(num_qubits):
circuit = add_gate(circuit, "h", [i])
for i in range(num_qubits):
circuit = add_gate(circuit, "x", [i])
circuit = add_gate(circuit, "cx", list(range(num_qubits - 1)), [num_qubits - 1])
for i in range(num_qubits):
circuit = add_gate(circuit, "x", [i])
for i in range(num_qubits):
circuit = add_gate(circuit, "h", [i])
# Measurement
circuit = add_measurement(circuit, list(range(num_qubits)))
return circuit
circuit = create_grover_circuit(3, 1)
result = run_circuit(circuit, "aer_simulator", shots=1000)
Draw and Analyze Circuit
circuit = create_quantum_circuit(2, 2)
circuit = add_gate(circuit, "h", [0])
circuit = add_gate(circuit, "cx", [0, 1])
circuit = add_measurement(circuit, [0, 1])
# Get depth
depth = get_circuit_depth(circuit)
print(f"Circuit depth: {depth}")
# List gates
gates = list_available_gates()
print(f"Available gates: {len(gates)}")
# Draw circuit
ascii_output = draw_circuit(circuit, "ascii")
print(ascii_output)
Architecture
mcp-qiskit/
├── src/mcp_qiskit/
│ ├── __init__.py # Package exports
│ ├── __main__.py # CLI entry point
│ ├── _circuit.py # Circuit operations
│ ├── _backend.py # Backend management
│ ├── _execution.py # Circuit execution
│ └── _mcp.py # MCP server definition
├── tests/ # Test suite
├── SPEC.md # Project specification
└── README.md # This file
Module Responsibilities
- _circuit.py: Quantum circuit creation, gates, measurements, visualization
- _backend.py: Backend discovery, status, configuration
- _execution.py: Circuit execution, transpilation
- _mcp.py: FastMCP server definition, tool registration
Requirements
- Python 3.11+
- qiskit >= 2.3.1
- qiskit-aer >= 0.14.0
- fastmcp >= 2.0
Development
Setup
git clone https://github.com/daedalus/mcp-qiskit.git
cd mcp-qiskit
pip install -e ".[all]"
Running Tests
pytest -v
Code Quality
# Format code
ruff format src/ tests/
# Lint
ruff check src/ tests/
# Type check
mypy src/
Pre-commit Hooks
pre-commit install
Troubleshooting
Backend Not Found
If you get "Backend not found", ensure the backend name is correct:
# List available backends
backends = list_backends()
print([b["name"] for b in backends])
Import Errors
Make sure Qiskit is properly installed:
pip install qiskit==2.3.1 qiskit-aer
MCP Connection Issues
Verify the server is running:
mcp-qiskit --help
License
MIT License - see LICENSE file.
Contributing
Contributions are welcome! Please open an issue or submit a PR on GitHub.
Related Projects
- Qiskit - Quantum computing SDK
- FastMCP - MCP framework
- Model Context Protocol - Protocol specification
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mcp_qiskit-0.1.0.tar.gz.
File metadata
- Download URL: mcp_qiskit-0.1.0.tar.gz
- Upload date:
- Size: 12.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
82ca0bdace9ad028a23e967fba1d7dd7e6d85f43a3e05a8a30312163c58b9563
|
|
| MD5 |
bb4321b5e6a3850196602783b4c84428
|
|
| BLAKE2b-256 |
a7c4533aa24897ee5193f507f709279554740074898adaf8e6b989ef6f6bc04f
|
Provenance
The following attestation bundles were made for mcp_qiskit-0.1.0.tar.gz:
Publisher:
pypi-publish.yml on daedalus/mcp-qiskit
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mcp_qiskit-0.1.0.tar.gz -
Subject digest:
82ca0bdace9ad028a23e967fba1d7dd7e6d85f43a3e05a8a30312163c58b9563 - Sigstore transparency entry: 1239925383
- Sigstore integration time:
-
Permalink:
daedalus/mcp-qiskit@67ec661509f43b20f9346eeb6434a9a841f4e834 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/daedalus
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi-publish.yml@67ec661509f43b20f9346eeb6434a9a841f4e834 -
Trigger Event:
release
-
Statement type:
File details
Details for the file mcp_qiskit-0.1.0-py3-none-any.whl.
File metadata
- Download URL: mcp_qiskit-0.1.0-py3-none-any.whl
- Upload date:
- Size: 15.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
999ccbcaa92e2c2f7762554a155d10387a1404672818cf76200abc9ceae83654
|
|
| MD5 |
921b590969ad06cacf83a2bc7645832f
|
|
| BLAKE2b-256 |
1c5a90ac4b187847ad66b75cf7bfb36cef81e981434066a862a0c5f017c2628c
|
Provenance
The following attestation bundles were made for mcp_qiskit-0.1.0-py3-none-any.whl:
Publisher:
pypi-publish.yml on daedalus/mcp-qiskit
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mcp_qiskit-0.1.0-py3-none-any.whl -
Subject digest:
999ccbcaa92e2c2f7762554a155d10387a1404672818cf76200abc9ceae83654 - Sigstore transparency entry: 1239925411
- Sigstore integration time:
-
Permalink:
daedalus/mcp-qiskit@67ec661509f43b20f9346eeb6434a9a841f4e834 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/daedalus
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi-publish.yml@67ec661509f43b20f9346eeb6434a9a841f4e834 -
Trigger Event:
release
-
Statement type: