Open source · reached through Signal

A thinking partner living at home.

You reach Estia through Signal: text her, send a voice note or call her. She knows your calendar, reads your mail, dims the lights and looks things up. The AI model runs on your Mac. Mail and calendar are read-only, and she answers only you.

  • No cloud AI
  • No open port
  • No account with us
  • MIT licence
Tiffany (AI) Signal, end-to-end encrypted
  1. Today 08:41
  2. what's on Friday?
  3. Two things: a team call at 10:00, and dinner at 19:00.
  4. turn off the living room lamp
  5. Done, the living room lamp is off.
  6. Voice note, 0:04
  7. Everything is up. The model and helpers are answering, and disk and memory look fine.
Our own Estia is called Tiffany.

The short version.

Text, talk or call.

Everything happens in one Signal chat, in one language at a time: English or one of ten others. Core features work after setup. Each extra stays off until you add its section to the config.

Security, in plain words.

Estia reads your mail and calendar and switches things in your home, so she is built to do as little as she can, and to tell you what she did. These are the rules, and the gaps.

How a message travels

  1. Your phone

    You message her in Signal like any contact. The message is end-to-end encrypted.

  2. Signal

    Signal passes it on and cannot read it. Estia has her own number, so she never sees your other chats.

  3. Your Mac

    The Mac fetches it with signal-cli, a command-line Signal client, over an outgoing connection. No part of Estia accepts connections from the internet: no web app, no open port, nothing to log in to.

The rules

  • Only you can talk to her. Only the Signal accounts in her config get an answer, checked in code. Strangers get nothing back: no reply, and their calls are not even rejected, since a rejection is itself a reply.
  • Mail and calendars are read-only. Mail is read with Microsoft's read-only permission, so the sign-in itself cannot send, move or delete. Outlook calendars use the read-only Calendars.Read, and Google calendars are a read-only feed whose secret address works like a password: never make a private calendar public for her. Mail bodies are never stored.
  • What she reads can't give her orders. Web pages, search results, mail, calendar entries and shared audio files are data, never instructions. If an answer drew on them, a device change waits for your yes.
  • She can't run commands. The model has no shell. Its only file access is a read-only tool for documents git tracks in your projects folder (~/dev unless you change it), never secret-like files such as .env.
  • She only learns from you. Facts come from what you say, or from a page you ask her to learn from, and what she picks up on her own never replaces a fact you gave her. Mail, calendar, web and map results never teach her anything.
  • Every device has a rule. Each light or plug is normal, ask first or never off, enforced in code. A note from code, not from the model, says what really changed.
  • What she keeps stays on the Mac. Chats and your profile stay in one database on the Mac until you delete them. Photos, voice notes and call audio are deleted after use. Logs never hold the text of a message.
  • Secrets go in hidden prompts. Setup and each extra ask for keys, codes and passwords in your own Terminal, never in a chat, and store them readable only by you.

What stays home, and what goes online

The model always runs on the Mac. Outside services are reached only for the extras you switch on. Mail syncs every five minutes in the background, and the digest reads the calendar each morning.

Stays on the Mac Goes online, for the extras you switch on
The model (Gemma, through Ollama) Signal, for your messages and calls (end-to-end encrypted)
Your chats, memory and profile Microsoft, to read mail and Outlook calendars (read-only)
Speech-to-text and text-to-speech Google's iCal feeds, for Google calendars (read-only)
Health checks and reading project docs Ollama's web search and Brave Search: your search questions
Lights and plugs (home network) Google Maps: what you look for, a rounded area for “near me”, and your home address for routes from or to home
Spotify, for music
Web pages: links you send her, and the top result of a Brave search

Setup also downloads the model (ollama.com), the voice models (Hugging Face) and, for calls, signal-cli and the call helper's sources (GitHub, crates.io).

Known gaps

  • Signal's own delivery receipts go to any sender, so a stranger can tell the number is registered.
  • signal-cli starts the call helper for every incoming call before Estia checks who is calling. The helper uses only Signal's relays, so a caller never learns the Mac's IP addresses.
  • One user per Mac is assumed. On a Mac shared with other accounts, another user could start a look-alike of one of her local services first.
  • A voice note forwarded inside Signal keeps its voice-note mark, so it counts as your own words.
  • The call helper is built on an old WebRTC revision.
  • Prompt injection is reduced by rules in code, not ruled out. A local model can still be talked into a wrong answer, so check anything important.

The full list is in SECURITY.md.

Found a problem?

Please report it privately, not in a public issue: use Report a vulnerability on the repository's Security tab. Leave real numbers, account IDs and keys out; a made-up example is enough.

