cd /news/ai-agents/hasharot-control-a-claude-code-agent… · home topics ai-agents article
[ARTICLE · art-55216] src=github.com ↗ pub= topic=ai-agents verified=true sentiment=↑ positive

Hasharot – Control a Claude Code agent on your machine from Telegram

Hasharot, an open-source tool that connects Telegram to a Claude Code agent running locally on a user's machine, has been released. It allows users to control the agent via Telegram messages, enabling file operations, code editing, web browsing, and voice interactions while keeping code and secrets on the local machine. The tool supports team workflows with per-user sandboxing and owner approvals.

read14 min views1 publishedJul 11, 2026
Hasharot – Control a Claude Code agent on your machine from Telegram
Image: source

Your and your teammates' personal AI agent, running on your machine, controlled from Telegram.

  Telegram  ──▶  Grammy Bot  ──▶  Claude Agent SDK  ──▶  Your Machine
  voice/text     command router     agentic runtime       bash, files, code

Features · Quick Start · Commands · Team Workflow · Configuration · Architecture · Context & Memory · Roadmap

Hasharot bridges Telegram to a full Claude Code agent running locally on your machine. Send a message in Telegram — Claude reads your files, runs commands, writes code, browses Reddit, fetches Medium articles, transcribes voice notes, and speaks responses back. All from your phone.

This is not a simple API wrapper. It's the real Claude Code agent with tool access — Bash, file I/O, code editing, web browsing — packaged behind a Telegram interface with streaming responses, session memory, rich output formatting, and a multi-user access-control layer.

Why it's different:

  • 🧠 The real agent, not a chat wrapper— Bash, file I/O, code editing, and web access, driven by the Claude Agent SDK - 📱 Your machine, your phone— code and secrets never leave your computer; you just drive it from Telegram - 👥 Team-ready— per-user sandboxing, owner approvals, and one parallel session per forum topic - 🎙 Voice in, voice out— talk to your codebase and hear it answer back - 🔌 Delegate & forget— hand a task to an autonomousPaperclipagent and get the finished result (with docs, links, and follow-up questions) pushed back to Telegram

If Hasharot looks useful, star the repo— it helps others find it and it genuinely makes our day.

| |

Already using a coding agent (Claude Code, Cursor, Codex, …)? Just paste this one line into it — the agent does the whole setup and only asks you for a bot token and your Telegram ID:

Fetch https://raw.githubusercontent.com/Mamasodikov/hasharot/main/docs/AGENT_SETUP.md and follow it to set up Hasharot on this machine.

Prefer doing it by hand? Continue below.

Requirement Notes
Node.js 22+
with npm
Claude Code CLI
installed and authenticated — claude in your PATH
Telegram bot token
from

Your Telegram user ID@userinfobot

git clone https://github.com/Mamasodikov/hasharot.git
cd hasharot
cp .env.example .env

Edit .env

:

TELEGRAM_BOT_TOKEN=your_bot_token
ALLOWED_USER_IDS=your_user_id
OWNER_USER_ID=your_user_id     # you = admin (approvals, /access, /answer_policy)
npm install
npm run dev        # dev mode with hot reload

Open your bot in Telegram → /start

Command Description
/start
Welcome message
/project
Set working directory (interactive picker)
/newproject <name>
Create and switch to a new project
/default [off]
Show or clear this chat's default project
/clear
Clear conversation + session
/status
Current session info
/sessions
List saved sessions
/resume
Pick from recent sessions
/continue
Resume most recent session
/teleport
Move session to terminal (forked)
Command Description
/plan
Plan mode for complex tasks
/explore
Explore codebase to answer questions
/loop
Run iteratively until task complete
/model
Switch Sonnet / Opus / Haiku
/provider
Switch AI provider (Claude / OpenCode)
/mode
Toggle streaming / wait
/terminalui
Toggle terminal-style display
Command Description
/access
List pending / approved / blocked users
/allow_user
Whitelist a user + open permission/folder setup
/permissions
Set a user's permissions & folders
/sandbox_folder
Multi-select folders to sandbox a user
/answer_policy
Configure when the bot answers (alias / reply / @mention, or everything)
/approval_timeout
How long approval requests wait — 5m…3h presets or ♾️ unlimited
/deny_user
Deny a request or revoke access
/block_user
Hard-block a user (bot ignores them completely)
Command Description
/reddit
Fetch Reddit posts, subreddits, profiles
/vreddit
Download Reddit-hosted videos
/medium
Fetch Medium articles via Freedium
/file
Download a project file
/telegraph
Toggle Instant View for long responses
/extract <url>
Download media from YouTube, TikTok, Instagram
Command Description
/tts
Toggle voice replies, pick voice
/transcribe
Transcribe audio to text
Send voice note
Auto-transcribed → processed by Claude
Command Description
/ping
Health check
/context
Show Claude context / token usage
/botstatus
Bot process status
/restartbot
Restart the bot
/cancel
Cancel current request
/commands
Show all commands
/softreset
Soft reset (cancel + clear session)

