Skip to content
marmot-protocolPublic

About

Marmot Development Kit

Resources

Stars

67 stars

Watchers

1 watching

Forks

Latest commit

 

History

1,564 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

MDK — Marmot Development Kit

MDK is the Rust implementation of Marmot, an end-to-end encrypted group messaging protocol built on MLS (RFC 9420) with Nostr identity. It powers White Noise: the protocol engine, encrypted storage, Nostr transport, the app runtime behind the mobile bindings, the wn command-line app, and the wn-agent connector that brings AI agents into encrypted chats.

The protocol specification lives in marmot-protocol/marmot. This repository holds the implementation, its architecture notes, conformance tests, formal models, and release tooling.

Contents

Find your way

I want to… Start here
Talk to Hermes, OpenClaw, Claude Code, Codex, OpenCode, Pi, or Goose from White Noise White Noise + Agents quickstart
Use White Noise from a terminal (CLI, daemon, TUI) wn guide
Integrate MDK into an iOS, macOS, or Android app MarmotKit integration guide
Integrate from C or another raw-FFI host C ABI guide
Upgrade an app to a new MDK release Version upgrade guides
Understand the Marmot protocol Marmot specification
Understand MDK's architecture Architecture index
Understand how clients agree on group state How convergence works
Contribute code Development
Cut a release Release guide

Chat with an AI agent

wn-agent gives an agent runtime its own White Noise identity and bridges encrypted Marmot chats to it over a local control socket (same-user by default, optional bearer token). You invite the agent from White Noise on your phone like any other contact; only accounts you allowlist can invite or message it.

Runtime Connector Docs
Hermes Gateway plugin integrations/hermes
OpenClaw Channel plugin integrations/openclaw
Claude Code Terminal harness integrations/claude
Codex Terminal harness integrations/codex
OpenCode Terminal harness integrations/opencode
Pi Terminal harness integrations/pi
Goose Terminal harness integrations/goose

The quickstart installs a checksum-verified release on macOS or Linux and gets you to a first encrypted chat. For how connectors share one machine, identities, and allowlists, see How the connectors fit together. The connector daemon itself is documented in crates/agent-connector.

The wn command-line app

wn manages accounts, relays, KeyPackages, chats, groups, and messages, and includes a terminal UI (wn tui). wnd is the background daemon that keeps accounts synced and serves the CLI and TUI. Install both from a checkout:

cargo install --path crates/cli --locked --bins

The wn guide covers configuration, a two-account quick start against local relays, the full command map, the daemon, the TUI, and JSON output for scripting.

Build an app on MDK

Apps embed MDK through the multi-account app runtime (marmot-app), exposed as:

Each release ships a concise release note and a detailed upgrade guide with required changes, new defaults, and optional features. The latest is 0.12.0 → 0.13.0; read every intervening guide when skipping releases. Read docs at the tag matching your binaries — master may describe unreleased APIs.

How MDK is built

MDK separates the protocol engine from storage, transport, and application concerns so each can be tested, replaced, and reasoned about on its own:

 apps (MarmotKit / C)    wn CLI · wnd · TUI    wn-agent ──► agent runtimes
            └────────────────┬─────┴──────────────┘
                     marmot-app        multi-account runtime, projections
                     marmot-account    account homes, keys, transport orchestration
                     cgka-session      one encrypted account-device lifecycle
                     cgka-engine       OpenMLS group state machine + commit convergence
                     storage-sqlite    SQLCipher persistence (one DB per account-device)

 transport-nostr                     the relay plane: shared relay sessions, delivery, directory fetches
 transport-nostr-peeler / -adapter   Nostr events ⇄ engine messages, relay I/O
 transport-quic-stream / -broker     transient live previews for agent replies

How convergence works

In Marmot, commits are the consensus log. Clients fetch from several relays, see messages in different orders, and may come back online holding commits from abandoned branches. Every honest client that receives the same valid messages must still land on the same epoch and group state. The engine — not relay order or timestamps — picks the canonical branch.

To understand… Read
The convergence model Distributed convergence
The engine's canonicalization contract Canonicalization contract
How it is tested: scenarios, vectors, generated chaos, property tests Conformance simulator
Multi-process and container campaigns Campaign runner
Formal proofs and how they map to Rust tests Tamarin models
What the engine owns and leaves out cgka-engine

Crate map