The security policy lists what is in scope, and security.txt has the contacts.

This page, too

This page runs no JavaScript, sets no cookies and loads nothing from anyone else: no fonts from a CDN, no analytics, no trackers. Its content security policy blocks scripts outright.

Two commands, then a few prompts.

One script does the setup and asks you only for what it must. Most of the time goes to the model download (about 18 GB on a 32 GB Mac, about 8 GB on smaller ones). It needs no input; if it stops, run setup again and it resumes.

What you need

A Mac
Apple silicon. M1 or later, macOS 14 or later. Voice notes and calls need macOS 15.6.
Memory
16 GB or more. 32 GB is recommended. On 16 or 24 GB, setup picks a smaller model.
A phone number
A spare number. For her own Signal account; no Signal app may use it. A prepaid SIM is fine.
Disk
About 20 GB free. Mostly for the AI model.

The two commands

git clone https://github.com/enable4all/estia-on-mmini.git ~/estia && cd ~/estiascripts/setup.sh

Click a line to select all of it. Keep the folder at ~/estia, outside Desktop, Documents and Downloads: macOS blocks background services there.

Read it before you run it. The dry run describes every step and shows its commands, without asking, installing or downloading anything. setup.sh and the Python behind it are plain to read, and setup.sh is safe to run again: it skips what is done.

scripts/setup.sh --dry-run

What setup does, and what it asks of you

  1. Installs the tools. Homebrew if it is missing (it asks first, and Homebrew asks for your password once), then signal-cli, Ollama and uv, and starts Ollama.

    setup.sh
  2. Picks the model for your Mac and downloads it. gemma4:26b on 32 GB or more, gemma4:12b on 16 or 24 GB. The Mac stays awake meanwhile. If the download stops, run setup again and it resumes.

    setup.sh
  3. Registers her Signal number. You type the number; the captcha link, the SMS code and a registration-lock PIN, if any, go into hidden prompts and are never shown. A mistyped code can be typed again.

    You
  4. Finds you. setup.sh shows a one-time word, and you send it to her new number from your own Signal. The account that sent it is the only one that gets answers: a profile name could be copied, the word cannot. If it does not arrive, setup lists the usual reasons and looks again.

    You
  5. Asks her language, then writes the config and her personality. English unless you pick another. config.toml and soul.md in ~/.config/local-assistant, readable only by you. A file already there is copied first, never just replaced.

    setup.sh
  6. Makes her always on. A background service, the bridge, that starts at boot and runs as you, not as root. It asks for your password once, to put the service file in place.

    You
  7. Checks the result. scripts/doctor.sh changes nothing. Every ✗ line ends with the command that fixes it; ○ means set up but not tested yet.

    doctor.sh
  8. Says hello. On her first start she sends you a welcome message on Signal: what is set up, something to try, and what stays on the Mac. You are done when it has arrived and doctor.sh shows no ✗. Reply to see her answer.

    Estia

Or let your AI set it up

Open the folder in your AI coding assistant (Claude Code, Codex and the like) and say “set me up”. It follows SETUP-WITH-YOUR-AI.md, which tells it never to ask for a secret in the chat, never to read your key files and never to run sudo, and to hand over to you for the captcha, the SMS code, passwords and keys. If it asks for a secret in the chat anyway, don't paste it.

Or do it by hand

Every step is in setup_assistant.md, with what it does and how to check it, so you can see exactly what changes on your Mac.

Extras, one at a time

Each extra stays off until its section is in the config. One exception: the read-only project tool is on by default for the git repositories in ~/dev. Each extra's script asks for keys in hidden prompts, never through chat and never into the config file. scripts/setup.sh --extras lists them.

Extra What leaves the Mac How to add it
Voice notes and calls Nothing for speech: it runs on the Mac. Calls go through Signal's relays, so your phone never learns the Mac's IP address. To keep your phone's address from the Mac too, turn on “Always relay calls” in Signal on your phone. scripts/install-voice-daemon.sh; calls also need a build in tools/call-tunnel/
Calendar and digest A read of each calendar, each time she looks and each morning: Google's iCal feed, or Microsoft 365 for an Outlook calendar Google: scripts/set-calendar-url.sh [name]. Outlook: Calendars.Read, then scripts/mail-login.sh <address>
Mail A read-only sync with Microsoft 365, every five minutes scripts/mail-login.sh <address>
Lights and plugs Nothing: home network only scripts/tapo-discover.sh
Web search Your search questions, to Ollama and Brave scripts/set-web-keys.sh
Places and routes What you look for, an area rounded to about 1 km, and your home address for routes from or to home, to Google scripts/setup-google-maps.sh
Music Playback commands, to Spotify scripts/spotify-login.sh

