Python client, CLI, and provisioning toolkit for Sovereign Hybrid Compute (SHC) — the quickest way to spin up a VM, give it a NoDNS domain via Nostr, and get HTTPS with Let's Encrypt DNS-01. No domain registrar needed.
Disclosure: The SHC link above is an affiliate link. If you sign up through it, we receive a 5% recurring commission (grandfathered rate) on your spending, at no extra cost to you. We use SHC as the CI backend for our open-source projects and genuinely recommend the service.
- terraform-provider-shc — Terraform provider for SHC
- shc-pulumi — Pulumi provider for SHC
shcCLI — order, manage, and snapshot VMs from the command line- Python client —
SHCClientwraps the full SHC User API - NoDNS integration — publish DNS records via Nostr events (kind 11111)
- Certbot DNS-01 — get Let's Encrypt certs without opening port 80
- Provisioning helpers — one-call setup for Caddy + HTTPS on a fresh VM
pip install -e .Requires Python 3.11+.
export SHC_API_KEY="shc_live_..."
shc catalog
shc order --hostname my-vm --package-id 23 --pricing-id 55 \
-o 108=50 -o 126=debian12-cloud -o 167=none \
--ssh-key ~/.ssh/id_ed25519.pub --pay
shc list
shc info <service_id>
shc cancel <service_id>from shc_toolkit import SHCClient
c = SHCClient()
vms = c.list_vms()
c.start_vm(123)
c.create_snapshot(123, name="pre-deploy")NoDNS maps Nostr keypairs to .nodns.shop subdomains. You publish DNS records as kind 11111 Nostr events, and the nodns-bot pushes them to Knot DNS. No domain registration, no DNS provider account.
Your machine
└── nostr-sdk → publishes kind 11111 events to Nostr relays
↓
nodns-bot → Knot DNS (ns1.nodns.shop)
↓
Public DNS: <npub>.nodns.shop A <your-vm-ip>
from shc_toolkit.nodns import NoDNSKeyPair, publish_dns_records
kp = NoDNSKeyPair.generate()
print(f"Domain: {kp.fqdn}")
print(f"Save this nsec to update records later: {kp.nsec}")
publish_dns_records(kp, [
{"type": "A", "name": "@", "value": "<your-vm-ip>", "ttl": 300},
])shc nodns --ip <your-vm-ip>The provisioning module automates the complete flow on a fresh Debian VM:
from shc_toolkit.client import SHCClient
from shc_toolkit.nodns import NoDNSKeyPair, publish_dns_records
from shc_toolkit.provision import install_caddy, get_cert_dns01
# 1. Order a VM (or use an existing one)
c = SHCClient()
vm = c.get_vm_summary(123)
ip = vm["ips"][0]["ip"]
# 2. Publish A record via NoDNS
kp = NoDNSKeyPair.generate()
publish_dns_records(kp, [{"type": "A", "name": "@", "value": ip, "ttl": 300}])
# 3. Install Caddy + get Let's Encrypt cert via DNS-01
install_caddy(ip)
get_cert_dns01(ip, kp.fqdn, keypair_path="/tmp/nodns-keypair.json")For the certbot auth hook to work, save the keypair and deploy nodns_vm.py to the VM first. See shc_toolkit/provision.py for details.
$ curl https://npub1mv7l45exqsu5nr5tnefkr33ruhzjj4r8prg6qtcedv4lyf3rzguqptuwm4.nodns.shop
Hello from NoDNS + Let's Encrypt DNS-01!Certificate issued by Let's Encrypt via DNS-01 through nodns. No port 80, no traditional DNS provider, no domain registrar.
The SHC User API has full documentation available at:
- Interactive docs: https://blesta.sovereignhybridcompute.com/user-api/docs/
- OpenAPI 3.1 spec: https://blesta.sovereignhybridcompute.com/user-api/openapi.json
- LLM-friendly docs: https://blesta.sovereignhybridcompute.com/user-api/llms.txt
This toolkit covers the most common endpoints (VM lifecycle, ordering, snapshots, billing). For operations not yet wrapped (reinstall, backups, etc.), use SHCClient._request() directly or open a PR.
The toolkit supports dual transport: REST v2 (default) or MCP Streamable HTTP. Both transports are fully functional for all operations including reads, writes, spend/destructive actions with confirmation flow, and upgrades.
The flagship SHC MCP server at https://mcp.sovereignhybridcompute.com/ exposes
116 tools over Streamable HTTP. Every spend and destructive op is confirm-gated.
CI tests randomly select REST or MCP per run, ensuring both transports receive equal coverage over time without doubling test cost.
from shc_toolkit import create_client
# Auto (defaults to REST — change with SHC_TRANSPORT=mcp)
c = create_client(transport="auto")
# Force MCP
c = create_client(transport="mcp")
# Force REST (default)
c = create_client(transport="rest")Or via environment variable:
export SHC_TRANSPORT=mcp # or 'rest' or 'auto'Install the MCP optional dependency:
pip install shc-toolkit[mcp]Both transports implement the same SHCTransport interface — your code works
unchanged regardless of which backend is selected.
Option IDs differ by VPS line. Always read them from shc catalog or GET /ordering/catalog.
For NVMe Starter (package_id 23):
| Option | ID | Example values |
|---|---|---|
| RAM | 106 | 4096 (base), 8192, 16384 |
| CPU | 107 | 1 (base), 2, 4 |
| Disk | 108 | 8 (base), 32, 50, 100 |
| IPv4 | 109 | 1 (base), 2, 4 |
| Template (NVMe/HDD/SSD) | 126 | debian13-cloud, debian12-cloud, ubuntu2404-cloud, ubuntu2204-cloud, fedora43-cloud, arch-cloud, nixos-cloud, almalinux9-cloud, alpine323-cloud, devuan5-cloud, openbsd79-cloud |
| Template (Dev VPS) | 174 | Same as above |
| GUI | 167 | none, gnome, kde, xfce, cinnamon, mate |
Values are the value field from the catalog, not value_id.
Windows is available bring-your-own-license on all VPS lines: Windows Server 2022/2025 (Core or Desktop) and Windows 11 Pro. Windows Server requires >=32GB disk; Windows 11 requires >=64GB disk. Apply your own license after first boot.
GUI requires >=16GB disk AND >=4GB RAM.
Disposable per-job CI runners on cheap SHC VPSs. The toolkit orders a VPS,
bootstraps the GitHub Actions runner over SSH with --ephemeral, registers
it with a unique per-run label, and the workflow destroys the VM in an
if: always() teardown job when the benchmark finishes.
Live-measured cold-start: 135.8 s end-to-end on dev-4c-16gb
($0.90/day, ~$0.01 per run prorated). Workload execution matches
ubuntu-latest per-shard. Full perf comparison and the Firecracker
cold-start reduction target live in
docs/github-ephemeral-runners.md.
Firecracker PoC validated: nested KVM works on SHC Dev VPS, μVMs boot
in ~2 s vs the 100 s VPS scheduling floor — 50× faster per job,
150× throughput at parallelism 4. Pool-mode architecture and live
benchmark numbers in
docs/firecracker-pool-mode.md.
export SHC_API_KEY="shc_live_..."
export SHC_GITHUB_ADMIN_TOKEN="ghp_..." # PAT with repo admin / runners:write
shc github-runner provision \
--repo Amperstrand/tollgate-module-basic-go \
--labels shc-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}
shc github-runner destroy --service-id "$SERVICE_ID"Intended audience: OSS maintainers with expensive / slow / custom CI who want pay-per-minute runners on machines they control.
- Nested KVM: Available ONLY on Dev VPS plans (pkg 80–84, Cherryvale, KS). NVMe/SSD/HDD VPS plans do NOT expose VMX/SVM to guests — QEMU runs in TCG (software emulation) only. Verify after ordering with
grep -E 'vmx|svm' /proc/cpuinfo. - Hourly proration: You're charged the full daily rate at order time, but get refunded for unused hours when you cancel (minimum 1 hour charge). A 2-hour session on a $0.49/day plan costs ~$0.04.
- Single location: Katy, Texas only.
- API key lifecycle: API keys expire after 90 days (max 730). A 401 on a working key means it expired — mint a new one at
/account/api-keys. Maximum 25 active keys per account. - Snapshot/backup limit: All VPS plans (including Dev VPS) support 1 snapshot and 1 backup concurrently (
snapshot_limit: 1,backup_limit: 1per package). Verified working on Dev VPS via front-door E2E (2026-07-01).
A pay-per-minute SSH server that accepts Cashu ecash tokens as payment. Users paste a token as their SSH username and get an interactive bash shell for as many minutes as the token is worth. Includes a static faucet page for minting free test tokens.
MIT
- READS: All working (getAccount, getBillingBalance, listVirtualMachines, getOrderingCatalog)
- WRITES: All working (createVirtualMachineOrder with confirmation flow, cancelVirtualMachine)
- CI: Randomly selects REST or MCP per run for equal coverage
- Ticket #220 resolved by SHC (SQL drift + timestamp bug + missing firewall rule)
- Code is complete and correct (keypair generation, event publishing, DNS verification)
- VERIFIED: Published A record resolves correctly within 10 seconds
- Bot was down (SOA stale since June 9) — restarted, added relay.damus.io + nos.lol, disabled PoW requirement
shc nodns --ip <ip> --zone nodns.shoppublishes,shc order --nodnsauto-publishes after VM creation- Wildcard
*.nodns.shop → 46.224.104.12is overridden by per-npub records when published
- Bootstrap code complete and tested on NVMe VPS (Debian 13, Katy TX)
- Installs unzip + Bun + @contextvm/sdk, deploys gateway server, sets up systemd
- VM becomes discoverable MCP server on Nostr via
wss://relay.contextvm.org - Verified: service active (0 restarts), pubkey generated, relay connected, announcements broadcast
- Fixed 4 bugs found during live test: missing
unzipprereq,nostr-toolsAPI drift (hexToBytesremoved), systemd PATH missing bun,relayUrls→relayHandlerrename in SDK - Test cost: $0.01 (ordered VM 761, verified, canceled in 12 min, $0.25 refunded)