My AI assistant runs my back office. I still press send myself.
Before I have my first coffee, last night’s invoices are booked and both bank accounts have been checked. After the coffee I say “inbox”, and a few minutes later I know which three emails actually matter today. The replies are already sitting in Gmail as drafts.
That is my assistant. I built it myself, and by now it is the hardest-working member of my company. It has exactly one restriction, and the restriction is deliberate: it is not allowed to send anything.
What it does all day
I run a small software company in Madrid on my own: a dozen products, my own servers, customers who write in three languages, and the paperwork that comes with a Spanish S.L. This is what it handles now.
- Mail. It goes through the whole inbox, shows me the most important messages first and writes the replies: right thread, right signature, my tone. As drafts.
- Money. It reads supplier invoices from the mail, checks whether they are already booked and enters them in my invoicing software, contix. It reads the business and the private account three times a day, works out who has paid, and flags every movement it cannot match to an invoice or that simply does not add up. Read only: it cannot move a single cent.
- Unpaid invoices. It keeps track of who still owes me money and prepares the payment reminder. The reminder only goes out after I say so. There is a reason for that. Last summer a reminder went to a customer who had paid long before. The money was in the account, nobody had matched it, and the warning about it had appeared exactly once. Since then, unmatched payments get flagged again and again until someone sorts them out.
- End of quarter. Before the books close I get the list of bank movements that still have no receipt. My accountant gets a complete file instead of a treasure hunt.
- Customers. “Has he paid? Since when has his hosting been running? Is his domain about to expire, and did we warn him?” The answer comes with evidence, not a hunch.
- Projects. I work on about fifteen projects, each with its own Claude Code session. It reads their code and documentation, keeps the docs current, records the latest status, commits to Git and backs everything up to GitHub. If an email concerns a project, it lands there as a task in the queue.
- Servers. A separate session looks after my servers and websites: checking backups, installing updates, running regular security audits and fixing whatever turns out to be open.
- Calendar. At the start of every session it tells me what is on today and which follow-ups are due. “Put this email on the 15th” and it is gone until the 15th. It only creates reminders when I ask. What goes into my calendar is my decision.
- Social media. It writes posts for LinkedIn, X, Bluesky, Mastodon and the rest and puts them in front of me. I approve, edit or reject. Whatever I approve, it publishes itself through the official APIs. On LinkedIn it also goes through my messages and suggests replies.
- AI costs. Paid AI calls from my projects go through a cost guard: text, images, video, voice, music. Every single call is logged with the project, the exact model and the amount, and every project has a daily cap. At the end of the month, or whenever I like, I can see who spent what.
None of this is spectacular on its own. Together it is the part of my day I used to call “admin” in a tired voice.
Written instructions instead of improvisation
A language model is talented and moody. Ask it the same thing twice and you get two ways of working. So every recurring job is a skill in my setup: a written work instruction that Claude Code follows exactly the same way every time.
The “inbox” skill, for example, says:
- First get an overview of the whole inbox, read and unread, however old.
- Then sort by importance. Customers and prospects always come first.
- For every important email, a suggestion of what to do and a draft reply.
- Where there are several sensible options: alternatives, but its preferred version always first, with one sentence explaining why.
- Routine at the end as a single list that I wave through with one word.
So every morning runs the same way. That sounds boring. That is the point.
The memory: 178,000 entries
An assistant without memory is a polite stranger. A customer writes “as discussed”, and the assistant has to know what was discussed. Two weeks ago, two years ago, in a note or in a chat.
That is why the heart of the system is not an AI at all, but a search database (RAG). As of today it holds:
- about 88,000 sent and received emails from the last five years, without newsletters and advertising,
- 38,000 passages from my Claude Code sessions,
- 25,000 commit messages, which together are the decision log of every project,
- 12,500 documents from all my project folders, and 6,800 pages of my own websites,
- plus notes, voice dictations, documents and exported WhatsApp chats.
When an email comes in, it looks there first: earlier threads with the same person, where the project stands, what I promised last time. Only then does it write.
I built the database in the spring, on my Mac. Every text is cut into passages, and an open source model (bge-m3) turns each passage into a vector of numbers that captures its meaning. That is why a search for “invoice for the migration” also finds the email that says “factura de la migración”. In June everything moved to my own server. It has no graphics card, so the first full run took hours. Since then, only new material gets added.
It stays fresh thanks to a handful of unremarkable scripts. The server pulls in new mail every 15 minutes and my websites every night. Twice a day the Mac pushes whatever only lives on the Mac: notes, session logs, commits, documents. Private and financial folders are deliberately left out. Because the vectors are computed on my own server, my mail does not go to any AI provider to be indexed.
The most instructive failure belongs here. For ten weeks, one script did not index a single new session. Every run politely reported “0 new, status ok”, and the statistics showed a respectable number. The number was not wrong. It was frozen. Since then I do not trust any “ok” that does not also say how much actually happened.
The side effect I never planned: my own sent mail is the style guide. The drafts sound like me because they learned from five years of me. Even the short ones.
Guardrails written in code
In May, an email to a customer contained an IBAN that did not exist. It looked perfectly plausible, and that was exactly the problem. One correction email later there was a list of verified facts (bank details, tax numbers, addresses) and a hook that checks every outgoing email against it. If a hard fact appears that is not on the list, the draft is blocked.
That is how every rule here comes about: from a real mistake, and then as code, not as a good intention.
- Credentials live in the keychain and a password manager, never in a prompt or a chat.
- Every write action first checks whether the thing already exists. Nothing gets booked twice.
- Money, legal matters, prices, dates and the first contact with a new customer always reach me as a question, never as an action.
- When something breaks, my phone buzzes. When everything works, it stays quiet.
- For important decisions I can call in a second AI as a reviewer. It checks the first one’s proposal without any obligation to agree.
Which model, what it costs, where the data lives
Not every job needs the strongest model. Routine work runs on small, cheap models; diagnosis and anything that cannot be undone runs on the strongest one. When a new model comes out, it gets tested on real cases before it takes over.
The thinking at my desk runs on my Claude Code subscription, so a long session costs nothing extra. The service on the server that recognises invoices and reads the bank accounts around the clock uses small models through the API: 5,193 runs in 90 days, 2.50 dollars in total. I checked the sum twice.
And for customers who cannot let a single line leave the EU: the AI calls can run entirely through Amazon Bedrock in a European data centre.
None of this is finished. The bank connection has to be re-authorised every 90 days and has had weeks where it simply delivered nothing. Then I reconcile by hand, like everyone else.
The one line
For a while it did send. I approved an email in the terminal and the assistant sent it. That worked fine, and in October I switched it off anyway.
Not because of a disaster. Every email in my name is a promise, and I want to have seen the promise. Since then every outgoing email is created as a draft, and a hook blocks direct sending.
In the morning I open Gmail and the drafts are waiting. Most of them I send as they are, some I change, a few I delete and tell it what I actually meant. The next draft is better.
If a customer asks whether I answer with the help of AI: yes. The person who decides what gets said is still me.
Why I am telling you this
Because this is exactly what I now build for other companies. Not the same assistant, but the same pattern: your email, your invoices, your bank, your software and a memory made of your own history, connected to a model that prepares the work, with a person who makes the decisions. Every company gets its own instance.
I built it for myself first because I wanted to know where it breaks. It breaks in boring places: an expired bank consent, an invoice layout that changes overnight, a script that says “ok” for ten weeks, an IBAN that looks too plausible, a reminder to someone who paid long ago. The interesting part was never the model. It was deciding what it is allowed to do on its own.
If you can picture something like this in your company, just get in touch: on WhatsApp or through the contact form. Two sentences are enough: what is eating most of your time right now. I write the reply myself. The draft, maybe not.
Get new posts by email
One mail when a new post is out. Nothing else: no drip campaign, no tracking, no “quick question” follow-ups. Unsubscribe with one click, any time.
Double opt in: you get a confirmation mail first. Your address is used only to send these posts. Controller: Martin Schenk S.L. · Privacy