Geoff is a simple, constrained personal assistant written in Rust, supporting a small set of narrowly scoped tools, and designed to reliably handle well-defined tasks without surprises. It's vibe-coded exactly for my needs and probably won't be useful to you, except as inspiration to build your own hyper-opinionated personal assistant! You can chat to Geoff in the terminal or over Telegram, and he can access your emails, calendars, notes and contacts, and run scheduled tasks. That's it.
Today's world is full of shiny, flashy personal assistants, constantly updating themselves and executing literally any task that you can imagine - think Moltbot-née-Clawdbot; if you imagined this as an actual personal assistant, it'd be someone who rearranges your entire filing system alphabetically by the third word of each document while you're at lunch, then sends a 47-slide presentation about the efficiency gains. This .... may well be what you wanted, but, there is a certain inherent element of terror involved.
Now this isn't for everyone. Some of us want bland, mid-tier assistants, capably executing a narrow set of tasks that have been carefully delegated down to them.
Free access to the entire internet? Nope. The ability to go and update themselves on the fly with "exciting new features?" No thankyou.
Now imagine a personal assistant for some mid-tier executive in a boring industry. Probably Banking. He's not going out there and landing High Stakes Deals on your behalf - oh no, he lacks the initiative (and access to resources!) for that. Nor is he furiously creating new arms/feet/heads for himself to further execute Your Every Task.
Geoff embodies reliability over flashiness - he's the kind of assistant you can depend on to handle tasks that have been carefully explained to him, executing them with minimal fuss. He has a small set of tools available to him, with narrowly defined interfaces, and he studiously chips away at his low-stakes tasks with them.
Geoff is a small, straightforward Rust application in the spirit of moltbot, but much more constrained:
- Single binary simple, hard-coded tools. Jeff can use his tools to:
- Work with Obsidian vaults
- Read and search an IMAP mail server
- Read calendars events over CalDAV
- Read contacts over CardDAV
- cron scheduler to automate tasks at certain times
- A terminal UI and a telegram UI to interact with
That's it! No filesystem access, no web access. If you want more features you have to code them; this is just enough for Geoff to be useful to me to help with my daily work.
I think there's a lot to be said for building software just for ourselves. Coding agents reduce the personal cost - and barrier to entry - to building new things, to such an extent that we can suddenly afford to make something reasonably complicated that scratches a personal itch without having to drop other things. Geoff is exactly that for me - it hasn't taken substantial effort on my part - i've barely looked at the code - but it does solve a useful subset of problems that Moltbot does without me losing sleep over it. If I want more tools, I can quickly let an agent bolt them on. I don't have to care about generalising this out, or trying to drive adoption of it to make it worth my time. Probably, personal assistants are a real sweet spot for "vibecode a thing that scratches my exact itch".
Which is to say - probably Geoff is useless for you - except for perhaps as a foundation for your own personal assistant ideas - but I think that the idea, at least - personal software for personal needs - has legs.
Requires Rust 1.85 or later.
cargo build --releaseThe binary will be at target/release/geoff.
Geoff looks for configuration in:
./geoff.toml~/.config/geoff/config.toml
All settings, including API keys and passwords, can be set directly in geoff.toml. Alternatively, secrets can be provided via environment variables (e.g., ANTHROPIC_API_KEY, IMAP_PASSWORD).
By way of example:
[llm]
model = "claude-sonnet-4-20250514"
max_tokens = 4096
system_prompt = "You are Geoff, a reliable personal assistant."
[user]
name = "Your Name"
location = "Melbourne, Australia"
timezone = "Australia/Melbourne"
[ui]
mode = "tui" # or "web" or "telegram"
[ui.web]
host = "127.0.0.1"
port = 3000
[ui.telegram]
bot_token = "your-bot-token"
authorized_user_id = 123456789
[tools.email]
host = "imap.example.com"
port = 993
username = "you@example.com"
[tools.calendar]
url = "https://caldav.example.com/calendars/user/"
username = "you@example.com"
[tools.contacts]
url = "https://carddav.example.com/addressbooks/user/"
username = "you@example.com"
[tools.notes]
vault_path = "/path/to/obsidian/vault"
[[task]]
name = "morning-briefing"
schedule = "0 8 * * 1-5" # Weekdays at 8am
prompt = "What's on my calendar today?"
enabled = true- Create a bot via @BotFather on Telegram
- Get your user ID via @userinfobot
- Add
bot_tokenandauthorized_user_idto the config - Run
geoff --ui telegram
geoff # Start with default TUI
geoff --ui web # Start web interface
geoff --ui tui # Start terminal interface
geoff --ui telegram # Start as Telegram bot
geoff --debug # Show tool calls and logs (TUI only)Add [[task]] sections to run prompts on a schedule using cron syntax:
Cron format: "minute hour day-of-month month day-of-week"
Examples:
"0 8 * * 1-5"- Weekdays at 8am"30 9 * * *"- Every day at 9:30am"0 */2 * * *"- Every 2 hours
Geoff is structured as a Cargo workspace with the following crates:
| Crate | Purpose |
|---|---|
geoff-core |
Core types, traits, and error handling |
geoff-config |
Configuration loading and validation |
geoff-llm |
LLM provider abstraction (Anthropic) |
geoff-tools |
Tool implementations (email, calendar, etc.) |
geoff-observability |
Datadog LLM Observability integration |
geoff-ui |
UI handlers (TUI, web, Telegram) |
geoff-cli |
CLI entry point |
