๐ Wyrm Cloud โ
Encrypted multi-device sync for the Wyrm MCP server. Free for solo, $0/month forever.
Live at wyrm.ghosts.lk.
Two editions โ don't confuse them (constitution Article IX):
- Wyrm Sync โ this page. Zero-knowledge, end-to-end encrypted multi-device sync. Your master key never leaves your device; the server stores opaque ciphertext and cannot read your memory.
- Wyrm Cloud (managed memory) โ a separate, opt-in, entitlement-gated tier at mcp.wyrm.ghosts.lk for Claude web/phone connectors (remote MCP). Those clients have no local machine or key, so this store is server-readable by design (not E2E) and disclosed as such. It is never created from your Sync/Local data automatically.
What it does โ
You install wyrm-mcp on your phone, laptop, workstation. Each one has its own local Wyrm database. Without Wyrm Cloud, those databases drift โ a quest you closed on your laptop doesn't appear on your phone.
With Wyrm Cloud:
- You sign in once per device with Google or GitHub
- Mark rows as cross-project visible (
cross_project_visibility = 'org'or'public') - Run
wyrm cloud syncโ those rows are encrypted client-side, pushed to the cloud, then pulled to your other devices - The cloud stores opaque ciphertext only โ your encryption key never leaves your devices
What's encrypted โ
| Row type | Synced |
|---|---|
| Ground truths | โ |
| Memory artifacts | โ |
| Quests | โ |
| Design tokens | โ |
| Design references | โ |
| Sessions, hour entries, failure patterns | โ (device-local time-series) |
Only rows where you explicitly set cross_project_visibility = 'org' or 'public' are pushed. Default is 'within' โ local-only.
Quick start โ
# install the latest stable
npm install -g wyrm-mcp@latest
# sign in (browser flow with Google or GitHub)
wyrm cloud login
# see what's there
wyrm cloud status
# push + pull
wyrm cloud syncThe login flow:
- CLI prints
https://wyrm.ghosts.lk/cliand a short code likeABCD-1234 - You open the URL on your phone, type the code, sign in
- CLI polls; completes in seconds
Encryption details โ
- Algorithm: AES-256-GCM (Cloudflare server cannot decrypt)
- Key: 32 random bytes stored at
~/.wyrm/cloud.key(0600 perms) - Generated automatically on first
wyrm cloud login - Per-payload envelope:
[version:1][iv:12][ciphertext+tag:N+16] - Tamper detection: GCM auth tag rejects modified ciphertext
You're responsible for backing up ~/.wyrm/cloud.key. Losing it means losing access to your synced data โ by design. This is the operator-owns-data guarantee in our constitution.
Architecture โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Your machine โ โ Cloudflare edge โ
โ wyrm-mcp + wyrm CLI โ โ wyrm.ghosts.lk Worker โ
โ ~/.wyrm/wyrm.db (SQLite) โ HTTPS+Bearer โ โ
โ ~/.wyrm/cloud.key (0600) โ โโโโโโโโโโโบ โ Validates session โ
โ โ โ Stores ciphertext in R2 โ
โ Encrypts BEFORE sending โ โ Indexes deltas in D1 โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโโโโโThe cloud server has access to:
- Your email + the OAuth provider (Google or GitHub) you signed in with
- Counts of deltas, devices, storage usage
- Encrypted blob bytes (opaque to the server)
The cloud server does NOT have access to:
- Plaintext memory content
- Your encryption key (
~/.wyrm/cloud.key) - The actual
kind,row_id, orpayloaddata inside blobs (well โkindis cleartext for filtering, but the payload contents are encrypted)
Tiers โ
| Tier | Price | Storage | Sync ops | Features |
|---|---|---|---|---|
| Free | $0 | 1 GiB | 100/day | Unlimited devices, all features |
| Pro | $5/mo | 10 GiB | unlimited | Higher per-delta cap |
| Team | $15/seat | 100 GiB pooled | unlimited | Org tier โ cross-account 'org' sync |
| Org | custom | unlimited | unlimited | SLA + SOC2 attestation |
Paid tiers wire when Stripe is configured server-side. Until then everyone is on Free which covers solo personal use forever.
Web dashboard โ
wyrm.ghosts.lk/login โ same Google/GitHub sign-in, then a web dashboard at /app showing:
- Account email + tier
- Storage usage
- Devices (revoke individual machines)
- Orgs you belong to
- Logout
CLI command reference โ
wyrm cloud login # Google or GitHub OAuth
wyrm cloud logout # revoke session both ends
wyrm cloud status # account / tier / storage / devices
wyrm cloud devices # list registered devices
wyrm cloud devices revoke <id> # revoke a specific device
wyrm cloud sync [--dry-run] # push + pull encrypted deltasConfig locations:
~/.wyrm/cloud.jsonโ session token (HttpOnly-equivalent, 0600)~/.wyrm/cloud.keyโ AES-256-GCM master key (0600, NEVER shared)~/.wyrm/cloud-cursor.jsonโ last-pulled timestamp per device
Security guarantees โ
- All HTTP traffic over TLS 1.3 (Cloudflare-enforced)
- 60-second timeout on every CLI request (no hung sessions)
- OAuth login defeats: code-substitution phishing (typed-code), login-CSRF (state-cookie binding), redirect-URI tampering (registered-URI verification)
- Sessions are 256-bit random tokens, 30-day expiry, revocable instantly
- Devices revoked from the dashboard refuse future syncs at the next attempt
- Server-side: every D1 query is tenancy-filtered by
account_idfrom the validated Bearer - Pentest pass: 50+ adversarial probes across SQL injection, IDOR, oversize payloads, cleartext-payload rejection โ all clean
Constitution alignment โ
Wyrm Cloud is rule I (local-first) compliant: Wyrm runs unchanged without ever logging in. The cloud is purely additive opt-in.
Wyrm Cloud is rule IV (operator owns the data) compliant: AES-256-GCM with operator-held keys, server stores opaque blobs only, full data export via ~/.wyrm/wyrm.db, can be deleted on demand.
Open source โ
- Server code: github.com/Ghosts-Protocol-Pvt-Ltd/wyrm-cloud
- Spec: dragon-platform/specs/019-wyrm-cloud-sync
- CLI code: github.com/Ghosts-Protocol-Pvt-Ltd/Wyrm โ
packages/mcp-server/src/cloud/
Cost transparency โ
Wyrm Cloud runs on Cloudflare's free tier:
- Workers: 100K requests/day free
- D1: 5GB ยท 5M reads/day ยท 100K writes/day free
- R2: 10GB storage ยท $0 egress free
At current scale (single founder + a few testers), monthly cost is $0.00. We'll publish a hosting-cost transparency report once paid tiers exist + traffic warrants it.