https://github.com/kingmadellc/rout
Personal AI assistant native to iMessage. Text it like a friend — it texts back with Claude.
https://github.com/kingmadellc/rout
ai-assistant anthropic claude imessage macos personal-ai python
Last synced: 4 months ago
JSON representation
Personal AI assistant native to iMessage. Text it like a friend — it texts back with Claude.
- Host: GitHub
- URL: https://github.com/kingmadellc/rout
- Owner: kingmadellc
- License: mit
- Created: 2026-02-21T07:07:56.000Z (5 months ago)
- Default Branch: main
- Last Pushed: 2026-02-21T22:54:33.000Z (5 months ago)
- Last Synced: 2026-02-21T23:25:59.533Z (5 months ago)
- Topics: ai-assistant, anthropic, claude, imessage, macos, personal-ai, python
- Language: Python
- Homepage:
- Size: 43.9 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Rout — Personal AI Agent for macOS
Every AI assistant makes you leave what you're doing. Open a browser. Switch apps. Lose your train of thought. Rout lives in iMessage — the app you already have open. Text it. Get answers. Stay in flow.
Built on [OpenClaw](https://openclaw.ai). Runs as a launchd service on macOS.
**[→ View the project page](https://kingmadellc.github.io/rout/)**
---
### What's New in v1.4
- **Three-tier safety gate** — SAFE (execute immediately) → CONFIRM (execute + audit log) → DESTRUCTIVE (block, require explicit confirmation). All actions classified and logged.
- **Provider-agnostic web search** — DuckDuckGo, Brave, or SearXNG. Auto-failover between providers. No API key required for DDG.
- **Event-driven proactive triggers** — portfolio drift alerts, calendar conflict detection, and configurable threshold-based notifications. Beyond simple cron.
- **Vector memory keyword fallback** — ChromaDB vector search with automatic keyword fallback when embeddings miss. More reliable context retrieval.
- **Slim tool descriptions** — reduced tool definition token overhead for faster, cheaper Claude calls.
### v1.3
- **Kalshi trading integration** — portfolio, positions, markets, research cache via iMessage commands. Buy/sell with risk limits, trade audit log, exit monitoring with webhook alerts.
- **Webhook server v2** — hot-reload (`kill -HUP` or `/admin/reload`), retry with exponential backoff, in-memory history ring buffer, runtime trigger registration via API, admin endpoints (`/admin/triggers`, `/admin/history`, `/admin/stats`), `rout-webhook` CLI tool.
### v1.2
- **Event-driven webhook triggers** — any service can POST to `localhost:7888` and Rout sends you an iMessage. Config-driven templates, rate-limited, authenticated.
- **Push transport hardened** — BlueBubbles Socket.IO under launchd with proof-of-life guard.
- **Group chat fix** — responses correctly route back to originating group chat.
---
## Why Rout
- **One interface** — text it like you'd text a friend. Calendar, reminders, web search, memory, image analysis — all through natural conversation.
- **Multi-turn reasoning** — Claude doesn't just answer questions. It reasons, calls tools, observes results, and responds. Ask it to check your schedule and create an event in the same conversation.
- **Safety gate** — destructive actions (calendar writes, reminder creation) require your explicit confirmation before executing. Nothing happens behind your back.
- **Provider failover** — auto-switches Anthropic → Codex → local Ollama if a provider is rate-limited. Zero downtime.
- **Persistent memory** — Rout remembers context about you across conversations. Vector-retrieved via ChromaDB, with graceful MEMORY.md fallback.
- **Crash-proof** — launchd auto-restarts the watcher. If it goes down, it texts you.
## What It Looks Like
Everything happens in Messages.app — conversations, confirmations, and background tasks:
```
You: What's on my calendar today?
Rout: You've got 3 things today:
• Team standup @ 9:30 AM [Work]
• Dentist appointment @ 1:00 PM [Personal]
• Pick up groceries @ 5:30 PM [Reminders]
You: Move the dentist to Thursday at 2pm
Rout: Create event on Personal calendar?
📅 Dentist appointment
🕐 Thursday at 2:00 PM (1 hour)
Reply yes or no.
You: Yes
Rout: ✅ Done. Event created: Dentist appointment
You: spawn: research the latest AI policy news and summarize the key points
Rout: ✅ Subagent spawned!
Task: research the latest AI policy news...
You'll get an iMessage when it's done. (Timeout: 10 min)
*(5 minutes later)*
Rout: ✅ Task complete: EU AI Act enforcement begins Q3 2026.
US executive order expands compute reporting thresholds.
China releases new generative AI licensing framework.
```
No app to open. No browser tab. Spawn a task, keep texting — Rout handles it in the background and texts you when done.
## Capabilities
| Capability | What It Does |
|---|---|
| **Natural conversation** | Multi-turn agent loop with tool use, conversation history, and memory context |
| **Calendar** | Read today's events, read a date range, or create new events via AppleScript |
| **Reminders** | Read incomplete reminders or create new ones with optional deadlines |
| **Timed alerts** | "Remind me in 20 minutes" — sends you an iMessage when time's up |
| **Web search** | Provider-agnostic search (DuckDuckGo, Brave, SearXNG) for news, scores, weather, current events |
| **Image analysis** | Send a photo, get a description and analysis |
| **Memory** | Query, add, or clear persistent context (vector store + markdown backup) |
| **Proactive messages** | Morning briefing and meeting reminders via cron (opt-in) |
| **Kalshi trading** | Portfolio, positions, markets, buy/sell with risk limits and trade audit |
| **Webhook triggers** | HTTP endpoint for event-driven alerts — hot-reload, retry, admin API, CLI tool |
| **Subagents** | Spawn background tasks via `spawn:` — get an iMessage when the work is done |
| **Real-time push** | BlueBubbles Socket.IO integration for sub-50ms message delivery (polling fallback) |
| **Provider failover** | Anthropic → Codex → Ollama with persistent cooldown tracking |
## Quick Start
### Requirements
- Mac running macOS 12+ (always-on recommended)
- [OpenClaw](https://openclaw.ai) installed (`npm install -g openclaw`)
- Python 3.10+
- [imsg CLI](https://github.com/nicholasstephan/imsg) (`brew install imsg`)
- Claude Pro/API **or** Codex Pro+ account
- *(Optional)* [Ollama](https://ollama.com) for local LLM fallback and vector embeddings
- *(Optional)* [BlueBubbles](https://bluebubbles.app/) for real-time push transport (Socket.IO)
- *(Optional)* [ChromaDB](https://www.trychroma.com/) for vector memory (`pip install chromadb`)
### Install
```bash
git clone https://github.com/kingmadellc/rout.git
cd rout
chmod +x setup.sh && ./setup.sh
```
> **Note:** macOS will ask you to grant Full Disk Access to Terminal (or your terminal app) so that Rout can read your iMessage database. Go to **System Settings → Privacy & Security → Full Disk Access** and add your terminal. This is required for the watcher to function.
### Configure
1. Copy `config.yaml.example` to `config.yaml` — add your chat IDs and name
2. Copy `MEMORY.md.example` to `MEMORY.md` — give your agent context about you
3. *(Optional)* Copy `CLAUDE.md.example` to `CLAUDE.md` — project context for Claude Code / Cowork sessions
4. Run `imsg list --json` to find your chat ID
5. Start: `./start_watcher.sh`
6. Test: text yourself `ping` — you should get back `🏓 Pong!`
7. Run `doctor` to verify everything is connected
### Update
```bash
git pull
```
Your `config.yaml` and `MEMORY.md` are gitignored — updates are code-only.
## Commands
Text these to yourself via iMessage:
| Command | Description |
|---|---|
| `ping` | Test connectivity — should return 🏓 Pong! |
| `help` | List all commands |
| `status` | Check watcher status, config, and logs |
| `doctor` | Run installation diagnostics |
| `memory: view` | Show persistent memory |
| `memory: add ` | Append to memory |
| `memory: clear CONFIRM` | Reset memory |
| `spawn: ` | Spawn a background subagent — texts you when done |
| `subagent: ` | Alternate trigger for spawn |
| `subagents` | List active and recent subagents |
| `portfolio` | Show Kalshi portfolio: cash, positions, P&L |
| `positions` | Show open Kalshi positions with P&L |
| `markets` | List top opportunities from research cache |
| `cache` | Show Kalshi research cache status |
| *(anything else)* | Routed to Claude — natural conversation with tool use |
## Architecture
```
┌── BlueBubbles push (Socket.IO, sub-50ms)
│
iMessage ──────────┤
│
└── imsg CLI polling (fallback, 2s interval)
│
▼
imsg_watcher.py → command dispatch
│
┌───────────────┤───────────────┐
│ │ │
Structured Free-form spawn:
commands text subagent:
│ │ │
│ ▼ ▼
│ agent_loop.py subagent_handlers.py
│ │ │
│ ┌─────┼─────┐ openclaw sessions:spawn
│ │ │ │ (isolated, 10 min timeout,
│ Claude Tool Safety iMessage on completion)
│ API Use Gate
│ │
│ ┌────┼────┐
│ │ │ │
│ calendar reminders memory
│ read/write create query/add
│
┌────┼────┐
│ │ │
help status memory:view
ping doctor memory:add
Webhook Triggers (event-driven, independent of watcher)
External service ──POST──▶ webhook_server.py (:7888)
│
┌──────────┤──────────┐
│ │ │
/webhook /webhook/ /health
(generic)
│ │
▼ ▼
Send via BB REST API → osascript → imsg CLI
```
The watcher is handler-agnostic. All intelligence lives in `agent/`. The core loop never changes — you only add capabilities.
## File Structure
```
agent/
agent_loop.py Multi-turn tool-use loop (the brain)
safety_gate.py Confirmation flow for destructive actions
tool_registry.py Tool definitions, schemas, dispatch
providers.py Provider failover engine
tools/
calendar_tools.py Calendar.app read/write via AppleScript
reminder_tools.py Reminders.app via AppleScript
memory_tools.py Memory query/add (vector + MEMORY.md)
search_tools.py Provider-agnostic web search (DDG, Brave, SearXNG)
comms/
imsg_watcher.py Hybrid transport — push + polling fallback
bb_push.py BlueBubbles Socket.IO real-time transport
webhook_server.py HTTP webhook endpoint for event-driven triggers
handlers/
general_handlers.py Thin wrapper routing to agent_loop
core_handlers.py help, status, ping, doctor
memory_handlers.py Memory view, add, clear commands
subagent_handlers.py spawn: and subagent: — background task delegation
kalshi_handlers.py Portfolio, positions, markets, buy/sell with risk limits
memory/
vector_store.py ChromaDB + Ollama embeddings
memory_migrator.py One-time MEMORY.md → vector migration
scripts/
proactive_agent.py Cron-driven morning briefing + meeting reminders
config/
*.py Config loading and validation
docs/
SUBAGENT_USAGE.md Subagent spawning guide
PLUGIN_SDK.md Plugin/handler development guide
BUILD_YOUR_FIRST_HANDLER.md Step-by-step handler tutorial
tests/
test_*.py Unit tests (pytest)
imsg_commands.yaml Command registry — maps triggers to handlers
config.yaml.example Config template (copy → config.yaml)
MEMORY.md.example Memory template (copy → MEMORY.md)
CLAUDE.md.example Project context template (copy → CLAUDE.md)
setup.sh One-time setup
start_watcher.sh Start via launchd
stop_watcher.sh Stop watcher
```
## Development
```bash
# Run tests
python -m pytest tests/ -v
# Compile check
python3 -m py_compile comms/imsg_watcher.py handlers/*.py agent/*.py agent/tools/*.py
```
## Build Your Own Tool
Every capability is a tool in the registry. Adding one takes 3 steps:
**1. Create a tool module**
```python
# agent/tools/weather_tools.py
def get_forecast(city: str = "San Francisco") -> str:
"""Get weather forecast for a city."""
# Your logic here
return f"Weather for {city}: 72°F, sunny"
```
**2. Register it in `agent/tool_registry.py`**
```python
"get_forecast": {
"description": "Get weather forecast for a city",
"input_schema": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "City name"},
},
},
"executor": lambda **kwargs: weather_tools.get_forecast(
city=kwargs.get("city", "San Francisco")),
"safety": SAFE,
},
```
**3. Restart**
```bash
./stop_watcher.sh && ./start_watcher.sh
```
Claude now knows about your tool and will call it when relevant.
## Privacy
Rout runs entirely on your Mac. Your messages, calendar data, and memory stay on your machine. The only external calls are to your configured AI provider (Anthropic, Codex, or Ollama) for generating responses. No telemetry, no analytics, no third-party services.
## Contributing
See [CONTRIBUTING.md](CONTRIBUTING.md), [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md), and [SECURITY.md](SECURITY.md).
## License
MIT. See [LICENSE](LICENSE).
---
Built by KingMade LLC · Powered by OpenClaw