Every "chat with an AI from your phone" product asks you for the same thing: an account. Then your conversations live in a database you don't administer, subject to a retention policy you didn't write and can't audit.
I wanted the opposite trade — Claude in my messengers, with the transcript on my own disk. That's Telechat: a self-hosted Claude bot that runs as one Python process, speaks Telegram, WhatsApp, Slack and a local web chat at the same time, and stores everything in a single SQLite file.
Here's what that actually buys you, and — because "privacy-first" is a claim people make without qualifying it — where the trust boundary really sits.
Thirty seconds, no account anywhere
The fastest way to see it work skips setup entirely:
npx telechat web
That starts a chat UI on http://127.0.0.1:8585. No bot token. No messenger account. Nothing written to disk. It needs exactly one thing — a way to reach Claude, either the Claude Code CLI you already have or an ANTHROPIC_API_KEY — and if neither is there it tells you which one is missing instead of failing obscurely.
It binds to loopback. Not 0.0.0.0 with a note in the README telling you to firewall it.
The self-hosted part is the whole point
A self-hosted Claude bot runs on your machine under your account. In CLI mode Telechat shells out to the claude binary you already authenticated, so if you have a Claude subscription there's no API key and no second bill. In API mode it talks to Anthropic directly with your key.
Either way there is no Telechat server in the path. I don't operate one. There's nothing to log into, so there's nothing of yours for me to hold. Your turn history, saved memories, knowledge base, session state and cost tracking all land in ~/.telechat/bot.db:
sqlite3 ~/.telechat/bot.db .tables # it's just a file
telechat env clean # and credentials are just a file too
You can read it, grep it, back it up, or rm it. That's the entire data-deletion story.
One process, four messengers
Which platforms start is one environment variable:
BOT_MODE=telegram # the default
BOT_MODE=telegram,slack # a comma-separated list
BOT_MODE=all # all four
Each adapter owns its platform's quirks — Telegram's inline keyboards, Slack's thread semantics, WhatsApp's total lack of interactivity — then hands a plain string to the same invocation layer.
The payoff isn't that it saves RAM. It's that they share the store, so they share your conversation. A memory you saved from Telegram is loaded when you ask from Slack. A session you started at your desk in the web chat is on the list when you pick it up on your phone. That's only true because there is exactly one process and exactly one database.
Nothing on the internet has to reach you
This is the design decision that removes most of the attack surface, and it's easy to miss because it shows up as an absence.
The usual chat-bot tutorial reaches for a webhook. Accept an inbound HTTP request and you now need a public URL, a TLS certificate, and a reply inside the platform's timeout — which an LLM turn routinely blows past, so you need a queue, so you need somewhere to run the queue.
Telechat never accepts an inbound connection from a platform:
| Platform | Transport |
|---|---|
| Telegram | Long polling |
| Green API free tier, polled over HTTPS | |
| Slack | Socket Mode — an outbound WebSocket the app opens |
| Web chat | Local aiohttp server on 127.0.0.1
|
All four are outbound. No inbound firewall rule, no tunnel, no certificate to renew, nothing exposed. It works behind NAT, on hotel Wi-Fi, on a corporate network, and on a laptop that closes — when it wakes, polling resumes.
The part "privacy-first" posts usually leave out
Self-hosted is not automatically safe, and the honest version matters more than the marketing one.
In CLI mode, this bot is a remote shell. It runs claude with your authentication and your filesystem access. Anyone who can message the bot can ask Claude to read, write, or execute, bounded only by CLAUDE_CLI_PERMISSION_MODE and CLAUDE_CLI_WORK_DIR. So:
Always set an allowlist. TELEGRAM_ALLOWED_USER_IDS, WHATSAPP_ALLOWED_NUMBERS, SLACK_ALLOWED_USER_IDS. Empty means anyone who finds your bot can use it. The setup wizard warns about this and the warning is not decorative.
The allowlist is flat. Conversations and memory are keyed per user; capability is not. Everyone on that list shares one Claude auth, one working directory, and one permission ceiling. Adding a second person grants them what it grants you. This is a personal single-operator tool, not a multi-tenant deployment, and per-user isolation does not exist yet.
There's also a class of bug worth naming because it's specific to running on a machine you care about. Telechat reads links you paste, so a pasted URL is an outbound request from inside your network. A recent fix closed the obvious holes: redirects are now followed one hop at a time with every hop re-checked, and hostnames are resolved with every resolved address checked — so a public link answering 302 Location: http://169.254.169.254/ no longer reaches cloud metadata, and a hostname pointing at 127.0.0.1 no longer reaches your own services. DNS rebinding is still open; closing it means pinning connections to a vetted address, which is a larger change. That's documented rather than glossed.
If that trade-off doesn't suit you, it should be visible before you install, not after.
Install
npm install -g telechat
telechat init
telechat init walks each platform interactively, opens the right pages, grabs your tokens, validates them, and writes your config. There's pip install telechatai if you'd rather, and telechat doctor when something's off.
MIT licensed, source at github.com/telechatai/telechat. It's a small project and the security policy describes the trust boundary in more detail than most tools this size bother with — which is, I think, the least you should expect from anything you're about to hand your filesystem to.
Top comments (0)