Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
131a2c4
Improving existing pyproject files. Including bandit for security checks
cbjuan Nov 27, 2025
208e1a9
Adding a general pyproject.toml to define the whole monorepo
cbjuan Nov 27, 2025
54bad6c
Adding mypy and ruff configurations for the repo
cbjuan Nov 27, 2025
8dc51e2
Improving test workflow
cbjuan Nov 27, 2025
e62252e
Improving readme
cbjuan Nov 27, 2025
82b5ffa
feat: Add Python 3.13 and 3.14 to pyproject files and the CI test mat…
cbjuan Nov 27, 2025
670d7c4
Ruff format
cbjuan Nov 27, 2025
c1320d2
feat: Broaden per-file ignore scopes and add new specific ignores for…
cbjuan Nov 27, 2025
f6262cb
Add the release of the metapackage qiskit-mcp-servers
cbjuan Nov 27, 2025
ba9b7a8
Adding docs about the metapackage
cbjuan Nov 27, 2025
f1f33e3
Improve the documentation for automated package releases
cbjuan Nov 27, 2025
49f79f4
Edit the current owner to AI4Quantum
cbjuan Nov 27, 2025
856a0a5
Fixing the tool.uv.sources to fix the uv run ruff
cbjuan Nov 28, 2025
b430905
Fix ruff format
cbjuan Nov 28, 2025
f8c5f3d
Merge pull request #32 from Qiskit/improving-gh-workflow
cbjuan Dec 1, 2025
f47763d
Update README.md
cbjuan Dec 1, 2025
e9a4c3d
Merge pull request #34 from Qiskit/update-python-versions
cbjuan Dec 1, 2025
9151cee
Merge pull request #33 from Qiskit/improving-readme
cbjuan Dec 1, 2025
a7b7d76
Fixing mypy and ruff issues
cbjuan Dec 1, 2025
b596746
Fixing mypy issues with types in other files
cbjuan Dec 1, 2025
3d2f4cb
Merge branch 'main' into improving-pyproject-tomls
cbjuan Dec 1, 2025
b2358ff
Fixing issues with mypy and ruff
cbjuan Dec 1, 2025
c81c1fc
Lint fixes
cbjuan Dec 1, 2025
1e261f4
Fix issues with pytest in newer versions
cbjuan Dec 1, 2025
537cf61
Fix more issues with async tests after last changes
cbjuan Dec 1, 2025
8393d24
Fix issues for python 3.14
cbjuan Dec 1, 2025
1d4b726
Merge branch 'main' into improving-pyproject-tomls
cbjuan Dec 1, 2025
b9320ab
Ruff format
cbjuan Dec 1, 2025
b9dfc15
Update PUBLISHING.md
cbjuan Dec 1, 2025
9c8e641
Merge branch 'improving-pyproject-tomls' into improve-package-releases
cbjuan Dec 1, 2025
09d8082
Lint fixes
cbjuan Dec 1, 2025
532703d
Merge branch 'improving-pyproject-tomls' into improve-package-releases
cbjuan Dec 1, 2025
b611380
QCA fixes
cbjuan Dec 1, 2025
a978bf8
Merge pull request #42 from Qiskit/improve-package-releases
cbjuan Dec 1, 2025
17ff897
Fixing corrupted uv.lock
cbjuan Dec 1, 2025
78a92dc
Ruff format
cbjuan Dec 1, 2025
295a48c
Merge branch 'main' into improving-pyproject-tomls
cbjuan Dec 1, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 42 additions & 5 deletions .github/workflows/publish-pypi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,21 @@ on:
workflow_dispatch:
inputs:
package:
description: 'Package to publish (code-assistant, runtime, or both)'
description: 'Package to publish'
required: true
default: 'both'
default: 'all'
type: choice
options:
- both
- all
- meta-package
- code-assistant
- runtime

jobs:
publish-code-assistant:
if: |
(github.event_name == 'release' && contains(github.ref, 'code-assistant')) ||
(github.event_name == 'workflow_dispatch' && (github.event.inputs.package == 'both' || github.event.inputs.package == 'code-assistant'))
(github.event_name == 'workflow_dispatch' && (github.event.inputs.package == 'all' || github.event.inputs.package == 'code-assistant'))
runs-on: ubuntu-latest
permissions:
id-token: write # Required for trusted publishing
Expand Down Expand Up @@ -50,7 +51,7 @@ jobs:
publish-runtime:
if: |
(github.event_name == 'release' && contains(github.ref, 'runtime')) ||
(github.event_name == 'workflow_dispatch' && (github.event.inputs.package == 'both' || github.event.inputs.package == 'runtime'))
(github.event_name == 'workflow_dispatch' && (github.event.inputs.package == 'all' || github.event.inputs.package == 'runtime'))
runs-on: ubuntu-latest
permissions:
id-token: write # Required for trusted publishing
Expand All @@ -77,3 +78,39 @@ jobs:
with:
packages-dir: qiskit-ibm-runtime-mcp-server/dist/
verbose: true