Hasharot is built for hashar — many people getting work done together. The core primitive is Telegram forum Topics: in a supergroup with Topics enabled, every topic runs as a fully independent session with its own project, model, and conversation memory. Zero configuration needed.

  🏠 General      — announcements, coordination (bot stays quiet unless addressed)
  🎨 Frontender   — pinned to the frontend project
  ⚙️ Backender    — pinned to the backend project
  🚀 DevOps       — pinned to infra / deploy scripts
  🧪 QA           — pinned to the test suite

Create a topic for each role or workstream (Frontender, Backender, DevOps, …).Pin a project inside each topic with/project

(or set it once with/default

) — the topic remembers it.Work in parallel— a long-running task in the Backender topic never blocks or pollutes the Frontender topic's context. Each teammate talks to the agent in their own lane.Sandbox teammates(owner) — grant each user their own folder with/sandbox_folder

, so the Frontender can only touch the frontend project even if they wander into another topic.

Tip:keep one "General" topic un-pinned for coordination. By default the bot stays silent in group chats until directly addressed — by an alias name, a reply to its message, or an @mention. The owner tunes all of this live with: toggle each trigger on/off, add/remove alias names, or switch to answer-everything mode (with a warning — it will reply to normal human conversation too)./answer_policy

Today the cleanest pattern is one topic per person per project (e.g. myapp — Alice

, myapp — Bob

) — each gets an independent session over the same folder. True parallel editing isolation is on the roadmap below.

**Reddit — **/reddit

& /vreddit

/reddit

& /vreddit

/reddit

is now a pure TypeScript module using Reddit's OAuth2 API directly — no external Python dependency.

REDDIT_CLIENT_ID=your_client_id
REDDIT_CLIENT_SECRET=your_client_secret
REDDIT_USERNAME=bot_account
REDDIT_PASSWORD=bot_password

Create a "script" app at https://www.reddit.com/prefs/apps/. Use a dedicated bot account — NOT your personal credentials. Video downloads need ffmpeg

and ffprobe

on your PATH.

**Medium — **/medium

/medium

Pure TypeScript via Freedium mirror — no extra dependencies.

FREEDIUM_HOST=freedium-mirror.cfd
MEDIUM_TIMEOUT_MS=15000

Voice Transcription — Groq Whisper

GROQ_API_KEY=your_groq_key
GROQ_TRANSCRIBE_PATH=/absolute/path/to/groq_transcribe.py

Text-to-Speech — OpenAI TTS

OPENAI_API_KEY=your_openai_key
TTS_MODEL=gpt-4o-mini-tts
TTS_VOICE=coral
TTS_RESPONSE_FORMAT=opus

13 voices available: alloy

, ash

, ballad

, cedar

, coral

, echo

, fable

, marin

, nova

, onyx

, sage

, shimmer

, verse

All config lives in .env

. See .env.example for the full annotated reference.

