SDKs
SDKs (Python & Go)
Two flavors of the same thing: fingerprint the machine, activate, verify
offline tokens, and auto-revalidate. Pick the one that fits your stack —
or shell out to the Go mmk binary from anything.
Python — sdk/python/mmk.py
One file, zero HTTP dependencies (stdlib urllib), cryptography for offline
verification only.
Install
pip install cryptography # the only dependency
Quickstart
import sys
import mmk
client = mmk.MMK(
base_url="http://localhost:8080",
product_id=1,
api_key="<product api key>", # from POST /v1/products
public_key_pem=open("product.pub.pem").read(), # from the same response
)
On purchase (or first run)
result = client.activate("9TMC-5TS9-0MKQ-VS8A-87Q0", name="My MacBook")
if result.get("status") != "active":
sys.exit(f"activation failed: {result}")
# the offline token is cached automatically
On every launch
claims = client.ensure_valid()
if claims is None:
sys.exit("license invalid — please check your key")
ensure_valid() is the whole story:
- cached token exists and its signature / expiry / fingerprint check out → instant approval, no network,
- otherwise it calls
validateonce; a fresh signed token is cached, - revoked or expired →
None→ you deny.
Deactivation (optional — frees a seat)
client.deactivate()
Go — sdk/go (library + mmk binary)
Pure Go standard library — zero external modules, cross-compiles everywhere, and the CLI is a single static binary with no runtime. If your stack isn't Python (Tauri, Go apps, C++, Unity), this is your path.
Build
cd sdk/go
go build ./cmd/mmk # mmk.exe on Windows, mmk on Linux/macOS
GOOS=linux GOARCH=amd64 go build ./cmd/mmk # cross-compile for a server/CI
CLI quickstart
./mmk fingerprint
# 6805c498fd6654ede932a2d67949da69a96d44115ec8e7ba7cec94d5c8f4220b
./mmk activate --url http://localhost:8080 --product 1 \
--api-key <product api key> --key 9TMC-5TS9-0MKQ-VS8A-87Q0 \
--name "My MacBook" --platform macos
# {"status": "active", "license": {...}, "offline_token": "eyJ..."}
./mmk check --url http://localhost:8080 --product 1 \
--api-key <product api key> --pubkey product.pub.pem
# VALID license 9TMC-5TS9-0MKQ-VS8A-87Q0 (policy: lifetime)
./mmk verify --pubkey product.pub.pem --token "eyJ..." --fingerprint 6805c498...
check is the offline-first path: a cached token that verifies (signature,
expiry, fingerprint) is accepted with zero network; otherwise it revalidates
and refreshes the cache. Config can also come from env vars: MMK_URL,
MMK_PRODUCT_ID, MMK_API_KEY, MMK_LICENSE_KEY.
As a library
import "minmaxkey.dev/mmk"
c := mmk.NewClient("http://localhost:8080", 1, apiKey, publicKeyPEM, licenseKey)
claims, err := c.EnsureValid() // offline-first, caches token
if err != nil {
log.Fatal("not licensed")
}
fmt.Println("licensed for", claims.Sub)
mmk.VerifyToken(token, publicKeyPEM, fingerprint) does the offline check in
any context — embed it in your Go app, or call the binary from CI.
Machine fingerprinting
Both SDKs hash the most stable hardware identifier they can find:
- Windows — registry
MachineGuid - Linux —
/etc/machine-id(or DMI product UUID) - macOS —
IOPlatformUUID(ioreg) - fallback — hostname + machine type
It's deterministic on a given install, survives reboots, and changes on OS reinstall — that's by design, and it's why the dashboard has a reset seats button. It's a friendly binding, not a security boundary.
Offline verification
from mmk import verify_token
claims = verify_token(token, client.public_key_pem, expected_fingerprint=client.fingerprint)
# raises ValueError on bad signature / expiry / wrong machine
claims, err := mmk.VerifyToken(token, publicKeyPEM, fingerprint)
The API key question
Your app ships with the product api_key — that's fine. It only gates
operations the license key + fingerprint already authorize, and it's how the
server distinguishes your product. Treat the license key itself as the
credential.
Roadmap notes
- TypeScript / C# ports will land as the server API stabilizes — the wire format is language-agnostic.