A ready-to-run OpenClaw agent configuration with a dashboard UI, plugins, and skills for task management and email management. Built on Gmail and Obsidian — no database required. Compatible with OpenClaw v2026.2.19+. See the Changelog for version history.
Originally extracted from Tempo, a personal AI Chief of Staff system built by Ja'dan Johnson, a designer and technologist focused on human-centered AI. This repo packages the core productivity features into a standalone, configurable starting point that anyone can fork, extend, and make their own.
This repo gives you a complete OpenClaw agent setup out of the box:
- 16 registered tools — Task CRUD, email triage, follow-up tracking, board sync, and more via an OpenClaw plugin
- 2 skills —
task-planner(brain dump to structured tasks) andemail-composer(draft replies) - Dashboard UI — React/Vite/Tailwind command center with Kanban board, email overview, and agent chat
- Heartbeat system — Proactive 30-minute checks for deadlines, blocked work, and unanswered emails (with v2026.2.19 heartbeat guard)
- Telegram integration — Mobile notifications for heartbeat alerts
- Vault template — Ready-to-use Obsidian vault structure with Kanban board and task templates
- QMD memory — Queryable Markdown memory backend with hybrid search (BM25 + vectors + reranking)
- Hooks engine — Event-driven automation with bundled
command-loggerandsession-memoryhooks - Model fallbacks — Automatic failover chain (Gemini 2.0 Flash -> Gemini 2.5 Flash -> GPT-4o Mini)
- Compaction memory flush — Automatically saves context before session compaction
Design decisions:
- No database — Gmail labels are your email categories. Obsidian markdown files are your tasks. Zero infrastructure.
- Model fallbacks — Runs on Gemini 2.0 Flash by default with automatic failover. Swap to any OpenClaw-supported model in one config line.
- Meet users where they are — Gmail and Obsidian are tools people already use. The agent organizes things behind the scenes.
- Private — Everything runs on your machine. Your emails and tasks never leave your control.
| Requirement | Version | Check |
|---|---|---|
| Node.js | v22+ | node --version |
| npm | v10+ | npm --version |
| OpenClaw | v2026.2.19+ | openclaw --version |
| Git | any | git --version |
Platform integrations (configure after install):
| Integration | Required? | What it does |
|---|---|---|
| Gmail API (OAuth) | Yes — for email management | Triage, label, draft replies |
| Google API key | Yes — for LLM | Powers the Gemini model |
| Obsidian vault | Yes — for task management | Markdown-based task storage |
| Telegram bot | Optional | Mobile heartbeat notifications |
New to OpenClaw? Install it first:
npm install -g openclaw@latest, then runopenclaw onboardto walk through initial setup. See the OpenClaw getting started guide.
git clone https://github.com/jdanjohnson/Openclaw-AI-Assistant-Project.git
cd Openclaw-AI-Assistant-Project
cp .env.example .envEdit .env with your credentials:
# Gmail OAuth (required for email management)
GMAIL_CLIENT_ID=your-client-id
GMAIL_CLIENT_SECRET=your-client-secret
GMAIL_REFRESH_TOKEN=your-refresh-token
# LLM (required)
GOOGLE_API_KEY=your-google-api-key
# Obsidian Vault (required for task management)
VAULT_PATH=/path/to/your/obsidian/vault
# Telegram (optional — enables mobile notifications)
TELEGRAM_BOT_TOKEN=your-bot-token
TELEGRAM_CHAT_ID=your-chat-idTip: See Gmail OAuth Setup below for step-by-step instructions on getting your Gmail credentials.
Copy the vault template into your Obsidian vault:
cp -r vault-template/* /path/to/your/obsidian/vault/This creates:
Tasks/Board.md— Kanban board (compatible with Obsidian Kanban plugin)Templates/Task.md— Task file template with YAML frontmatterFollow-Ups.md— Follow-up tracking fileProjects/— Project folder
cd agent/plugins/core
npm installExpected output: added 57 packages (no vulnerabilities).
cd agent
openclaw gatewayThe agent starts on port 18789 by default. You should see:
Gateway listening on http://localhost:18789
Note (v2026.2.19): The gateway defaults to
auth.mode: "none"for local use. If you expose the gateway externally through a reverse proxy, thetrustedProxiesconfig ensures WebSocket connections aren't rejected with "device identity required" errors. See the Deployment section.
openclaw doctorThis checks your configuration, model access, plugin loading, and channel connectivity. Fix any warnings before proceeding.
cd dashboard
npm install
npm run devOpen http://localhost:5173 to access the command center.
Once the gateway is running, try these commands via Telegram or the dashboard chat:
- "list my tasks" — verify task management works
- "triage my inbox" — verify email management works
- "what's due today?" — verify heartbeat-style checks work
If all three work, your setup is complete.
To enable email management, you need Gmail API credentials:
- Go to Google Cloud Console
- Create a new project (or select an existing one)
- Enable the Gmail API under APIs & Services > Library
- Go to APIs & Services > Credentials
- Click Create Credentials > OAuth client ID
- Application type: Web application
- Add
http://localhost:3000/callbackas an authorized redirect URI - Copy the Client ID and Client Secret into your
.env
Use the OAuth 2.0 Playground or run a local OAuth flow:
- Go to OAuth Playground
- Click the gear icon, check "Use your own OAuth credentials"
- Enter your Client ID and Client Secret
- In Step 1, select
https://mail.google.com/scope - Authorize and exchange for tokens
- Copy the Refresh Token into your
.env
On first run, the agent automatically creates these labels in your Gmail:
| Label | Purpose |
|---|---|
| To Respond | Emails requiring your reply |
| FYI | Informational, no action needed |
| Comment | Someone commented on a PR, doc, thread |
| Notification | Automated system notifications |
| Meeting Update | Calendar/meeting related |
| Awaiting Reply | You're waiting for someone else |
| Actioned | Already handled |
| Marketing | Promotional, newsletters, cold outreach |
For mobile notifications and heartbeat alerts:
- Message @BotFather on Telegram
- Create a new bot with
/newbot - Copy the bot token into
TELEGRAM_BOT_TOKEN - Start a chat with your bot, then get your chat ID:
https://api.telegram.org/bot<YOUR_TOKEN>/getUpdates - Copy the chat ID into
TELEGRAM_CHAT_ID - Update
agent/openclaw.json— setchannels.telegram.chatIdto your chat ID
├── agent/ # OpenClaw agent configuration
│ ├── openclaw.json # Agent config (model, memory, hooks, heartbeat, Telegram)
│ ├── plugins/core/ # Plugin with 16 registered tools
│ │ ├── index.ts # Tool registration via api.registerTool()
│ │ ├── openclaw.plugin.json # Plugin manifest (required by OpenClaw v2026.2.19+)
│ │ └── package.json # Dependencies (typebox, googleapis, gray-matter)
│ ├── lib/ # Core libraries
│ │ ├── vault-sync.ts # Board.md ↔ task file synchronization
│ │ ├── vault-tasks.ts # Task CRUD (create, list, update, complete, archive, delete)
│ │ ├── gmail-adapter.ts # Gmail API OAuth adapter
│ │ ├── gmail-email.ts # Email triage + categorization tools
│ │ └── follow-up-tracker.ts # Follow-up detection + vault writer
│ └── workspace/ # Agent behavior definitions
│ ├── SOUL.md # Assistant identity and rules
│ ├── HEARTBEAT.md # 5-priority proactive check system
│ └── skills/ # Specialized capabilities
│ ├── task-planner/ # Brain dump → structured tasks
│ └── email-composer/ # Draft email replies
├── dashboard/ # React command center
│ ├── src/
│ │ ├── App.tsx # Main app (3 tabs: Tasks, Email, Chat)
│ │ ├── components/
│ │ │ ├── TaskBoard.tsx # Kanban board with brain dump
│ │ │ ├── EmailSummary.tsx # 8-category email overview
│ │ │ ├── ChatPanel.tsx # Agent chat interface
│ │ │ └── HeartbeatStatus.tsx # Heartbeat indicator
│ │ └── lib/
│ │ ├── agent-api.ts # WebSocket agent communication
│ │ └── types.ts # Shared TypeScript types
│ ├── package.json
│ └── vite.config.ts
├── vault-template/ # Example Obsidian vault structure
│ ├── Tasks/Board.md # Kanban board
│ ├── Templates/Task.md # Task template with frontmatter
│ ├── Follow-Ups.md # Follow-up tracking
│ └── Projects/ # Project folder
├── .env.example # Required environment variables template
└── README.md
Tasks live as markdown files in your Obsidian vault with YAML frontmatter:
---
status: working
assignee: me
priority: high
project: product-launch
due_date: 2026-02-20
created_at: 2026-02-15T10:00:00Z
tags: [urgent, design]
---
Review the landing page mockups and provide feedback to the design team.The agent keeps Tasks/Board.md (Obsidian Kanban plugin format) in sync with individual task files. Edit either one — the sync engine reconciles them.
Task statuses: backlog → next → working → done (with blocked and archived)
Tools available:
create_task— Create a new tasklist_tasks— List/filter tasksupdate_task— Modify any fieldcomplete_task— Mark as donearchive_task— Move to Archive/delete_task— Permanently removesync_board— Force Board.md ↔ file synclist_projects/create_project— Project management
The agent categorizes your unread emails and applies Gmail labels directly — your inbox becomes organized without copying emails into a database.
Flow:
- You say "triage my inbox" (or heartbeat triggers it)
- Agent fetches unread emails via Gmail API
- LLM categorizes each email into one of 8 categories
- Gmail labels are applied automatically
- For "To Respond" emails, the agent can draft replies (saved as Gmail drafts, never auto-sent)
Tools available:
run_email_triage— Categorize and label unread emailslist_emails— Search Gmailread_email— Read full email contentsend_email/create_draft— Create drafts in Gmail
Combines Gmail labels with an Obsidian file:
- Scans "To Respond" and "Awaiting Reply" labels in Gmail
- Writes a human-readable
Follow-Ups.mdin your vault - Flags overdue items (1 day for needs-reply, 3 days for awaiting-reply)
Every 30 minutes (configurable), the agent runs 5 priority checks:
- Approaching deadlines — Tasks due within 24 hours
- Blocked tasks — Tasks stuck in
blockedstatus - Overdue follow-ups — Emails waiting too long for replies
- WIP overflow — More than 5 tasks in
workingstatus - Unread To-Respond — Emails labeled "To Respond" still unread
Results are sent via Telegram (if configured) as a single consolidated message.
Edit agent/openclaw.json:
{
"agents": {
"defaults": {
"model": {
"primary": "google/gemini-2.0-flash",
"fallbacks": [
"google/gemini-2.5-flash",
"openai/gpt-4o-mini"
]
}
}
}
}Replace primary with any model supported by OpenClaw (OpenAI, Anthropic, Mistral, etc.). The fallbacks array provides automatic failover if the primary model is unavailable.
In agent/openclaw.json:
{
"heartbeat": {
"every": "30m",
"activeHours": {
"start": "08:00",
"end": "23:00",
"timezone": "America/New_York"
}
}
}The agent uses Queryable Markdown (QMD) as its memory backend, enabling hybrid search across workspace markdown files:
{
"memory": {
"backend": "qmd",
"qmd": {
"limits": { "maxResults": 6, "timeoutMs": 4000 },
"sessions": { "enabled": true, "retentionDays": 30 }
}
}
}Memory files in workspace/memory/ are automatically indexed and searchable.
Two bundled hooks are enabled by default:
| Hook | Purpose |
|---|---|
command-logger |
Logs all tool usage for debugging |
session-memory |
Persists important context before session compaction |
Add custom hooks by creating directories in workspace/hooks/ with a HOOK.md frontmatter file and optional handler.js.
When a session approaches the token limit, the agent automatically saves important context before compaction:
{
"agents": {
"defaults": {
"compaction": {
"memoryFlush": {
"enabled": true,
"softThresholdTokens": 4000
}
}
}
}
}Create dashboard/.env:
VITE_GATEWAY_URL=ws://localhost:18789The installation guide above runs everything locally. This is the simplest and most private setup.
For always-on heartbeats and Telegram notifications:
- Provision a server — Any Linux VPS with Node.js 22+
- Clone the repo and configure
.env - Sync your vault — Use Obsidian Sync, Syncthing, or rsync to keep your vault accessible on the server
- Run as a service:
sudo tee /etc/systemd/system/openclaw-agent.service << 'EOF'
[Unit]
Description=OpenClaw Productivity Agent
After=network.target
[Service]
Type=simple
User=ubuntu
WorkingDirectory=/home/ubuntu/Openclaw-AI-Assistant-Project/agent
ExecStart=/usr/local/bin/openclaw gateway
Restart=always
EnvironmentFile=/home/ubuntu/Openclaw-AI-Assistant-Project/.env
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl enable openclaw-agent
sudo systemctl start openclaw-agent- Dashboard (optional) — Build and serve statically:
cd dashboard
npm run build
# Serve dist/ with Caddy, nginx, or any static hostIf exposing the gateway externally (e.g., for the dashboard on a different machine):
# Caddyfile example
agent.yourdomain.com {
reverse_proxy 127.0.0.1:18789
}
Important (v2026.2.19): Use
127.0.0.1:18789(notlocalhost:18789) in your reverse proxy config to avoid IPv6 connection issues. The gateway binds to IPv4 only, butlocalhostmay resolve to[::1](IPv6) first.The
gateway.trustedProxiesconfig inopenclaw.jsonis set to["127.0.0.1", "::1"]by default. This ensures WebSocket connections through a local reverse proxy aren't rejected with "device identity required" errors.If your reverse proxy runs on a different machine, add its IP to
trustedProxies.
Contributions are welcome. Here's how to get involved.
- Fork the repo and clone your fork
- Set up your environment — follow the Installation guide above
- Create a branch for your feature or fix:
git checkout -b feature/your-feature-name
- Make your changes — keep commits focused and descriptive
- Test locally — make sure the agent starts and the dashboard builds:
cd dashboard && npm run build cd agent && openclaw gateway
- Open a pull request against
mainwith a clear description of what you changed and why
New adapters:
- IMAP/SMTP adapter for non-Gmail email providers
- Microsoft Outlook adapter (Graph API)
- CalDAV adapter for calendar integration
New skills:
- Meeting briefer — cross-reference calendar with tasks and contacts
- Research assistant — web search + summarization
- Weekly review generator — automated retrospectives
Dashboard improvements:
- File-watcher daemon for real-time vault change detection (currently agent-polled)
- Task detail drawer with inline editing
- Email thread viewer
- Dark/light theme toggle
Infrastructure:
- Multi-user authentication layer
- Docker Compose setup for one-command deployment
- Mobile companion app (React Native)
- Webhook integrations (GitHub, Linear, Slack)
- TypeScript for all agent code and dashboard
- All plugin tools must return
jsonResult()format - Email content must be wrapped in
<untrusted_email_data>tags before LLM processing - No hardcoded API keys, email addresses, or personal references
- Prefer editing existing files over creating new ones
Open a GitHub issue with:
- Steps to reproduce
- Expected vs actual behavior
- Your environment (Node version, OS, OpenClaw version — should be v2026.2.19+)
Common issues and their solutions. Run openclaw doctor first — it catches most configuration problems automatically.
| Symptom | Cause | Fix |
|---|---|---|
gateway.auth.mode is required |
OpenClaw < v2026.2.19 | Upgrade: npm install -g openclaw@latest |
device identity required on WebSocket |
Missing trustedProxies behind reverse proxy |
Add your proxy IP to gateway.trustedProxies in openclaw.json |
Cannot find module '@sinclair/typebox' |
Plugin dependencies not installed | Run cd agent/plugins/core && npm install |
| Dashboard shows "Disconnected" | Gateway not running | Start the gateway: cd agent && openclaw gateway |
GOOGLE_API_KEY is not set |
Missing .env file |
Copy .env.example to .env and fill in your credentials |
| Heartbeat not firing | Outside active hours or HEARTBEAT.md empty |
Check activeHours in openclaw.json and ensure HEARTBEAT.md has content |
| Gmail labels not created | OAuth credentials invalid | Re-run the Gmail OAuth Setup steps |
model not found error |
Model string doesn't match OpenClaw format | Use provider-prefixed format: google/gemini-2.0-flash, openai/gpt-4o-mini |
| Fallback models not triggering | API key valid but model overloaded | Fallbacks only trigger on errors, not on slow responses. Check openclaw doctor for model status |
| Plugin tools not registering | Missing openclaw.plugin.json manifest |
Ensure agent/plugins/core/openclaw.plugin.json exists (required by v2026.2.19+) |
For issues not listed here, open a GitHub issue or check the OpenClaw troubleshooting docs.
This project started as Tempo, a personal AI Chief of Staff built by Ja'dan Johnson. Ja'dan is a designer and technologist who works at the intersection of human-centered design and AI — exploring how intelligent systems can reduce the cognitive overhead between what you intend to do and what your tools actually help you accomplish.
This repo extracts the task and email management pieces into a generic, configurable starting point built on OpenClaw. The goal is to give others a foundation to build their own AI productivity workflows — adapt the skills, swap the model, extend the tools, and make it yours.
This repo tracks the latest stable OpenClaw release. Key features from v2026.2.19:
- QMD memory backend — Hybrid search (BM25 + vectors + reranking) over workspace markdown files
- Hooks engine — Event-driven automation (
command-logger,session-memory, custom hooks) - Plugin manifests —
openclaw.plugin.jsonfor structured plugin discovery - Model fallbacks — Automatic failover chain across providers
- Gateway auth hardening — Explicit
auth.mode: "none"for loopback setups (prevents token auth breaking connections) - Heartbeat guard — Skips interval heartbeats when
HEARTBEAT.mdis missing/empty - Compaction memory flush — Saves important context before session compaction
- Trusted proxies —
gateway.trustedProxiesfor reverse proxy setups (fixes "device identity required" errors)
MIT