Keeping her running.

Once she is set up, there is little to do. She watches the Mac herself, and two read-only scripts tell you what is wrong and how to fix it.

Updating

git pull && uv sync --frozen && (cd tools/tapo && uv sync --frozen) && (cd tools/ical && uv sync --frozen)sudo launchctl kickstart -k system/com.local-assistant.bridge

Run in ~/estia. The second line restarts the bridge and asks for your password. After changes in tools/voice, also run scripts/install-voice-daemon.sh. Files and services use the project's internal name, local-assistant.

When something is off

You see What to do
“Estia isn't available right now” Ollama is not running. Start it with brew services start ollama.
“Voice isn't available right now” The voice service is down or still loading. After a macOS update, allow about 15 minutes.
A mailbox asks for sign-in Run scripts/mail-login.sh <address> again.
“Calendar: the secret address no longer works” Save the new address with scripts/set-calendar-url.sh (with the calendar's name, if it has one).
“Calendars.Read is not granted yet” An administrator grants it in Microsoft Entra, or run scripts/mail-login.sh <address> again.
She answered before, then replies stop Often a changed Signal safety number. Confirm it in Signal first, then follow Operations.
No reply at all, not even “typing…” Run scripts/check.sh over SSH, then read ~/Library/Logs/local-assistant/bridge.log.
Anything else Run scripts/doctor.sh, or send /status.

Good to know

  • She is as awake as the Mac. If it sleeps or is off, so is she. Ollama starts when you log in, so after a restart someone logs in once. Automatic login avoids that but cannot be used with FileVault, which keeps her data encrypted; sudo fdesetup authrestart restarts without the password prompt.
  • Replies take a few seconds. At most about half a minute. The first one after a quiet spell is slower while the model loads.
  • She says when she was away. After a restart she skips messages older than ten minutes and tells you she was offline, so you can ask again.
  • Backups are not built in yet. The database and Signal's keys are not backed up for you.

Common questions.

What does it cost?

Estia is free and MIT licensed (the call helper, which patches AGPL code, is AGPL-3.0), and the model is free too. Some extras use outside services with their own terms: music needs Spotify Premium, places and routes need a Google Cloud account with billing (a daily cap keeps use within the free allowance), and web search needs Brave and Ollama API keys.

Which Mac do I need?

A Mac with Apple silicon and 16 GB of memory or more; 32 GB is recommended. macOS 14 or later, and macOS 15.6 or later for voice notes and calls. A Mac that stays on, such as a Mac mini, works best.

Which languages does she speak?

One at a time: English, Spanish, Italian, Korean, Portuguese, Dutch, Polish, German, Japanese, Russian or French, the languages Whisper hears best that also have a voice. You pick one at setup, and it changes only when you type /language in Signal, never by voice. What the code writes, such as notes, the digest's headings and /status, stays in English.

Does anything leave my Mac?

The model always runs on the Mac. Your messages travel through Signal, end-to-end encrypted. Each extra you switch on reaches its own service, and only for that job. The table under Security lists every one.

Why Signal, and not her own app?

Signal already has end-to-end encryption, voice notes and calls on any phone, and the Mac fetches messages over an outgoing connection, so it needs no open port. There is no web app to attack and nothing to log in to.

Can other people talk to her?

No. Only the Signal accounts in her config get an answer, and setup adds only yours. Anyone else is ignored: no reply, no read receipt, no typing indicator. Signal itself still confirms delivery, so a stranger can tell the number exists.

Can she send mail or change my calendar?

No. Mail is read with a read-only permission, so even the sign-in cannot send, move or delete anything. Calendars are read-only too: Google calendars through a read-only feed, Outlook calendars with a read-only permission. She tells you what needs a reply; you answer it yourself.

Which model does she use?

Google's Gemma 4, through Ollama: gemma4:26b on 32 GB or more (the tested one), gemma4:12b on smaller Macs, with weaker answers. Any Ollama model with tool calls can be set in the config.

Can I change her personality?

Yes. Her tone comes from soul.md, a short file you write. She reads it but never edits it, and it shapes how she sounds, never what she is allowed to do.

What if the Mac restarts?

She is back once the Mac is up and Ollama runs. Set the Mac to never sleep and to start after a power failure; the settings are in Keep it running.

Why Estia, and can I call her something else?

Estia (Εστία) is the hearth, the heart of a Greek home. Name her what you like: it is one setting. Ours is called Tiffany, and Estia started as her. Estia is an independent open-source project by enable4all.