publish-meta-package:
runs-on: ubuntu-latest
# Meta-package should be published after individual servers
needs: [publish-code-assistant, publish-runtime]
# Allow meta-package to run even if individual packages were skipped (already published)
if: |
always() &&
(needs.publish-code-assistant.result == 'success' || needs.publish-code-assistant.result == 'skipped') &&
(needs.publish-runtime.result == 'success' || needs.publish-runtime.result == 'skipped') &&
((github.event_name == 'release' && contains(github.ref, 'meta')) ||
(github.event_name == 'workflow_dispatch' && (github.event.inputs.package == 'all' || github.event.inputs.package == 'meta-package')))
permissions:
id-token: write # Required for trusted publishing
contents: read

steps:
- uses: actions/checkout@v4

- name: Install uv
uses: astral-sh/setup-uv@v3
with:
version: "latest"

- name: Set up Python
run: uv python install 3.12

- name: Build meta-package
run: |
uv build

- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
packages-dir: dist/
verbose: true
70 changes: 46 additions & 24 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,52 @@ on:
branches: [ main, develop ]

jobs:
# Fast feedback: linting and type checking
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Install uv
uses: astral-sh/setup-uv@v3
with:
version: "latest"
enable-cache: true

- name: Set up Python
run: uv python install 3.12

- name: Install dependencies
run: |
cd qiskit-code-assistant-mcp-server && uv sync --group dev
cd ../qiskit-ibm-runtime-mcp-server && uv sync --group dev

- name: Run ruff linting
run: |
cd qiskit-code-assistant-mcp-server && uv run ruff check src tests
cd ../qiskit-ibm-runtime-mcp-server && uv run ruff check src tests

- name: Run ruff formatting check
run: |
cd qiskit-code-assistant-mcp-server && uv run ruff format --check src tests
cd ../qiskit-ibm-runtime-mcp-server && uv run ruff format --check src tests

- name: Run type checking
run: |
cd qiskit-code-assistant-mcp-server && uv run mypy src
cd ../qiskit-ibm-runtime-mcp-server && uv run mypy src

- name: Run security checks
run: |
cd qiskit-code-assistant-mcp-server && uv run bandit -c pyproject.toml -r src
cd ../qiskit-ibm-runtime-mcp-server && uv run bandit -c pyproject.toml -r src

test-code-assistant:
runs-on: ubuntu-latest
needs: lint
strategy:
matrix:
python-version: ["3.10", "3.11", "3.12"]
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]

steps:
- uses: actions/checkout@v4
Expand All @@ -20,6 +61,7 @@ jobs:
uses: astral-sh/setup-uv@v3
with:
version: "latest"
enable-cache: true

- name: Set up Python ${{ matrix.python-version }}
run: uv python install ${{ matrix.python-version }}
Expand All @@ -29,17 +71,6 @@ jobs:
run: |
uv sync --group dev --group test

- name: Run linting for Code Assistant server
working-directory: ./qiskit-code-assistant-mcp-server
run: |
uv run ruff check src tests
uv run ruff format --check src tests

- name: Run type checking for Code Assistant server
working-directory: ./qiskit-code-assistant-mcp-server
run: |
uv run mypy src

- name: Run tests for Code Assistant server
working-directory: ./qiskit-code-assistant-mcp-server
env:
Expand All @@ -56,9 +87,10 @@ jobs:

test-runtime:
runs-on: ubuntu-latest
needs: lint
strategy:
matrix:
python-version: ["3.10", "3.11", "3.12"]
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]

steps:
- uses: actions/checkout@v4
Expand All @@ -67,6 +99,7 @@ jobs:
uses: astral-sh/setup-uv@v3
with:
version: "latest"
enable-cache: true

- name: Set up Python ${{ matrix.python-version }}
run: uv python install ${{ matrix.python-version }}
Expand All @@ -76,17 +109,6 @@ jobs:
run: |
uv sync --group dev --group test

