- Send audio files (ogg/wav/mp3/flac/m4a) as audio_url in multimodal content - Remove whisper_url config and transcribe_audio — LLM handles audio natively - Skip media files in build_prompt text (only mention non-media uploads) - Log multimodal content types and successful API calls for debugging
NOC — Not OpenClaw
Telegram bot that bridges messages to local claude CLI sessions — chat with Claude directly from Telegram.
User → Telegram → noc bot → claude --resume → stream back → Telegram
~600 lines of Rust. One binary. One config file. Does the thing.
Why "Not OpenClaw"?
OpenClaw is an open-source AI agent framework with admirable ambitions. It supports 20+ messaging platforms, 35+ LLM providers, a hub-and-spoke gateway (Node.js), an agent runtime (separate language, naturally), a three-tier skills override system, built-in RAG pipelines, multi-agent routing, cron scheduling, browser automation, and voice wake-word detection. It has 400,000+ lines of code, 1,800+ open issues, and requires at least 1 GB of RAM to breathe. The official docs recommend a $600 Mac mini as a minimum viable host. Cold-start on a modest CPU: ~500 seconds. Security researchers have called it "a security nightmare dressed up as a daydream."
To be fair, if you need to orchestrate 47 Telegram bots across 12 LLM backends with a RAG pipeline and overnight autonomous tasks, OpenClaw is probably fine.
Most people just want to talk to Claude on their phone.
NOC is for those people.
How it works
- User sends a message to the bot
- First message must be the auth passphrase, otherwise the bot replies "not authenticated"
- Once authenticated, messages are piped to
claude --resume <session_id>via stdin claudestdout is streamed back as the reply (message is edited live as tokens arrive)- Files uploaded to the bot are forwarded to Claude; files Claude writes to the output dir are sent back
- Sessions are scoped per chat and refresh daily at a configurable hour (default: 5am)
Session IDs are deterministic — generated with UUIDv5 from (chat_id, date), format: noc-{chat_id}-{YYYYMMDD}.
Setup
cp config.example.yaml config.yaml
# fill in your values
Config
| Key | Description |
|---|---|
tg.key |
Telegram bot token |
auth.passphrase |
Passphrase required to authenticate each session |
session.refresh_hour |
Hour (local time, 24h) when sessions reset (default: 5) |
Deploy
Local
make deploy
Builds the release binary and installs a systemd --user service.
Remote (hera)
make deploy-hera
Builds locally, copies the binary and config to heradev, then starts the service there.
Logs
journalctl --user -u noc -f
Tech stack
| Layer | Technology |
|---|---|
| Language | Rust (2021 edition) |
| Telegram | teloxide 0.12 |
| Async runtime | tokio (full) |
| Config | YAML + serde |
| Deployment | systemd user service + Makefile |
Roadmap
- Streaming responses — edit message as output arrives
- Markdown formatting — MarkdownV2 rendering
- Timeout handling — kill claude if it hangs
- Graceful shutdown on SIGTERM
/resetcommand — force new session without waiting for daily refresh- Rate limiting per chat
- Voice message support — STT (whisper.cpp) → text → claude
- Video/audio transcription