This tutorial shows how to use the Mau command-line tool for practical peer-to-peer social networking. It handles all the GPG complexity for you.
Time: ~10 minutes
Prerequisites:
1# Clone the repository
2git clone https://github.com/mau-network/mau.git
3cd mau
4
5# Build the CLI
6go build -o mau ./cmd/mau
7
8# Verify it works
9./mau
You should see:
Available commands:
init: Initialize new account in current directory
show: Show current account information
export: Export account public key to file
friend: Add a friend using this public key file
...
Create a new Mau account in the current directory:
1mkdir ~/my-mau
2cd ~/my-mau
3
4# Initialize (you'll be prompted for name, email, passphrase)
5../mau/mau init
Follow the prompts:
Enter your name: Alice
Enter your email: alice@example.com
Enter passphrase: [your-secure-password]
Confirm passphrase: [your-secure-password]
✓ Account created successfully!
Fingerprint: 5D000B2F2C040A1675B49D7F0C7CB7DC36999D56
What just happened?
.mau/ directory structure.mau/account.pgpView your account info:
1../mau/mau show
Output:
Name: Alice
Email: alice@example.com
Fingerprint: 5D000B2F2C040A1675B49D7F0C7CB7DC36999D56
Directory: /home/alice/my-mau
Friends: 0
Follows: 0
Files: 0
Create a JSON file with your post:
1cat > my-first-post.json <<'EOF'
2{
3 "@context": "https://schema.org",
4 "@type": "SocialMediaPosting",
5 "headline": "Hello from Mau CLI!",
6 "articleBody": "Just set up my decentralized social profile.",
7 "datePublished": "2026-02-28T08:00:00Z"
8}
9EOF
Share it with your followers:
1../mau/mau share my-first-post.json
Output:
✓ File shared: my-first-post.json
Size: 234 bytes
Encrypted for: yourself (public post)
Saved to: 5D000B2F.../my-first-post.json.pgp
What happened?
List your shared files:
1../mau/mau files
Output:
📝 Your shared files:
my-first-post.json.pgp
Size: 389 bytes
Modified: 2026-02-28 08:00:15
Let’s simulate adding Bob. First, Bob needs to:
mau init on his machineBob’s side:
1# Bob initializes his account
2cd ~/bob-mau
3../mau/mau init
4# (Name: Bob, Email: bob@example.com, passphrase: ...)
5
6# Bob exports his public key
7../mau/mau export bob-pubkey.pgp
8
9# Bob sends bob-pubkey.pgp to Alice (email, USB, etc.)
Your side (Alice):
1# You receive bob-pubkey.pgp and add Bob as a friend
2../mau/mau friend bob-pubkey.pgp
Output:
✓ Friend added: Bob <bob@example.com>
Fingerprint: ABC123DEF456789ABC123DEF456789ABC123DEF
Verify Bob is in your friends list:
1../mau/mau friends
Output:
👥 Your friends:
Bob <bob@example.com>
Fingerprint: ABC123DEF456789ABC123DEF456789ABC123DEF
Following: No
Following means you want to sync Bob’s posts:
1../mau/mau follow ABC123DEF456789ABC123DEF456789ABC123DEF
Or shorter (Mau matches partial fingerprints):
1../mau/mau follow ABC123
Output:
✓ Now following: Bob <bob@example.com>
Check your follows:
1../mau/mau follows
Output:
👤 You are following:
Bob <bob@example.com>
Fingerprint: ABC123DEF456789ABC123DEF456789ABC123DEF
Last sync: Never
To allow others to sync your posts, run a server:
1../mau/mau serve
Output:
🚀 Mau server starting...
Address: http://192.168.1.100:8080
Fingerprint: 5D000B2F2C040A1675B49D7F0C7CB7DC36999D56
📡 Announcing on local network via mDNS...
Service: 5D000B2F2C040A1675B49D7F0C7CB7DC36999D56._mau._tcp.local
✓ Server running. Press Ctrl+C to stop.
What’s happening?
Test the server (open another terminal):
1# List your files
2curl http://localhost:8080/5D000B2F2C040A1675B49D7F0C7CB7DC36999D56
3
4# Download a specific file
5curl http://localhost:8080/5D000B2F2C040A1675B49D7F0C7CB7DC36999D56/my-first-post.json.pgp \
6 -o downloaded.pgp
7
8# Decrypt it
9gpg --decrypt downloaded.pgp
Assuming Bob is also running mau serve on his machine:
1# Sync from Bob's server
2../mau/mau sync http://bob-machine.local:8080 ABC123
Or if Bob is on the same network, Mau can discover him automatically:
1# Auto-discover via mDNS and sync
2../mau/mau sync ABC123
Output:
🔍 Discovering ABC123... on local network
✓ Found: Bob at http://192.168.1.101:8080
📥 Syncing from Bob...
Checking files modified since: Never
⬇ bob-hello.json.pgp (412 bytes)
⬇ bob-recipe.json.pgp (1.2 KB)
✓ Synced 2 files from Bob
View Bob’s files:
1../mau/mau files ABC123
Output:
📝 Files from Bob <bob@example.com>:
bob-hello.json.pgp
Size: 412 bytes
Modified: 2026-02-28 07:30:00
bob-recipe.json.pgp
Size: 1.2 KB
Modified: 2026-02-28 07:45:00
Open and decrypt a file:
1../mau/mau open ABC123 bob-hello.json.pgp
Output:
1{
2 "@context": "https://schema.org",
3 "@type": "SocialMediaPosting",
4 "headline": "Just joined Mau!",
5 "author": {
6 "@type": "Person",
7 "name": "Bob"
8 },
9 "datePublished": "2026-02-28T07:30:00Z"
10}
11
12✓ Signature verified: Bob <bob@example.com>
Create a private message:
1cat > private-msg.json <<'EOF'
2{
3 "@context": "https://schema.org",
4 "@type": "Message",
5 "text": "Hey Bob, wanna grab coffee this weekend?",
6 "dateSent": "2026-02-28T08:30:00Z"
7}
8EOF
Share it (encrypted only for Bob):
1../mau/mau share private-msg.json --to ABC123
Output:
✓ File shared: private-msg.json
Encrypted for: Bob <bob@example.com>
Only Bob can read this message.
What happened?
When Bob syncs, he’ll see the file and can decrypt it.
Remove a file you shared:
1../mau/mau delete my-first-post.json.pgp
Output:
⚠ Are you sure you want to delete my-first-post.json.pgp? (y/N): y
✓ File deleted: my-first-post.json.pgp
Note: Peers who already synced will keep their copy.
Important: Deletion only removes it from your machine. Peers who already downloaded it will keep their copy (this is P2P - no central control!).
Stop following Bob:
1../mau/mau unfollow ABC123
Output:
✓ Unfollowed: Bob <bob@example.com>
Note: Bob's files remain on your disk.
Remove Bob entirely (deletes his files too):
1../mau/mau unfriend ABC123
Output:
⚠ This will delete Bob's directory and all his files. Continue? (y/N): y
✓ Removed friend: Bob <bob@example.com>
Deleted: ABC123DEF.../
1# Export your private key
2gpg --export-secret-keys --armor YOUR_FPR > my-account-backup.asc
3
4# Store securely (password manager, USB drive, etc.)
1../mau/mau share post1.json post2.json post3.json
1../mau/mau sync
2# Syncs from all followed friends who are discoverable
1# Using nohup
2nohup ../mau/mau serve > mau-server.log 2>&1 &
3
4# Or with systemd (create a service file)
1# Verify signature without decrypting content
2gpg --verify YOUR_FPR/some-file.json.pgp
Mau supports any Schema.org type. Examples:
1{
2 "@context": "https://schema.org",
3 "@type": "Recipe",
4 "name": "Spaghetti Carbonara",
5 "recipeIngredient": ["400g spaghetti", "200g pancetta", "4 eggs"],
6 "recipeInstructions": "Cook pasta. Fry pancetta. Mix eggs. Combine.",
7 "totalTime": "PT30M"
8}
1{
2 "@context": "https://schema.org",
3 "@type": "Event",
4 "name": "Mau Meetup Berlin",
5 "startDate": "2026-03-15T18:00:00+01:00",
6 "location": {
7 "@type": "Place",
8 "name": "C-Base",
9 "address": "Berlin, Germany"
10 }
11}
1{
2 "@context": "https://schema.org",
3 "@type": "Review",
4 "itemReviewed": {
5 "@type": "Restaurant",
6 "name": "Burgermeister"
7 },
8 "reviewRating": {
9 "@type": "Rating",
10 "ratingValue": 5
11 },
12 "reviewBody": "Best burgers in Berlin!"
13}
Just save as JSON and mau share them!
Make sure your GPG agent is running:
1gpg-agent --daemon
mau servemau sync ABC123 (local network only)Use full or partial fingerprint:
1../mau/mau friends # List all friends with fingerprints
2../mau/mau follow <first-8-chars>
✅ Initialize Mau accounts
✅ Share posts and files
✅ Add and follow friends
✅ Run HTTP server for syncing
✅ Sync content from peers
✅ Send private messages
✅ Manage friends and follows
✅ Use Schema.org types for structured content
| Task | Raw GPG | Mau CLI |
|---|---|---|
| Create identity | gpg --full-generate-key + manual export |
mau init |
| Share post | gpg --sign --encrypt ... (long command) |
mau share file.json |
| Add friend | gpg --import + manual file placement |
mau friend key.pgp |
| Sync posts | Manual HTTP requests + decryption | mau sync <fingerprint> |
| Serve files | Set up HTTP server manually | mau serve |
| Private message | gpg --encrypt -r ... (manual recipient) |
mau share --to <fingerprint> |
The CLI handles all complexity for you!
go run ./gui for a graphical interfaceTip: Set an alias for convenience:
1echo 'alias mau="~/mau/mau"' >> ~/.bashrc
2source ~/.bashrc