- name: Run linting for Runtime server
working-directory: ./qiskit-ibm-runtime-mcp-server
run: |
uv run ruff check src tests
uv run ruff format --check src tests

- name: Run type checking for Runtime server
working-directory: ./qiskit-ibm-runtime-mcp-server
run: |
uv run mypy src

- name: Run tests for Runtime server
working-directory: ./qiskit-ibm-runtime-mcp-server
env:
Expand Down
125 changes: 106 additions & 19 deletions PUBLISHING.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,24 @@ This guide covers how to publish the Qiskit MCP servers to PyPI, both manually a

## Packages

This repository contains two separate PyPI packages:
This repository contains multiple PyPI packages:

1. **qiskit-code-assistant-mcp-server** - MCP server for Qiskit Code Assistant
2. **qiskit-ibm-runtime-mcp-server** - MCP server for IBM Quantum Runtime
3. **qiskit-mcp-servers** - Meta-package that installs all MCP servers

### Meta-Package

The `qiskit-mcp-servers` meta-package provides a convenient way to install all servers at once:

```bash
# Install all MCP servers
pip install qiskit-mcp-servers

# Or install individual servers via extras
pip install qiskit-mcp-servers[code-assistant] # Only Code Assistant
pip install qiskit-mcp-servers[runtime] # Only Runtime
```

## Automated Publishing (Recommended)

