Your own personal AI assistant that runs 24/7 on your Mac. Powered by Claude Agent SDK + your Max subscription. $0 API costs.
A persistent, multimodal AI assistant that runs on your own hardware as a macOS daemon. Chat through Telegram with voice, images, and text. Manage scheduled tasks through a web dashboard. Let it work autonomously while you sleep.
Built on the Claude Agent SDK — authenticates via OAuth with your existing Claude Max subscription. No API keys, no per-token billing, no surprise costs. If you're already paying for Max, psibot is effectively free to run.
How is this different from OpenClaw? OpenClaw is a general-purpose AI assistant framework. psibot is purpose-built for a single user running Claude on their own Mac — optimized for Telegram, designed as an always-on daemon, and requires zero API spend beyond your existing Max plan.
$0 API Costs — Uses your Claude Max subscription via OAuth. No API keys, no per-token billing. Run Opus, Sonnet, and Haiku across all agents at no additional cost.
Always-On Daemon — Runs as a macOS LaunchAgent. Survives reboots, handles wake/sleep cycles, stays connected to Telegram 24/7, and runs autonomous tasks on a schedule.
Telegram-Native — First-class Telegram bot with voice messages, photo understanding, text-to-speech replies, and inline command menus. Not a web wrapper — a real bot experience.
Multimodal AI — Generates and edits images (Gemini), speaks with a neural voice (Edge TTS), transcribes voice messages (parakeet STT), and analyzes YouTube videos with semantic search.
Persistent Memory — Maintains knowledge files, daily logs, and structured memory across sessions. Learns about you over time and remembers context between conversations.
Autonomous Subagents — Spawns specialized agents: a coder (isolated git worktrees), a researcher (browser automation), an image generator, and an audio processor — each on the optimal model.
Scheduled Tasks — Cron-based job scheduling with budget controls. Periodic maintenance, reminders, or any recurring prompt with configurable quiet hours.
MCP Tool Ecosystem — Extensible via Model Context Protocol servers. Built-in tools for memory, browser automation, Telegram media, git worktrees, YouTube analysis, and more.
Web Dashboard — HTMX + SSE streaming interface for real-time chat, job management, memory browsing, and log viewing.
🎨 Image Editing |
🌐 Browser Automation |
🔊 Agentic Audio |
|---|---|---|
| Generate • Edit • Send | Navigate • Read • Research | Transcribe • Speak • Listen |
Most AI agent frameworks (OpenClaw, nanobot, etc.) require API keys and charge per-token. If you're already paying for Claude Max, that's wasted money. psibot takes a different approach:
| API-based agents | psibot (Max subscription) | |
|---|---|---|
| Authentication | API key management | OAuth via claude CLI |
| Cost model | Pay per token | Fixed monthly subscription |
| Bill risk | Uncapped, usage-dependent | Zero additional cost |
| Model access | Depends on tier/budget | Opus, Sonnet, Haiku — all included |
| Setup | Generate keys, set budgets, monitor spend | claude login and go |
- macOS (Apple Silicon or Intel)
- Xcode Command Line Tools (
xcode-select --install) - Claude CLI (
npm install -g @anthropic-ai/claude-code) — authenticated withclaude login - A Telegram bot token
The setup script handles everything from a fresh clone: Homebrew, Bun, dependencies, .env configuration, CLI linking, and daemon installation.
git clone https://github.com/DmacMcgreg/psibot.git
cd psibot
bash scripts/setup.shThe script will:
- Install Homebrew (if missing), then
bun,sqlite, andyt-dlp - Install
uv(Python tool runner) - Run
bun installfor node packages - Create
.envfrom template and prompt for your Telegram bot token and user IDs - Link the
psibotCLI and install the macOS LaunchAgent daemon - Optionally install
edge-tts,mlx-audio, andtailscale
After setup, start the daemon:
psibot startTo fully remove psibot (daemon, CLI, and optionally data/dependencies):
bash scripts/uninstall.shIf you prefer to set things up manually
git clone https://github.com/DmacMcgreg/psibot.git
cd psibot
bun install
bun link # Makes the 'psibot' command available globallycp .env.example .envEdit .env with your settings:
TELEGRAM_BOT_TOKEN=123456:ABC-DEF...
ALLOWED_TELEGRAM_USER_IDS=123456789
PORT=3141
DEFAULT_MODEL=claude-opus-4-6# Development (with hot reload)
bun run dev
# Production
bun run startpsibot install # Install LaunchAgent
psibot start # Start the daemon
psibot status # Check status
psibot logs # Tail logs| Tool | Purpose | Install |
|---|---|---|
| uv | Python tool runner for audio tools | curl -LsSf https://astral.sh/uv/install.sh | sh |
| mlx-audio | STT (parakeet) on Apple Silicon | uv tool install mlx-audio |
| edge-tts | Text-to-speech via Microsoft Edge neural voices | pip install edge-tts |
| Gemini API key | Image generation via Gemini | Set GEMINI_API_KEY in .env |
| Tailscale | Remote access to web dashboard + Funnel for webhooks + Wake-on-LAN packets | Install from tailscale.com/download |
| Variable | Default | Description |
|---|---|---|
TELEGRAM_BOT_TOKEN |
(required) | Telegram bot API token |
ALLOWED_TELEGRAM_USER_IDS |
(required) | Comma-separated authorized user IDs |
PORT |
3141 |
Web dashboard port |
DEFAULT_MODEL |
claude-opus-4-6 |
Model for the main agent |
DEFAULT_MAX_BUDGET_USD |
1.00 |
Max cost per agent run |
HEARTBEAT_ENABLED |
true |
Enable periodic autonomous heartbeat |
HEARTBEAT_INTERVAL_MINUTES |
30 |
Minutes between heartbeats |
HEARTBEAT_QUIET_START |
23 |
Quiet hours start (hour, 24h) |
HEARTBEAT_QUIET_END |
8 |
Quiet hours end (hour, 24h) |
HEARTBEAT_MAX_BUDGET_USD |
0.50 |
Max cost per heartbeat run |
PSIBOT_DIR |
~/.psibot |
Worktree and repo storage |
YOUTUBE_CLIENT_ID |
(optional) | Google OAuth client ID for YouTube |
YOUTUBE_CLIENT_SECRET |
(optional) | Google OAuth client secret |
YOUTUBE_SOURCE_PLAYLIST_ID |
(optional) | Playlist to process videos from |
YOUTUBE_DESTINATION_PLAYLIST_ID |
(optional) | Playlist to move processed videos to |
GEMINI_API_KEY |
(optional) | Gemini API key for image gen + video embeddings |
For reliable message delivery through network changes and sleep/wake cycles, enable webhook mode via Tailscale Funnel:
TELEGRAM_WEBHOOK_ENABLED=true
TELEGRAM_WEBHOOK_HOST=your-machine.tailnet-name.ts.net
TELEGRAM_WEBHOOK_PORT=8443psibot can analyze YouTube videos — extracting transcripts, generating structured summaries with Claude, and storing vector embeddings for semantic search. Transcripts are pulled via yt-dlp (no API quota), while playlist management uses the YouTube Data API via OAuth.
- Go to Google Cloud Console
- Create a project (or select an existing one)
- Enable the YouTube Data API v3 under APIs & Services > Library
- Go to APIs & Services > Credentials > Create Credentials > OAuth client ID
- Application type: Web application
- Add an authorized redirect URI:
- With Tailscale Funnel:
https://your-machine.tailnet-name.ts.net/auth/youtube/callback - Local only:
http://127.0.0.1:3141/auth/youtube/callback(use yourPORTvalue)
- With Tailscale Funnel:
- Copy the Client ID and Client Secret
If your app is in "Testing" mode on the OAuth consent screen, add your Google account as a test user.
YOUTUBE_CLIENT_ID=your-client-id.apps.googleusercontent.com
YOUTUBE_CLIENT_SECRET=your-client-secret
GEMINI_API_KEY=your-gemini-key # Required for vector embeddingsWith psibot running, ask the agent to start YouTube OAuth setup (or use the youtube_oauth_setup tool). It will return a Google authorization URL. Open it in your browser, grant access, and the callback saves tokens to ~/.psibot/youtube-oauth.json. Tokens auto-refresh; you only need to do this once.
Playlist IDs are the string after list= in a YouTube playlist URL:
https://www.youtube.com/playlist?list=PLxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This is the playlist ID
Add them to .env:
YOUTUBE_SOURCE_PLAYLIST_ID=PLxxxxx # Videos to process (e.g. "Watch Later")
YOUTUBE_DESTINATION_PLAYLIST_ID=PLyyyyy # Where processed videos are movedThe agent processes videos from the source playlist, analyzes them, and moves them to the destination. You can also analyze individual videos by URL without any playlist configuration.
| Tool | Description |
|---|---|
youtube_summarize |
Analyze a single video by URL or ID |
youtube_search |
Semantic search across all stored video analyses |
youtube_list |
List stored videos with keyword/channel filters |
youtube_get |
Get full analysis for a specific video |
youtube_process_playlist |
Batch-process videos from source playlist |
youtube_playlist_status |
Show processing stats and pending videos |
| Command | Description |
|---|---|
/ask <prompt> |
Send a message to the agent |
/jobs |
List scheduled jobs |
/memory |
Browse agent memory |
/status |
Show system status |
/verbose |
Toggle tool call feedback |
Send voice messages for automatic transcription and response. Send photos with optional captions for image-aware conversations.
src/
index.ts # Entry point
config.ts # Zod-validated env config
agent/
index.ts # AgentService (query with MCP + subagents)
tools.ts # agent-tools MCP server
media-tools.ts # media-tools MCP server
subagents.ts # Subagent definitions
prompts.ts # System prompt builder
telegram/
index.ts # Bot setup + auth middleware
commands.ts # Command & media handlers
format.ts # Message formatting
webhook.ts # Webhook mode (Tailscale Funnel)
web/
index.ts # Hono app + IP allowlist
routes/ # Chat, jobs, memory, logs
views/ # HTMX templates
heartbeat/
index.ts # Periodic autonomous tasks
scheduler/
index.ts # Cron + one-off job scheduling
executor.ts # Job execution via agent
memory/
index.ts # Knowledge files, search, daily logs
browser/
index.ts # Browser automation wrapper
db/
index.ts # SQLite (WAL mode)
schema.ts # Migrations
queries.ts # Prepared statements
shared/
types.ts # Type definitions
logger.ts # Timestamped logging
knowledge/
IDENTITY.md # Agent persona
USER.md # Learned user context
TOOLS.md # Tool documentation
HEARTBEAT.md # Maintenance task definitions
memory.md # Persistent memory
memory/ # Daily logs
data/
app.db # SQLite database
images/ # Generated images
audio/ # TTS output
media/ # Inbound Telegram media
| Component | Technology |
|---|---|
| Runtime | Bun |
| Agent | @anthropic-ai/claude-agent-sdk |
| Bot | grammy |
| Web | Hono + HTMX + SSE |
| Database | SQLite (bun:sqlite, WAL mode, FTS) |
| Scheduling | croner |
| Validation | Zod |
| Image Gen | Gemini API |
| TTS | Edge TTS (Sonia British neural voice) |
| STT | parakeet (via mlx-audio) |
| Browser | agent-browser |
- macOS Full Disk Access: If the project lives in
~/Documents(or~/Desktop,~/Downloads), Bun needs Full Disk Access. Grant it in System Settings > Privacy & Security > Full Disk Access, then add the Bun binary (typically/opt/homebrew/bin/bun). Without this, the daemon will fail with TCC permission errors. - mlx-audio PATH:
uv tool install mlx-audioplaces commands in~/.local/bin/. The launcher script includes this in PATH automatically, but your interactive shell also needs it —uvadds it to your shell profile during installation. - LaunchAgent quirk: The launcher script uses
bun --cwdinstead of plistWorkingDirectoryto avoid a Bungetcwd()deadlock under launchd - PATH for launchd: The launcher exports
~/.local/binand/opt/homebrew/bin— needed for mlx-audio commands and theclaudeCLI (Agent SDK OAuth)
Inspired by OpenClaw and nanobot. psibot started as an experiment to see how far you could push the Claude Agent SDK with just a Telegram bot and a Max subscription.
MIT



