I built a home server out of a 2017 MacBook Pro that was three months from the e-waste pile. That's the part people ask about. The interesting part is what it runs.
The setup: a Telegram bot on my phone connects to Carson, the Claude Code instance described in the previous post. It pushes results to my phone. No laptop needed.
One thing up front, before you get further. What works today is outbound only. Inbound is broken on the current Claude Code version. I'll get to that. If you came here for "chat with your AI from your phone," this isn't quite that yet.
Here's how it works, and what broke along the way.
Why a 2017 MacBook Pro
The MacBook was already there. It ran Home Assistant for a while. Then it started doing something more useful.
I first wired this up on the 2017 machine. That was the prototype. The version I actually use now connects Telegram to Carson on my main Mac. The 2017 machine is always-on infrastructure: Home Assistant, storage, the usual home server work. It also runs its own Claude Code instance, named Mrs Hughes. She handles the things that benefit from running locally and always-on: changing the lights, managing files on the server's storage, setting up Home Assistant automations. That's why the home server runs Claude Code at all. The naming follows the household convention from the first post. It just made sense to keep it consistent.
To be clear about the architecture, in case it gets confusing later. The Telegram bot does not live on the 2017 machine. It's a thin Node MCP server that runs on my main Mac alongside Carson. It runs wherever Carson runs.
Why Telegram
I looked at iMessage, WhatsApp, Slack, and building a custom iOS app.
iMessage is closed. There's no public bot API. WhatsApp Business has an approval process and per-message fees that make no sense for personal use. Slack would work but it's where I work. I didn't want the blur. A custom iOS app would've taken weeks to build and required me to maintain it. Hard pass.
Telegram has a free, public bot API. It works on every device I own. No business account, no developer review process. You register a bot via @BotFather, get a token, get your chat ID from one API call, and that's it.
Total added cost beyond what I was already paying for Claude: nothing.
The technical shape
Three moving parts.
The bot token. Register with @BotFather, get a token. That token is a password. It goes in a .env file and nowhere else. Leak it and anyone can send messages to your phone through your bot. Treat it like an SSH key.
The MCP server. A small Node script reads BOT_TOKEN and CHAT_ID from environment variables, exposes a single send_telegram_message tool, and POSTs to Telegram's /sendMessage endpoint. Wire it into Claude Code's MCP config. Carson can now push to your phone.
The CLAUDE.md instruction. This is the part that's easy to miss. The server being available doesn't mean Carson will use it. You have to tell him to. I added one line to CLAUDE.md: after completing any task that produces output, push a summary to Telegram. Without that line he just writes the result and stops. The tool sits there unused.
That's the whole outbound stack. Carson finishes a task. Sends me a message. My phone buzzes.
The interesting bit: inbound
The harder half is getting messages in. Typing something in Telegram and having Carson act on it.
Outbound is a dumb POST request. Inbound requires the MCP server to poll Telegram's API, detect new messages, and surface them into an active Claude Code session. Different problem. The protocol is called notifications/claude/channel, and it's where things got messy.
On Claude Code version 2.1.126, inbound messages silently disappear.
The bot receives the update from Telegram. You can see the typing indicator fire. The message lands nowhere. Nothing in ~/.claude/channels/telegram/inbox/. No error. No stderr. Just silence.
This is a confirmed bug (GitHub issue #56258, which I filed on May 4th, along with five or six other people who hit the same thing). The 2.1.x line doesn't act on notifications/claude/channel MCP notifications. It's not the token. It's not the allowlist. It's not the webhook config. The plumbing is fine. The version is broken.
Outbound still works on 2.1.126. So if you only need to push results to your phone, the setup is usable right now. True two-way will come when the bug is fixed.
So that's where it stands. What I have is a notification layer that can also receive instructions when I'm at my laptop. Not yet a mobile interface I can fire commands at from the bus. The gap is one version bump away. Just not there yet.
What it actually gets me today
Morning. Coffee. Phone.
Carson has a routine that runs at 07:00. Today's calendar, top XFA design priorities, anything worth knowing before I open the laptop. It lands in Telegram. I read it before I've looked at email.
Good morning, sir. Tuesday. One meeting: XFA product sync at 10:00 with the product team. Top design priority: the Compliance Goals onboarding flow — a gap between the agentless and enforcement paths was flagged last week, still unresolved. No Jira tickets due today. Dutch lesson at 14:00.
Evening. Before bed. One paragraph: wins, what slipped, one thought for tomorrow. That's it. Pushed to Telegram, no laptop needed.
Evening, sir. Win: the Awareness notification redesign got sign-off from the founder. Slip: the Enforcement block-state edge case is still sitting in Figma — you looked at it but didn't decide. Tomorrow: decide or park it. Don't open the laptop without a verdict in hand.
The async dispatch piece is what I'm most looking forward to when inbound is fixed. "Carson, draft a reply to that Jira comment." Result lands in Telegram. I copy-paste or approve. That loop doesn't require me to be at a desk.
The 2017 MacBook is running 24/7 for the Home Assistant side anyway. The Telegram MCP on the main Mac adds no always-on cost. It only runs when Carson is active.
What I'd do differently
Start with outbound only. The temptation is to wire up two-way from the start. Don't bother. Outbound push notifications are immediately useful. Inbound adds complexity and, as of this writing, a known bug. Get value from push first. Add the return channel when it's stable.
Keep the CLAUDE.md instruction explicit. The MCP server being configured does not mean Carson will use it. Write it clearly: after every task, send the output to Telegram. Hand-wavy instructions get hand-wavy results.
Don't put the bot token anywhere near your CLAUDE.md or your wiki. It's a credential. .env file. Add it to .gitignore before you do anything else. I cannot make this point loudly enough.
The setup isn't magic. It's a push notification system with a language model behind it. What makes it useful is the context layer. The wiki described in the first post is what personalises the morning brief and the evening review. Strip the wiki and you get a generic summary that could've been written by anyone. The Telegram layer is just the delivery.
The pipe is the easy bit. The brain is the part that took two months.
This is part of an ongoing series on Carson OS. Post one covers the full architecture: the wiki, the agents, the household model.