Expand Down Expand Up @@ -40,60 +54,119 @@ Alternatively, you can create releases manually through the GitHub web interface
1. Go to PyPI and create the project (if it doesn't exist):
- For `qiskit-code-assistant-mcp-server`: https://pypi.org/manage/project/qiskit-code-assistant-mcp-server/settings/publishing/
- For `qiskit-ibm-runtime-mcp-server`: https://pypi.org/manage/project/qiskit-ibm-runtime-mcp-server/settings/publishing/
- For `qiskit-mcp-servers`: https://pypi.org/manage/project/qiskit-mcp-servers/settings/publishing/

2. Add a "trusted publisher" with these settings:
- **PyPI Project Name**: `qiskit-code-assistant-mcp-server` (or `qiskit-ibm-runtime-mcp-server`)
- **PyPI Project Name**: `qiskit-code-assistant-mcp-server` (or `qiskit-ibm-runtime-mcp-server` or `qiskit-mcp-servers`)
- **Owner**: `AI4quantum`
- **Repository**: `qiskit-mcp-servers`
- **Repository**: `mcp-servers`
- **Workflow name**: `publish-pypi.yml`
- **Environment name**: (leave blank)

### Publishing via GitHub Releases

The workflow automatically publishes when you create a GitHub release:
The workflow automatically publishes when you create a GitHub release. The tag name determines which package is published.

#### Tag Naming Convention

| Tag Pattern | Package Published |
|-------------|-------------------|
| `code-assistant-v*` | qiskit-code-assistant-mcp-server |
| `runtime-v*` | qiskit-ibm-runtime-mcp-server |
| `meta-v*` | qiskit-mcp-servers (meta-package) |

#### Complete Release Workflow

Follow these steps to release a package:

##### Step 1: Update Version

Edit the version in the appropriate `pyproject.toml`:
- **Code Assistant**: `qiskit-code-assistant-mcp-server/pyproject.toml`
- **Runtime**: `qiskit-ibm-runtime-mcp-server/pyproject.toml`
- **Meta-package**: `pyproject.toml` (root)

##### Step 2: Commit and Push Changes

```bash
# Stage and commit the version change
git add -A
git commit -m "Bump qiskit-code-assistant-mcp-server to v0.1.1"

# Push to main branch
git push origin main
```

##### Step 3: Create and Push Tag

#### For Code Assistant Server:
```bash
# Update version in qiskit-code-assistant-mcp-server/pyproject.toml
# Then create and push a tag
# Create an annotated tag
git tag -a code-assistant-v0.1.1 -m "Release qiskit-code-assistant-mcp-server v0.1.1"

# Push the tag to GitHub
git push origin code-assistant-v0.1.1
```

##### Step 4: Create GitHub Release

```bash
# Create the release (this triggers the publish workflow)
gh release create code-assistant-v0.1.1 \
--title "qiskit-code-assistant-mcp-server v0.1.1" \
--generate-notes
```

Or use `--notes "Your release notes here"` instead of `--generate-notes` for custom notes.

#### Quick Reference Examples

# Create a GitHub release from this tag
gh release create code-assistant-v0.1.1 --title "qiskit-code-assistant-mcp-server v0.1.1" --notes "Release notes here"
**Code Assistant Server:**
```bash
# After updating version in qiskit-code-assistant-mcp-server/pyproject.toml
git add -A && git commit -m "Bump code-assistant to v0.1.1" && git push origin main
git tag -a code-assistant-v0.1.1 -m "Release v0.1.1" && git push origin code-assistant-v0.1.1
gh release create code-assistant-v0.1.1 --title "qiskit-code-assistant-mcp-server v0.1.1" --generate-notes
```

#### For Runtime Server:
**Runtime Server:**
```bash
# Update version in qiskit-ibm-runtime-mcp-server/pyproject.toml
# Then create and push a tag
git tag -a runtime-v0.1.1 -m "Release qiskit-ibm-runtime-mcp-server v0.1.1"
git push origin runtime-v0.1.1
# After updating version in qiskit-ibm-runtime-mcp-server/pyproject.toml
git add -A && git commit -m "Bump runtime to v0.1.1" && git push origin main
git tag -a runtime-v0.1.1 -m "Release v0.1.1" && git push origin runtime-v0.1.1
gh release create runtime-v0.1.1 --title "qiskit-ibm-runtime-mcp-server v0.1.1" --generate-notes
```

# Create a GitHub release from this tag
gh release create runtime-v0.1.1 --title "qiskit-ibm-runtime-mcp-server v0.1.1" --notes "Release notes here"
**Meta-Package:**
```bash
# After updating version in pyproject.toml (root)
git add -A && git commit -m "Bump meta-package to v0.1.1" && git push origin main
git tag -a meta-v0.1.1 -m "Release v0.1.1" && git push origin meta-v0.1.1
gh release create meta-v0.1.1 --title "qiskit-mcp-servers v0.1.1" --generate-notes
```

### Manual Workflow Trigger

You can also trigger publishing manually via GitHub Actions using the CLI:

```bash
# Publish both packages
gh workflow run "Publish to PyPI" -f package=both
# Publish all packages (individual servers + meta-package)
gh workflow run "Publish to PyPI" -f package=all

# Publish only code-assistant
gh workflow run "Publish to PyPI" -f package=code-assistant

# Publish only runtime
gh workflow run "Publish to PyPI" -f package=runtime

# Publish only meta-package
gh workflow run "Publish to PyPI" -f package=meta-package
```

Alternatively, you can trigger via the GitHub web interface:

1. Go to **Actions** → **Publish to PyPI**
2. Click **Run workflow**
3. Select which package to publish: `both`, `code-assistant`, or `runtime`
3. Select which package to publish: `all`, `meta-package`, `code-assistant`, or `runtime`

## Manual Publishing

Expand All @@ -118,6 +191,7 @@ pip install uv
Edit the version in `pyproject.toml`:
- **Code Assistant**: `qiskit-code-assistant-mcp-server/pyproject.toml`
- **Runtime**: `qiskit-ibm-runtime-mcp-server/pyproject.toml`
- **Meta-package**: `pyproject.toml` (root)

#### 2. Build the Package

Expand All @@ -143,6 +217,15 @@ uv build
python -m build
```

**For Meta-Package:**
```bash
# From repository root
uv build

# Or with build
python -m build
```

This creates `.whl` and `.tar.gz` files in the `dist/` directory.

#### 3. Verify the Build
Expand Down Expand Up @@ -188,6 +271,9 @@ pip install qiskit-code-assistant-mcp-server

# For Runtime
pip install qiskit-ibm-runtime-mcp-server

# For Meta-Package (installs all servers)
pip install qiskit-mcp-servers
```

## Version Management
Expand All @@ -206,6 +292,7 @@ The current version for each package is defined in their respective `pyproject.t

- **qiskit-code-assistant-mcp-server**: See [qiskit-code-assistant-mcp-server/pyproject.toml](qiskit-code-assistant-mcp-server/pyproject.toml) (search for `version =`)
- **qiskit-ibm-runtime-mcp-server**: See [qiskit-ibm-runtime-mcp-server/pyproject.toml](qiskit-ibm-runtime-mcp-server/pyproject.toml) (search for `version =`)
- **qiskit-mcp-servers**: See [pyproject.toml](pyproject.toml) (search for `version =`)

## Pre-Publication Checklist

Expand Down
Loading
Loading