What no app knows on its own.
Four apps record my day: Hevy my training, MyFitnessPal my food, the scale my weight, the watch my sleep. Milo reads them all and tells me what they mean together.
I built Milo because I could not buy a coach like this anywhere. The sketch shows how he is put together. As you scroll, every part docks into place.
One place for everything.
I never wanted Milo's knowledge to hang in a chat history. So everything lives in Postgres: training, measurements, habits, memories, every message. n8n hands it to Claude, Claude replies.
The core has sockets on its rim. Over the next chapters they fill up.
Eight blocks tell Milo where I stand.
Instead of a chat history, Claude gets a briefing. Eight blocks, computed fresh from the database for every message and inserted into the persona. If a value is missing, it says so. If a block is missing, Milo does not answer. The placeholders keep their German names from the code.
- DATUM
- Weekday and date
- ZIELE
- My goals, from the profile
- HISTORIE
- Training per week and muscle group, plus weight, sleep, steps, protein and appointments
- KONTAKT
- Status of unanswered check-ins
- EVIDENZ
- What the research says about the current question, with a source
- HABITS
- What I have already done this week
- ERINNERUNGEN
- Memories that match the message or are due today
- GESPRAECH
- Conversation of the last few days, with times
What I track anyway.
I did not want a new app to type things into. The apps I already use keep recording. Milo gets their data and never has to ask.
Hevy
As soon as I save a workout in Hevy, Hevy tells Milo. He fetches the sets and writes them to the database. At night he checks the ten most recent workouts again, in case a notification got lost.
Apple Health
An Apple shortcut pulls weight, food, sleep and steps from Apple Health and sends them to Milo. The raw data stays put. If processing goes wrong, I simply process the day again.
Buttons
A few things only I can know. For those I tap a button, in Telegram or in the web app. Milo stores every tap as an event and takes the last one.
If I want a new source, I build a webhook and a function. The rest is already there: the view where all measurements come together, and the habits that look at it.
Whatever Milo says, SQL worked out first.
A language model counts weekdays about as reliably as I do mental arithmetic after training. On 30 September Milo turned five days into two. Since then every number about intervals and weeks comes from SQL, and Milo takes it word for word.
The same goes for training goals: per exercise the best working set counts. The goal for the next session is to beat it, with one more rep or the next weight step.
Milo dreams, and something catches his eye.
At night Milo looks back seven days. Comeback, break, new top weight, habit streak: whatever he finds, he stores once as a memory. If a night is missed, the next one catches up.
Memories also come from conversation: one sentence that makes sense on its own, with type, importance and vector. For every message Milo retrieves the best matches, by similarity, importance and age.
On Mondays Milo sums up the week.
On Mondays SQL assembles the week, Claude writes a weekly review and a new version of my core profile from it. No version is overwritten.
Milo may be wrong, but not for good. Wrong memories I delete in the web app. Gone is gone, and the log never knows the wording.
Expert knowledge only with a source.
I did not want Milo pulling fitness knowledge out of the model. So there are 49 cards, each with a claim, its consequence, limits, strength of evidence and a verified DOI. For every message Milo looks up the ones that match, at most three.
Milo states numbers and study findings only from these cards or from my data, and says how sure that is. If he lacks the basis, he says so and notes the question.
If I want to teach Milo something new, I write a card into the seed file. At night it gets its vector, then Milo can find it.
Wherever I write, Milo knows.
To Milo, a channel is just a webhook. Agent, memory and history are the same for all of them. What I say in Telegram in the morning, Milo knows on the web in the evening.
Telegram
Milo started on Telegram. The check-in arrives here in the evening, with the buttons for ticking off habits under the habit message. Whisper transcribes voice messages.
Web app
heymilo.de is Milo's own interface, private, passkey login. The chat opens first and shows the same history as Telegram. Milo's reply appears word by word, with the logbook of training, weight and habits in between. Replies arrive as push notifications on my phone.
Voice
After training I do not like typing. So I hold the button, talk and let go. Whisper transcribes, with a vocabulary from the database. Only the text is kept, no audio.
If I want to reach Milo somewhere else, I build a webhook and add a value for channel. From the first web chat to voice messages, that took two days.
On the side
One glance at my phone is enough: the widget shows the week as a grid, the Today section the same with history. Every workout lands in the calendar, its title computed from the sets, not taken from Hevy.
Milo looks after himself.
If a workflow fails, the error lands in the database and as a Telegram message with me. Secrets are redacted beforehand, a warning sign tells the message apart from Milo. If an error repeats, it arrives at most once per hour.
Not every failure makes noise. A daily check reports when the shortcut has been silent for 36 hours or a value is missing three times in a row. Whatever can heal overnight heals overnight.
What an extension costs.
I built Milo so that something new is usually one row in the database, not a rebuild. Tap an extension: the stage lights up what changes, and the real code is shown below.
What comes next.
What I build next is on the roadmap. Three sockets are already free for it, there is no date.
- Nutrition
- Instead of tracking everything: Milo makes a plan, I only say when I deviate. What he does not know he estimates, and says that he is estimating. The targets come from the evidence cards.
- Training plan
- A training plan as a table in the database, with mode changes and deloads.
- New cards
- Sleep regularity, creatine, steps. They only come once the sources are checked.
What Milo cannot do.
- Milo exists only for me. Not a product, no accounts, no waiting list.
- Milo makes no diagnoses. If something hurts, he advises rest and a doctor. If I am not doing well, he stops coaching and points to people.
- He only sees what apps record and what I tell him.
- He can be wrong, but says how sure he is: well established, indication, contested.
- Everything SQL does not compute yet, the model computes, and that can go wrong.
- All values on this page are examples, not real health data. Milo speaks German, the messages shown here are translated.