Anxiety-reduction system for financial communications
Personal-Claw sits between you and financial email sources (accountant, bank, tax office), providing neutral defused summaries via Discord, and enforces mandatory human-in-the-loop approval for all replies. The goal is to break the catastrophizing → avoidance → anxiety cycle by removing emotional charge from financial communications.
Repository: https://github.com/JMacLulich/personal-claw
- Monitor Gmail inbox for emails from allowlisted financial contacts
- Send neutral, defused summaries to Discord using supportive/coaching tone
- Accept input from single allowlisted Discord user ID only (security)
- Support both text and voice input (voice transcribed to text)
- Show draft replies in Discord for review/editing before sending
- Require explicit two-step approval ("send this" → confirm) before actually sending
- Never auto-send under any circumstances
# Create virtual environment
python3 -m venv .venv
source .venv/bin/activate
# Install dependencies
pip install -r requirements.txt# Copy environment template
cp .env.example .env
# Edit .env and fill in required values1. Discord Bot Token (One-time setup)
- Go to https://discord.com/developers/applications
- Create new application (or use existing one)
- Go to Bot section
- Copy token
- Add to
.envasDISCORD_BOT_TOKEN
2. Your Discord User ID (Allowlist)
- In Discord, go to User Settings → Advanced
- Enable Developer Mode
- Right-click your username → Copy ID
- Add to
.envasDISCORD_ALLOWLISTED_USER_ID
3. Gmail OAuth Credentials (Fully automatic after first run)
- Go to https://console.cloud.google.com/apis/credentials
- Create a new project (or use existing one)
- Enable Gmail API (APIs & Services → Enable APIs)
- Create OAuth 2.0 credentials (Desktop app type)
- Download as
credentials.json→ save to project root - The bot will automatically create
token.jsonon first run
- Copy
.env.exampleto.envand set Gmail paths if you want non-default locations - Download
credentials.jsonfrom Google Cloud and place it in the project root - Run
./scripts/bootstrap.shto createtoken.json - To reset Gmail auth, delete
token.jsonand run the script again
Note: OpenClaw will also prompt for tokens if they are missing. Discord tokens are only required when you run the bot.
source .venv/bin/activate
python src/bot.pyFirst run opens your MacBook's browser for OAuth flow. The bot creates token.json automatically.
OpenClaw: This project uses OpenClaw CLI to run the bot. You'll start Personal-Claw by running:
openclawProject Structure:
personal-claw/
├── src/
│ ├── __init__.py
│ ├── config.py # Configuration management
│ ├── bot.py # Discord bot
│ ├── auth.py # User allowlist enforcement
│ ├── gmail_client.py # Gmail API client
│ ├── token_manager.py # OAuth token management
│ └── main.py # (Coming soon)
├── .env # Your secrets (gitignored)
├── .env.example # Environment variable template
├── requirements.txt # Python dependencies
└── README.md # This file
Key Dependencies:
- py-cord (2.6+) — Discord bot framework
- google-api-python-client — Gmail API integration
- google-auth-oauthlib — OAuth for Gmail
- google-auth-httplib2 — HTTP transport for Gmail
- python-dotenv — Environment variable management
All secrets are excluded from git via .gitignore (.env, token.json, credentials.json).
- Security: Bot only responds to allowlisted user ID — rejects all other users
- Privacy: Financial emails never logged or stored beyond operational needs
- Safety: NO auto-send under any circumstances — explicit approval required
- Interface: Discord only — no web UI, no email client
- Voice: Supports voice input as first-class (for checking while driving/walking)
- Tone: Supportive/coaching (not clinical, not patronizing)
How to run OpenClaw safely on your N100 (headless system):
Run OpenClaw in a rootless container (not a root Docker daemon):
--cap-drop=ALL— Drop all Linux capabilities--security-opt=no-new-privileges— No privilege escalation--read-only— Container filesystem is read-only (no writes except OpenClaw data volume)--cap-drop ALL— Drop all capabilities (no sudo, no raw socket access)
- No inbound ports exposed — OpenClaw connects outbound only (Discord, Gmail APIs)
- Outbound allow only: DNS (53) + HTTPS (443) for Gmail + Discord APIs
- Keep tokens/API keys in chmod 600 env file owned by a non-root user
- Never bake secrets into images or shell history
- Mail: start with read + draft only, no auto-send
- OpenClaw: disable marketplace/community skills; disable any tools that run shell commands or browse filesystem
- Discord DM-only (or one private channel) + allowlist your Discord user ID
- Free-text is fine, but sending email must require explicit confirmation every time
- Auditability: Keep logs, keep a small state DB, record every "draft created" and "sent" action (with timestamps and thread IDs)
--memory=512m— Limit memory to reduce attack surface--pids-limit=256— Process limit reduces DoS risk- No host mounts (except a single named volume for OpenClaw's own data)
- Tight network filtering (only outbound required ports)
- Host firewall: deny inbound by default, allow SSH (especially via Tailscale) first, then lock it down
- Prefer pinnning SSH allow rules to Tailscale interface (tailscale0) where possible
- After lockdown: disable inbound SSH except Tailscale interface
- Outbound allow only: DNS (53) + HTTPS (443) for Gmail + Discord APIs
If N100 is compromised:
- Containment: Rootless container, no host filesystem access, tight network rules
- Data Isolation: OpenClaw data in dedicated volume, not on host
- Least Privileges: No sudo, no raw sockets, no capability escalation
- Audit Trail: All "draft created" and "sent" actions logged
- No Inbound Services: OpenClaw connects outbound only
If an attacker gets code access:
- They still can't: Read-only filesystem, no tools inside container
- They're limited to: OpenClaw APIs only (Gmail read + Discord outbound), no shell access to host
What this protects against:
- Code execution on N100 (container doesn't have tools)
- Escalation beyond container (no sudo, no raw sockets)
- Access to your host system (no host mounts, outbound-only network rules)
What you're still responsible for:
- Your N100 host system (host firewall, SSH access)
- Keeping N100 software updated and patched
- Monitoring logs and unusual activity
Before running openclaw on N100:
- N100 host firewall configured (allow outbound, SSH locked down)
- SSH allow rules pinned to Tailscale interface (tailscale0) where possible
- No unnecessary ports open on N100 host
- Secrets in env file have correct permissions (chmod 600)
- OpenClaw marketplace skills disabled (no shell access to host filesystem)
- Secrets in env file owned by non-root user (check:
stat -c %u %g ~/.env) - Rootless container configured with tight security options
This setup creates a hardened sandbox for OpenClaw. Even if the container is compromised, attacker options are extremely limited.