Turn Claude Code into your personal assistant, accessible from anywhere via Telegram.
Send text, voice, photos, and documents. See responses and tools usage in real-time.
I've started using Claude Code as a personal assistant, and I've built this bot so I can access it from anywhere.
In fact, while Claude Code is described as a powerful AI coding agent, it's actually a very capable general-purpose agent too when given the right instructions, context, and tools.
To achieve this, I set up a folder with a CLAUDE.md that teaches Claude about me (my preferences, where my notes live, my workflows), has a set of tools and scripts based on my needs, and pointed this bot at that folder.
β π See the Personal Assistant Guide for detailed setup and examples.
- π¬ Text: Ask questions, give instructions, have conversations
- π€ Voice: Speak naturally - transcribed via OpenAI and processed by Claude
- πΈ Photos: Send screenshots, documents, or anything visual for analysis
- π Documents: PDFs, text files, and archives (ZIP, TAR) are extracted and analyzed
- π Session persistence: Conversations continue across messages
- π¨ Message queuing: Send multiple messages while Claude works - they queue up automatically. Prefix with
!or use/stopto interrupt and send immediately - π§ Extended thinking: Trigger Claude's reasoning by using words like "think" or "reason" - you'll see its thought process as it works (configurable via
THINKING_TRIGGER_KEYWORDS). The default chat model is Claude Opus 4.7, which always runs adaptive thinking withxhigheffort and ignores these keyword controls; Sonnet 4.5 / Haiku 4.5 still honor them. - π Interactive buttons: Claude can present options as tappable inline buttons via UIAskUserQuestion (JSON choice format)
git clone https://github.com/linuz90/soma
cd soma
cp .env.example .env
# Edit .env with your credentials
bun install
bun run src/index.ts- Bun 1.0+ - Install Bun
- Claude Agent SDK -
@anthropic-ai/claude-agent-sdk(installed via bun install) - Telegram Bot Token from @BotFather
- OpenAI API Key (optional, for voice transcription)
The bot uses the @anthropic-ai/claude-agent-sdk which supports two authentication methods:
| Method | Best For | Setup |
|---|---|---|
| CLI Auth (recommended) | High usage, cost-effective | Run claude once to authenticate |
| API Key | CI/CD, environments without Claude Code | Set ANTHROPIC_API_KEY in .env |
CLI Auth (recommended): The SDK automatically uses your Claude Code login. Just ensure you've run claude at least once and authenticated. This uses your Claude Code subscription which is much more cost-effective for heavy usage.
API Key: For environments where Claude Code isn't installed. Get a key from console.anthropic.com and add to .env:
ANTHROPIC_API_KEY=sk-ant-api03-...Note: API usage is billed per token and can get expensive quickly for heavy use.
- Open @BotFather on Telegram
- Send
/newbotand follow the prompts to create your bot - Copy the token (looks like
1234567890:ABC-DEF...)
Then send /setcommands to BotFather and paste this:
start - Show status and user ID
new - Start a fresh session
resume - Resume last session
stop - Interrupt current query
status - Check what Claude is doing
restart - Restart the bot
Create .env with your settings:
# Required
TELEGRAM_BOT_TOKEN=1234567890:ABC-DEF... # From @BotFather
TELEGRAM_ALLOWED_USERS=123456789 # Your Telegram user ID
# Recommended
CLAUDE_WORKING_DIR=/path/to/your/folder # Where Claude runs (loads CLAUDE.md, skills, MCP)
OPENAI_API_KEY=sk-... # For voice transcriptionFinding your Telegram user ID: Message @userinfobot on Telegram.
File access paths: By default, Claude can access:
CLAUDE_WORKING_DIR(or home directory if not set)~/Documents,~/Downloads,~/Desktop~/.claude(for Claude Code plans and settings)
To customize, set ALLOWED_PATHS in .env (comma-separated). Note: this overrides all defaults, so include ~/.claude if you want plan mode to work:
ALLOWED_PATHS=/your/project,/other/path,~/.claudeCopy and edit the MCP config:
cp mcp-config.ts mcp-config.local.ts
# Edit mcp-config.local.ts with your MCP serversThe bot supports UIAskUserQuestion, allowing Claude to present options as tappable inline keyboard buttons by emitting JSON choice objects. Add your own MCP servers (Things, Notion, Typefully, etc.) to give Claude access to your tools.
| Command | Description |
|---|---|
/start |
Show status and your user ID |
/new |
Start a fresh session |
/resume |
Resume last session after restart |
/stop |
Interrupt current query |
/status |
Check what Claude is doing |
/restart |
Restart the bot |
cp launchagent/ai.2lab.soma.plist.template ~/Library/LaunchAgents/ai.2lab.soma.plist
# Edit the plist with your paths and env vars
launchctl load ~/Library/LaunchAgents/ai.2lab.soma.plistThe bot will start automatically on login and restart if it crashes.
Prevent sleep: To keep the bot running when your Mac is idle, go to System Settings β Battery β Options and enable "Prevent automatic sleeping when the display is off" (when on power adapter).
Logs:
tail -f /tmp/soma.log # stdout
tail -f /tmp/soma.err # stderrShell aliases: If running as a service, these aliases make it easy to manage the bot (add to ~/.zshrc or ~/.bashrc):
alias soma='launchctl list | grep ai.2lab.soma'
alias soma-stop='launchctl bootout gui/$(id -u)/ai.2lab.soma 2>/dev/null && echo "Stopped"'
alias soma-start='launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/ai.2lab.soma.plist 2>/dev/null && echo "Started"'
alias soma-restart='launchctl kickstart -k gui/$(id -u)/ai.2lab.soma && echo "Restarted"'
alias soma-logs='tail -f /tmp/soma.log'# Run with auto-reload
bun --watch run src/index.ts
# Type check
bun run typecheck
# Or directly
bun run --bun tsc --noEmit
β οΈ Important: This bot runs Claude Code with all permission prompts bypassed. Claude can read, write, and execute commands without confirmation within the allowed paths. This is intentional for a seamless mobile experience, but you should understand the implications before deploying.
β Read the full Security Model for details on how permissions work and what protections are in place.
Multiple layers protect against misuse:
- User allowlist - Only your Telegram IDs can use the bot
- Intent classification - AI filter blocks dangerous requests
- Path validation - File access restricted to
ALLOWED_PATHS - Command safety - Destructive patterns like
rm -rf /are blocked - Rate limiting - Prevents runaway usage
- Audit logging - All interactions logged to
/tmp/soma-audit.log
Bot doesn't respond
- Verify your user ID is in
TELEGRAM_ALLOWED_USERS - Check the bot token is correct
- Look at logs:
tail -f /tmp/soma.err - Ensure the bot process is running
Claude authentication issues
- For CLI auth: run
claudein terminal and verify you're logged in - For API key: check
ANTHROPIC_API_KEYis set and starts withsk-ant-api03- - Verify the API key has credits at console.anthropic.com
Voice messages fail
- Ensure
OPENAI_API_KEYis set in.env - Verify the key is valid and has credits
Claude can't access files
- Check
CLAUDE_WORKING_DIRpoints to an existing directory - Verify
ALLOWED_PATHSincludes directories you want Claude to access - Ensure the bot process has read/write permissions
MCP tools not working
- Verify
mcp-config.tsexists and exports properly - Check that MCP server dependencies are installed
- Look for MCP errors in the logs
MIT
