A locally-orchestrated personal AI agent for your household. Talks to your family via Telegram (and other channels), controls your smart home via Homey, remembers preferences over time, and handles everyday personal assistant tasks.
Runs 24/7 in Docker on a Mac or Linux machine. Uses cloud LLMs (Claude, GPT-4o) for reasoning — conversations are sent to Anthropic/OpenAI APIs. All stored data (conversation history, memories, device state) stays local on your machine.
Developed by Claude, with assistance from me and Codex.
- Chat naturally — talk to it like any LLM, through Telegram
- Control your home — "turn off the living room lights", "set the thermostat to 21 degrees"
- Remember your family — learns preferences, routines, and context over time
- Household world model — maintains structured knowledge about members, places, devices, routines, and facts
- Multi-step tasks — plans, tracks, and resumes work across multiple conversation turns
- Cross-user features — ask it to remind a family member about something
- Personal assistant — find restaurants, answer questions, set reminders
- Event-driven — reacts to home events, runs scheduled tasks
- Domain skills — file-based skills extend the agent with specialised APIs and data sources (Norwegian weather, road traffic) without modifying code
See docs/architecture.md for the full design.
[Telegram] [WhatsApp*] [Events] [Cron]
└──────────┬────────────┘
[FastAPI Server]
│
[Agent Orchestrator]
(Pydantic AI)
│
┌──────────┼──────────┐
[Claude] [GPT-4o] [Tools]
│
┌──────┴──────┐
[Homey MCP] [Web / Other]
*Future channel
- Docker and Docker Compose
- Anthropic API key
- OpenAI API key
- Telegram Bot token (from @BotFather)
- Homey Personal Access Token
git clone <repo-url> homeAgent
cd homeAgent
cp .env.example .env
# Edit .env with your API keys and tokensdocker compose builddocker compose up -dcurl -X POST "https://api.telegram.org/bot<YOUR_TOKEN>/setWebhook" \
-H "Content-Type: application/json" \
-d '{"url": "https://your-domain.com/webhook/telegram", "secret_token": "<YOUR_WEBHOOK_SECRET>"}'See docs/integrations/telegram.md for full setup including exposing your local server.
All configuration is via .env. See .env.example for all available options with descriptions.
Key settings:
| Variable | Description |
|---|---|
ANTHROPIC_API_KEY |
Claude API key (primary LLM) |
OPENAI_API_KEY |
OpenAI key (fallback + embeddings) |
TELEGRAM_BOT_TOKEN |
From @BotFather |
TELEGRAM_WEBHOOK_URL |
Public HTTPS URL for your server |
HOMEY_TOKEN |
Homey Personal Access Token |
HOMEY_HOME_ID |
Your Homey home ID |
ALLOWED_TELEGRAM_IDS |
Comma-separated list of permitted Telegram user IDs |
ADMIN_TELEGRAM_IDS |
Subset of above with admin privileges |
APP_ENV |
development or production |
Critical rules — read before pushing to any git remote:
.envis gitignored. Never remove it from.gitignore. Never commit it..env.exampleis committed and must contain only placeholder values (sk-ant-...,123456789, etc.). Never put real credentials in it. This is just a template, helpful samples to get goingdata/is gitignored. It contains conversation history and personal memories.uv.lockshould be committed — it ensures reproducible builds.
Verify nothing sensitive is staged before every commit:
git diff --cached # review everything stagedScan for accidentally committed secrets:
# Install gitleaks: https://github.com/gitleaks/gitleaks
gitleaks detect --config .gitleaks.tomlIf you accidentally commit a secret:
- Rotate the credential immediately (don't wait)
- Remove it from git history:
git filter-repoor BFG Repo Cleaner - Force-push to overwrite remote history
- Assume the secret is compromised regardless
Access is controlled by ALLOWED_TELEGRAM_IDS in .env. Only listed Telegram user IDs can interact with the bot — all others are silently ignored.
To find a Telegram user ID: message @userinfobot on Telegram.
User commands:
/help— list available commands/contextstats— show context size breakdown for the next LLM call/history [n]— show recent conversation history (default 10 messages)/schedule— list active reminders and scheduled Homey actions
Admin commands:
/status— operational status (scheduler, Homey MCP, Prometheus MCP)/users— list household members with admin flags
HomeAgent can receive events pushed from Homey Advanced Flows and react to them autonomously — for example, alerting when motion is detected after midnight, or notifying when a door is left open.
Add to .env:
HOMEY_WEBHOOK_SECRET=<generate with: python -c "import secrets; print(secrets.token_hex(32))">Rules can be created three ways:
Via the admin dashboard — open the Control Loop tab at http://<host>:9090/admin, click + New Rule, fill in the form, and save. A Test button fires a synthetic event through the real dispatcher so you can verify rule behaviour without waiting for a live Homey event.
Via the agent — ask the agent directly: "Create an event rule that alerts me when the front door opens after 22:00." The agent has create_event_rule, list_event_rules, enable_event_rule, disable_event_rule, and delete_event_rule tools.
Via the admin API — POST /admin/event-rules with a JSON body:
{
"name": "Motion alert after 22:00",
"source": "homey",
"event_type": "device_state_change",
"entity_id": "<homey-device-uuid>",
"capability": "alarm_motion",
"value_filter_json": "{\"eq\": true}",
"condition_json": "{\"quiet_hours_start\": \"07:00\", \"quiet_hours_end\": \"22:00\"}",
"cooldown_minutes": 10,
"prompt_template": "Motion detected in {zone} at {time}. Is anyone expected home?"
}Fields:
| Field | Description |
|---|---|
event_type |
device_state_change or flow_trigger |
entity_id |
Homey device UUID, or * for any device |
capability |
Capability name to match (e.g. alarm_motion), or omit for any |
value_filter_json |
Optional: {"eq": true}, {"gt": 22.5}, {"ne": null} |
condition_json |
Optional: {"quiet_hours_start": "HH:MM", "quiet_hours_end": "HH:MM"} |
cooldown_minutes |
Minimum minutes between agent triggers for this rule (default 5) |
prompt_template |
Sent to the agent; supports {entity_name}, {capability}, {value}, {zone}, {time} |
- Add a trigger card for the device/capability you want to react to
- Add an action card: HTTP request → POST
- URL:
http://<homeagent-lan-ip>:8080/webhook/homey/event - Header:
X-Homey-Secret: <your-secret> - Body (JSON):
{
"event_type": "device_state_change",
"entity_id": "{{device.id}}",
"entity_name": "{{device.name}}",
"capability": "alarm_motion",
"value": true,
"zone": "{{device.zone.name}}"
}Use Homey's flow variables ({{device.id}} etc.) to populate the fields dynamically.
When a POST arrives:
- Homey secret is validated
household_idis resolved server-side (single-household)- The event is enqueued on the internal event bus
- The dispatcher checks matching
EventRulerecords - If a rule matches and passes cooldown/quiet-hours/value-filter checks, the agent is called with a structured prompt envelope
- The agent decides what action to take and sends a message to the configured channel
To inspect rules: GET /admin/event-rules (requires admin token).
# Install uv
curl -LsSf https://astral.sh/uv/install.sh | sh
# Install dependencies
uv sync
# Run in dev mode (uses polling instead of webhook)
APP_ENV=development uv run python -m apphomeAgent/
├── app/ # Application source
│ ├── agent/ # Pydantic AI agent, tools, context assembly
│ ├── channels/ # Channel adapters (Telegram, future WhatsApp)
│ ├── control/ # Admin dashboard, SSE events, auth
│ ├── memory/ # Memory layers: profiles, episodic, vector
│ ├── models/ # SQLModel database models
│ ├── scheduler/ # APScheduler jobs and cron tasks
│ ├── skills/ # File-based domain skills (weather, traffic, …)
│ ├── tasks/ # Multi-step task orchestration
│ ├── world/ # Household world model
│ ├── api/ # FastAPI routes and webhook handlers
│ └── homey/ # Homey MCP client and state cache
├── services/ # Co-located service containers
│ ├── tools-mcp/ # Sandboxed bash/python/scrape/search
│ └── prometheus-mcp/ # Prometheus metrics MCP server
├── docs/ # Design documentation
├── prompts/ # Agent persona, instructions, home context
├── data/ # Runtime data (git-ignored)
│ ├── db/ # SQLite databases
│ └── chroma/ # Vector store
├── docker/ # Dockerfile and build assets
├── .env.example
├── docker-compose.yml
└── pyproject.toml
The Docker image supports both ARM64 (Apple Silicon Mac) and AMD64 (Linux).
# Build for both platforms and push
docker buildx build \
--platform linux/amd64,linux/arm64 \
-t homeagent:latest \
--push .- Architecture
- Architecture Diagrams
- Agent Design
- Memory Design
- Household World Model
- Agent Skills
- Multi-Step Tasks
- Observability
- Slash Commands
- Tech Stack
- Telegram Integration
- Homey MCP Integration
- Folder
prompts/contains persona, instructions, and home context templates for the LLM. Update these to fit your household and preferences.