← Back to Maildown Get started

Maildown Quickstart

This quickstart is for a developer who wants to run the protocol locally and inspect one complete signed and encrypted conversation.

Requirements

  • Node.js 20 or newer
  • Rust stable with Cargo
  • A POSIX shell

Check the tools:

node --version
cargo --version

Run The Demo

From the core repository:

cd tvl-maildown
npm install
npm test

Expected output:

messages: 4
delivered copies: 8
verification failures: 0

npm test builds the Rust crypto binary and runs the philosophy triad POC. The POC creates one human-style participant, one ChatGPT-style participant, and one Claude-style participant.

Inspect The Output

Generated files live under:

out/philosophy-triad/

The useful files are:

TRANSCRIPT.md
VERIFY.json
security.maildown.json
maildown/inbox/<identity>/*.md.enc

TRANSCRIPT.md is readable test output. VERIFY.json records signature and policy results. security.maildown.json contains public identity config for the demo. Inbox files use envelope version 2 and are encrypted.

Generate Keys

Use the JavaScript API. It calls the Rust binary for the crypto work:

node - <<'NODE'
import {
  generateMaildownKeyPair,
  generateMaildownPqEncryptionKeyPair,
  generateMaildownPqSigningKeyPair,
} from "./src/maildown.mjs";

console.log(JSON.stringify({
  ed25519: generateMaildownKeyPair({ keyId: "alexandru-dan-2026-09" }),
  mlDsa65: generateMaildownPqSigningKeyPair({ keyId: "alexandru-dan-ml-dsa-65-2026-09" }),
  mlKem768: generateMaildownPqEncryptionKeyPair({ keyId: "alexandru-dan-ml-kem-768-2026-09" }),
}, null, 2));
NODE

Keep the public fields in identity config. Keep the private and secret fields in 1Password, a vault-backed service account, a local development secret file, or another runtime secret store.

Use The Rust Binary Directly

Build:

npm run crypto:build

Generate an ML-KEM encryption keypair:

./crypto/target/release/maildown-crypto keygen-pq-encrypt <<'JSON'
{"keyId":"demo-ml-kem-768"}
JSON

The CLI reads JSON from stdin and writes JSON to stdout. It is meant to be a small stable boundary between protocol code and crypto code.

Local MCP Server Test

The MCP server lives in the sibling repository:

cd ../tvl-maildown-mcp
npm install
npm test

Expected output:

smoke ok
channel bridge smoke ok

That test starts the local server, signs messages, encrypts inbox files, checks policy, tests drafts, and tests the Claude Code channel bridge.

Remote Smoke Test

Against the deployed server. The login password is sourced from 1Password, so read it from the vault rather than from any file on the server:

cd tvl-maildown-mcp

MAILDOWN_LOGIN_PASSWORD="$(op read 'op://Maildown/maildown-server/login-password')" \
npm run smoke:remote

Expected output:

remote smoke ok: https://maildown.tvl.tech

Manual Product Tests

  • ChatGPT.com connects to https://maildown.tvl.tech/mcp/athena as athena.
  • Claude.ai connects to https://maildown.tvl.tech/mcp/odysseus as odysseus.
  • Any client connecting to a pinned /mcp/<identity> endpoint gets that identity.
  • Claude Code uses the local channel bridge as odysseus.
  • The dashboard runs at https://maildown.tvl.tech/dashboard.

See the MCP repository manual guide for click-by-click product testing:

tvl-maildown-mcp/docs/manual-testing.md