Variable Description
TELEGRAM_BOT_TOKEN
Bot token from @BotFather
ALLOWED_USER_IDS
Comma-separated Telegram user IDs
Variable Default Description
ANTHROPIC_API_KEY
API key (optional with Claude Max subscription)
WORKSPACE_DIR
$HOME
Root directory for project picker
CLAUDE_EXECUTABLE_PATH
claude
Path to Claude Code CLI
BOT_NAME
Hasharot
Bot name in system prompt
STREAMING_MODE
streaming
streaming or wait
DANGEROUS_MODE
false
Auto-approve all tool permissions
CANCEL_ON_NEW_MESSAGE
false
Auto-cancel running query on new message
CLAUDE_SDK_LOG_LEVEL
off
SDK log level: off, basic, verbose, trace
Variable Default Description
REDDIT_CLIENT_ID
Reddit OAuth2 client ID
REDDIT_CLIENT_SECRET
Reddit OAuth2 client secret
REDDIT_USERNAME
Reddit bot account username
REDDIT_PASSWORD
Reddit bot account password
REDDIT_VIDEO_MAX_SIZE_MB
50
Max video size before compression
REDDITFETCH_TIMEOUT_MS
30000
Execution timeout
REDDITFETCH_JSON_THRESHOLD_CHARS
8000
Auto-switch to JSON output
Variable Default Description
FREEDIUM_HOST
freedium-mirror.cfd
Freedium mirror host
MEDIUM_TIMEOUT_MS
15000
Fetch timeout
MEDIUM_FILE_THRESHOLD_CHARS
8000
File save threshold
Variable Default Description
EXTRACT_ENABLED
true
Enable /extract command
YTDLP_COOKIES_PATH
Netscape cookies.txt for yt-dlp
Variable Default Description
GROQ_API_KEY
Groq API key for Whisper
GROQ_TRANSCRIBE_PATH
Path to groq_transcribe.py
OPENAI_API_KEY
OpenAI API key for TTS
TTS_VOICE
coral
Default TTS voice
TTS_MODEL
gpt-4o-mini-tts
TTS model
VOICE_SHOW_TRANSCRIPT
true
Show transcript text before agent response
src/
├── bot/
│   ├── bot.ts                     # Bot setup, handler registration
│   ├── handlers/
│   │   ├── command.handler.ts     # All slash commands + inline keyboards
│   │   ├── message.handler.ts     # Text routing, ForceReply dispatch
│   │   ├── voice.handler.ts       # Voice download, transcription, agent relay
│   │   └── photo.handler.ts       # Image save + agent notification
│   └── middleware/
│       ├── auth.middleware.ts      # User whitelist + group chat auth
│       └── stale-filter.ts        # Ignore stale messages on restart
├── claude/
│   ├── agent.ts                   # Claude Agent SDK, session resume, system prompt
│   ├── mcp-tools.ts              # MCP server: Reddit, Medium, Extract, Telegraph tools
│   ├── session-manager.ts         # Per-chat session state
│   ├── session-history.ts         # Session persistence and history
│   ├── request-queue.ts           # Sequential request queue
│   ├── command-parser.ts          # Help text + command descriptions
│   └── agent-watchdog.ts          # Watchdog for long-running agent tasks
├── reddit/
│   ├── redditfetch.ts             # Native TypeScript Reddit client (OAuth2)
│   └── vreddit.ts                 # Reddit video download + compression pipeline
├── medium/
│   └── freedium.ts                # Freedium article fetcher
├── media/
│   └── extract.ts                 # YouTube/TikTok/Instagram extraction (yt-dlp)
├── telegram/
│   ├── message-sender.ts          # Streaming, chunking, Telegraph routing
│   ├── markdown.ts                # MarkdownV2 escaping
│   ├── telegraph.ts               # Telegraph Instant View client
│   ├── telegraph-settings.ts      # Per-chat Telegraph toggle
│   ├── terminal-renderer.ts       # Terminal-style UI renderer
│   ├── terminal-settings.ts       # Per-chat terminal UI toggle
│   └── deduplication.ts           # Message dedup
├── tts/
│   ├── tts.ts                     # TTS provider routing (Groq Orpheus / OpenAI)
│   ├── tts-settings.ts            # Per-chat voice settings
│   └── voice-reply.ts             # TTS hook for agent responses
├── audio/
│   └── transcribe.ts              # Shared transcription utilities
├── utils/
│   ├── download.ts                # URL download with SSRF protection
│   ├── sanitize.ts                # Path and error sanitization
│   ├── workspace-guard.ts         # Workspace boundary enforcement
│   ├── url-guard.ts               # URL validation (protocol, SSRF)
│   ├── file-type.ts               # File content validation
│   ├── caffeinate.ts              # macOS sleep prevention
│   ├── session-key.ts             # Session key generation (DM + forum topics)
│   ├── agent-timer.ts             # Agent execution timing
│   └── debug-agent.ts             # Debug utilities
├── config.ts                      # Zod-validated environment config
└── index.ts                       # Entry point

The agent's context is assembled from five layers on every query (see agent.ts

):

# Layer Source Notes
1 Claude Code preset
Agent SDK (preset: 'claude_code' )
The same base system prompt as terminal Claude Code — Hasharot is a full agent, not an API wrapper
2 Bot prompt (static)
agent.ts + conduct.ts
Persona guidelines, Telegram/Telegraph output formatting, access-model conduct rules, MCP tool usage hints
3 SYSTEM_PROMPT_FILE
Path set in .env
Optional identity/memory file appended to every query. Re-read on change (mtime-cached) — edit it and the next message already uses it, no restart
4 Speaker prompt (dynamic)
Built per message Who is talking right now: name, group note, and their real access level (owner / sandboxed + folders / trusted)
5 Claude Code memories
settingSources: ['project', 'user']
✅ Standard CLAUDE.md support — see below

Project memory— theCLAUDE.md

(and.claude/

settings) of theopened project folder is loaded automatically. Every project carries its own memory: open~/projects/myapp

andmyapp/CLAUDE.md

is in context for that chat.User memory~/.claude/CLAUDE.md

(the machine owner's global memory) is loaded in every session.Conversation memory— sessions live in Claude Code's own session store;/continue

and/resume

restore the full history, and the working project is remembered per chat.

Tip:put project-specific instructions in that project'sCLAUDE.md

(picked up instantly per chat), and bot-wide personality/rules in theSYSTEM_PROMPT_FILE

— both apply without restarting the bot.

npm run dev          # Dev mode with hot reload (tsx watch)
npm run typecheck    # Type check only
npm run build        # Compile to dist/
npm start            # Run compiled build
./scripts/hasharot-botctl.sh dev start      # Start dev mode
./scripts/hasharot-botctl.sh dev restart     # Restart dev
./scripts/hasharot-botctl.sh prod start      # Start production
./scripts/hasharot-botctl.sh dev log         # Tail logs
./scripts/hasharot-botctl.sh dev status      # Check if running

If Hasharot is editing its own codebase, use prod mode to avoid hot-reload restarts:

./scripts/hasharot-botctl.sh prod start      # No hot reload
./scripts/hasharot-botctl.sh prod restart     # Apply changes

Then /continue

or /resume

in Telegram to restore your session.

Prod runs compiled code.prod start

/restart

builds (tsc

) first, so a restart always reflects the current source — a build error fails fast instead of serving a staledist/

.

For a bot that survives crashes and reboots, install the LaunchAgent template:

cp scripts/com.hasharot.bot.plist.example ~/Library/LaunchAgents/com.hasharot.bot.plist
npm run build
launchctl load ~/Library/LaunchAgents/com.hasharot.bot.plist

KeepAlive=true

restarts the process on exit; RunAtLoad

starts it at login. Without a supervisor the bot stays down after a crash or reboot until manually restarted.

All state lives in ~/.hasharot

(access grants + per-user sandbox paths, sessions, settings). It's a single copy on one disk — losing access-control.json

silently revokes every approved teammate. Back it up (Time Machine covers it, or tar czf hasharot-backup.tgz ~/.hasharot

).

User whitelist— only approved Telegram IDs can interact; the owner (OWNER_USER_ID

) approves everyone elsePer-user sandbox— restricted users are jailed to an owner-granted folder allowlist, captured per-query (revoking mid-query can't loosen it); every file and shell op is path-checked withsymlink resolution, and interpreters (python -c

,node -e

, …) and hidden-path escapes (--output=/etc/x

) are routed to owner approvalOwner approval flow— destructive or out-of-sandbox operations and ask the owner with Allow / Deny buttons, a clear** why**line (sandbox escape, destructive command, interpreter, …), and a live ⏳ countdown; posted both in the originating chat and the owner's DM — deciding in either place closes both. Timeout configurable via/approval_timeout

(presets or unlimited)Env isolation— the bot's own secrets (bot token, API keys) are stripped from the agent subprocess environment** Crash safety**— process-level handlers + inactivity watchdog free a wedged chat; atomic writes protect every JSON store** Dangerous mode**— opt-in auto-approve for all tool permissions (disables the above — use only on a fully trusted single-user box)** Secrets**— loaded from.env

(gitignored), never committed

Note on the shell sandbox:the restricted-user Bash gate is best-effort defense-in-depth (lexical inspection + owner approval), not a kernel jail — the whole bot runs as your user. For hostile users, run Hasharot itself inside a container/VM. For a trusted team sharing one machine, the sandbox + approval flow is the intended boundary.

Doc What's inside
docs/AGENT_SETUP.md

docs/ACCESS_CONTROL.md

docs/UI_BEHAVIOR.md

.env.example

Multi-user collaboration lands incrementally — each step only when the previous one hits its limits:

Topics — parallel sessions*(works today, zero setup)Every forum topic is an independent session. Per-role topics (Frontender, Backender, …) give a team parallel lanes with no code changes. - Busy-fork(next up)When a shared project session is busy with someone else's query, show a*"Fork"** button that branches a personal session from the shared context. Better than blanket per-user sessions: the main team context stays intact, and the fork inherits everything up to that point. - Worktree isolation*(when truly needed)Per-user git worktrees so two people canwrite code in the same reposimultaneously without stepping on each other's working tree. Only worth the complexity once "two devs, one repo, same time" is a real daily need. - OS-level command jail(only if hosting untrusted users)*Today the restricted-user shell gate is best-effort (lexical inspection + owner approval), not a kernel jail — see the Security note above. If Hasharot ever needs to host genuinely untrusted users, run each restricted command inside a real sandbox (sandbox-exec

on macOS,bwrap

/container on Linux) with the allowlist bind-mounted, instead of validating the command string. Larger architectural change; not needed for a trusted team sharing one machine.

Hasharot 🐜 — ishlaringizni hashar qilib bitiring.

If this project is useful to you, consider giving it a ⭐

Originally based on claudegram by NachoSEO.

── more in #ai-agents 4 stories · sorted by recency
── more on @hasharot 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/hasharot-control-a-c…] indexed:0 read:14min 2026-07-11 ·