Encrypted, ephemeral, private memos on atproto
TypeScript 100.0%
62 1 0

Clone this repository

https://tangled.org/graham.systems/cistern
git@tangled.org:graham.systems/cistern

For self-hosted knots, clone URLs may differ based on your setup.

README.md

Cistern#

Cistern is a private, end-to-end encrypted quick-capture system built on AT Protocol. Memos are encrypted using post-quantum cryptography and stored temporarily in your Personal Data Server (PDS), then automatically retrieved and deleted after consumption.

The system bridges the gap between where ideas are captured and where they are stored long-term. Create an encrypted memo on your phone, and it automatically appears in your desktop application, decrypted and ready to use.

Architecture#

Cistern is a Deno monorepo consisting of six packages:

@cistern/crypto#

Core cryptographic operations using post-quantum algorithms. Implements X-Wing key encapsulation with XChaCha20-Poly1305 authenticated encryption and SHA3-512 integrity verification. Handles keypair generation, encryption, and decryption.

@cistern/lexicon#

AT Protocol schema definitions for Cistern record types. Defines app.cistern.pubkey (public key records) and app.cistern.memo (encrypted memo records). Includes code generation from JSON schemas.

@cistern/shared#

Common utilities and authentication logic. Handles DID resolution via Slingshot service and creates authenticated RPC clients using app passwords.

@cistern/producer#

Creates and encrypts memos for storage. Manages public key selection, encrypts plaintext content, and uploads encrypted memos to the PDS as AT Protocol records.

@cistern/consumer#

Retrieves, decrypts, and deletes memos. Generates keypairs, manages private keys locally, retrieves memos via polling or real-time streaming (Jetstream), and handles memo deletion after consumption.

@cistern/mcp#

Model Context Protocol server that exposes Cistern as MCP tools for AI assistants. Supports stdio transport for local integrations (Claude Desktop) and HTTP transport for remote deployments. Automatically generates and persists keypairs in Deno KV.

Security Model#

Private keys never leave the consumer device. Public keys are stored in the PDS as records, while private keys remain off-protocol. Only the holder of the matching private key can decrypt memos encrypted with the corresponding public key.

Quick Start#

Using the MCP Server with Claude Desktop#

  1. Generate an app password for your Bluesky account
  2. Add to Claude Desktop config (~/Library/Application Support/Claude/claude_desktop_config.json):
{
  "mcpServers": {
    "cistern": {
      "command": "deno",
      "args": ["task", "--cwd", "/path/to/cistern/packages/mcp", "stdio"],
      "env": {
        "CISTERN_MCP_HANDLE": "yourname.bsky.social",
        "CISTERN_MCP_APP_PASSWORD": "xxxx-xxxx-xxxx-xxxx"
      }
    }
  }
}
  1. Restart Claude Desktop
  2. Create memos using the Cistern Producer from any device
  3. Ask Claude to retrieve and process your memos

See packages/mcp/README.md for detailed usage.

Testing#

Run all unit tests:

deno test --allow-env

Run end-to-end tests (requires AT Protocol credentials):

CISTERN_HANDLE="your.bsky.social" \
CISTERN_APP_PASSWORD="xxxx-xxxx-xxxx-xxxx" \
deno test --allow-env --allow-net e2e.test.ts