Area Crate What it is
Engine cgka-engine OpenMLS-backed group state machine and commit convergence
traits (cgka-traits) Shared traits and cross-boundary types
cgka-session Encrypted account-device session over the engine
Storage storage-sqlite SQLCipher persistence for engine, session, and simulator
fs-private Owner-only file, directory, and socket creation
media-store Encrypted per-file media store: file format and file lifecycle
Transport transport-nostr-peeler Nostr event ⇄ engine message boundary
transport-nostr-adapter Relay I/O behind an injectable client
transport-nostr The relay plane: per-account relay sessions, delivery and directory fetches
transport-quic-stream QUIC transport for live agent text previews
transport-quic-broker Memory-only preview broker (marmot-quic-broker); deployment
App marmot-account Account homes, key storage, transport orchestration
marmot-app Multi-account app runtime used by every front end
marmot-markdown CommonMark + Nostr display parser for messages
marmot-forensics Append-only JSONL forensic audit schema
Bindings marmot-uniffi MarmotKit: Swift and Kotlin bindings
marmot-uniffi-macros Runs MarmotKit's async exports on its own Tokio runtime
marmot-c C ABI bindings
Front ends cli (wn-cli) wn, wnd, and wn tui
Agents agent-connector The wn-agent connector daemon
agent-control Agent control protocol messages and framing
agent-stream-compose Live-preview stream composition
integrations/ Per-runtime plugins and terminal harnesses
Verification cgka-conformance-simulator Multi-client scenarios, vectors, chaos, property tests
convergence-campaign-runner Distributed container/VM campaigns
incident-replay Triages forensic exports of real incidents into verdicts and simulator vectors
formal/tamarin Tamarin models for convergence and lifecycle

Development

The toolchain is pinned in rust-toolchain.toml; most tasks run through just.

Cargo.toml patches HPKE 0.7 with the local vendor/hpke-rs-libcrux provider to use libcrux-kem 0.0.10, fixing RUSTSEC-2026-0330 and RUSTSEC-2026-0331. Its backport notes record provenance, regression commands and the removal condition.

just fast-ci                 # formatting, static gates, CI's two clippy passes; skips the `just test` matrix
cargo test -p <crate>        # targeted tests for the crate you changed
just ci                      # full local parity with GitHub CI (slow)

Pull requests run a pre-check of a few minutes: formatting, the static and contract gates, dependency audit, workspace clippy and the WASM build. They run no tests. The merge queue runs the full matrix on the exact commit it merges: every workspace test with the ci nextest profile, the CLI and relay end-to-end suites, simulator lanes, C bindings, iOS clippy, Windows filesystem contracts, Tamarin, Hermes and installer checks. Required CI must pass there before a change lands. Master pushes run CI only to refresh the Rust dependency caches that pull requests and merge groups restore, and only when Cargo.lock, a Cargo.toml, the toolchain pin, Cargo config or ci.yml changes.

Add ci:full and re-run all jobs to run the full matrix on a pull request, along with complete Android/Apple candidate packaging. ci:apple adds the iOS clippy lane and Apple packaging, and ci:android adds Android packaging; for packaging, re-run all candidate-workflow jobs or push a new commit. Ordinary PRs skip complete native candidate packaging, including Android target compilation and linking; use the opt-in when a change needs that signal before merging. Candidate packaging also runs on master when its inputs change, and weekly. Existing nightly and weekly campaigns retain their wider coverage. Broker image publishing stays serialized per ref so an older build cannot overwrite a newer latest image.

Common targeted runs:

cargo test -p cgka-engine
cargo test -p cgka-conformance-simulator                            # scenarios, vectors, property tests
cargo test -p cgka-conformance-simulator --features conformance-slow  # wider property-test run
just tamarin                                                        # formal models

The CLI's real-relay end-to-end tests need the local relay stack:

just relay-up
just e2e-test
just relay-down

Notes:

  • Stack size. .cargo/config.toml sets RUST_MIN_STACK=4194304 for Cargo-launched tests and debug binaries; unoptimized OpenMLS can overflow the default 2 MiB thread stack. Export the same value if you run a debug binary directly.
  • WASM. just wasm-check is a compile-only gate for cgka-traits, cgka-engine, and transport-nostr-peeler on wasm32-unknown-unknown (rustup target add wasm32-unknown-unknown; set CC_wasm32_unknown_unknown to a Clang with a wasm32 backend if needed). It does not claim browser support for storage, the runtime, bindings, or the CLI.
  • Commits must be cryptographically signed.

Releases

MDK versions the whole workspace as one compatibility cohort and publishes separate artifact tracks from the same commit: the source snapshot (v<version>), the wn-agent connector (wn-agent-v<version>), MarmotKit bindings (marmotkit-v<version>), and the C bindings (marmotc-v<version>). The release guide is the checklist; per-release notes live in docs/release/.

Nightly pre-releases such as marmotkit-v0.14.0-nightly.20261020 are built every day from the newest master commit that passed CI. They are for testing only: pin a formal release for anything you ship, expect each nightly to be deleted after 30 days, and don't count on going back to an older nightly. See nightly builds.

License

MIT.

About

Marmot Development Kit

Resources

Stars

67 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages