Lightweight multi-agent framework for personal AI assistants
Project description
smolclaw
Lightweight multi-agent framework for personal AI assistants
Run multiple AI agents — each with its own personality, skills, and channels — from a single process. Agents are defined as folders with markdown files. No code required.
Not another enterprise orchestration framework. smolclaw is for people who want a personal AI assistant that runs on their laptop — not a distributed system that needs a DevOps team. ~10 modules, filesystem-as-config, zero boilerplate.
Features
- Filesystem-as-config — Drop a folder, get an agent.
soul.mdfor personality,agent.yamlfor model/channels,skills/for capabilities. - Single gateway process — All agents, channels, scheduler, and API run in one async process. No microservices, no Docker, no infra.
- Telegram integration — Each agent gets its own Telegram bot with typing indicators, markdown rendering, and user authorization.
- Webhook delivery — POST agent responses to any HTTP endpoint (Slack incoming webhooks, Discord, custom APIs). Zero dependencies.
- Extensible channels — Register custom channel adapters via
register_channel()or distribute them as plugins via entry points. Third-party packages just work. - Cron scheduler — Schedule jobs with cron expressions, deliver results to Telegram. Jobs route through the same message bus as everything else.
- Semantic memory — Shared SQLite database with per-agent isolation, FTS5 full-text search, and optional vector search via sqlite-vec with hybrid retrieval (RRF).
- Hot-reload — Change a skill, soul, or config file and the agent updates live. No restart needed.
- Interactive REPL —
smolclaw chat <agent>for terminal conversations with session persistence. - MCP support — Connect agents to MCP servers (stdio/SSE/HTTP) for extended tool access.
- REST API + dashboard — FastAPI on
:7890with agent management, messaging, optional API key auth, and a built-in dark-mode dashboard. - OpenTelemetry tracing — Optional OTEL instrumentation for routing, LLM calls, memory, and cron. Zero overhead when disabled.
pip install smolclaw[otel]. - Claude SDK powered — Built on Anthropic's Claude Agent SDK with session management, extended thinking, and tool support.
Quick Start
# With uv (recommended)
uv pip install smolclaw
# Or with pip
pip install smolclaw
smolclaw init --agent tars
# Edit ~/.smolclaw/agents/tars/soul.md — give your agent a personality
smolclaw up
This creates a full project at ~/.smolclaw/ with your first agent and starts the gateway. The API + dashboard will be at http://localhost:7890.
How Agents Work
Each agent is a folder:
~/.smolclaw/agents/tars/
├── agent.yaml # Model, channels, memory config
├── soul.md # Personality & voice
├── agents.md # Operational rules & tool access
├── skills/ # Folder per skill (or symlinks to shared/)
├── context/ # Extra .md files loaded into system prompt
├── channels/ # Channel credentials (*.env files)
└── prompts/ # Templates for scheduled jobs
The system prompt is assembled automatically from these files. With hot-reload enabled, changes take effect immediately — no restart needed.
Example agent.yaml
name: tars
model: claude-opus-4-6
max_budget_usd: 5.0 # Per-run spending limit
fallback_model: claude-sonnet-4-6 # Used if primary model unavailable
enable_file_checkpointing: true # Crash recovery
channels:
telegram:
token_env: TARS_TELEGRAM_TOKEN
authorized_users: []
memory:
enabled: true
cross_agent: true
Example soul.md
# TARS
You are TARS, a personal virtual assistant. Inspired by Interstellar.
## Voice & Tone
- Humor setting: 60%
- Concise and direct. No filler.
- Dry humor when appropriate.
Why smolclaw?
| smolclaw | CrewAI | LangGraph | OpenAI Agents SDK | |
|---|---|---|---|---|
| Setup | pip install + folder |
pip install + code |
pip install + code |
pip install + code |
| Config | Markdown files | Python classes | Python code | Python decorators |
| Agents defined as | Folders with .md files |
Python code | Graph nodes | Python classes |
| Multi-model | Per-agent model selection | Per-agent | Per-node | OpenAI only |
| Channels | Telegram built-in, API | No built-in | No built-in | No built-in |
| Scheduler | Built-in cron | No built-in | No built-in | No built-in |
| Dashboard | Built-in | Studio (paid) | LangSmith (paid) | No built-in |
| Memory | Built-in SQLite | External | External | External |
| Code size | ~6300 lines | ~15K+ lines | ~25K+ lines | ~5K+ lines |
| Focus | Personal assistant | Enterprise teams | Workflows | General agents |
smolclaw is opinionated: one process, filesystem-as-config, batteries-included. If you want a personal AI assistant that just works — start here.
Architecture
Gateway (single process)
├── Agent: tars (Opus, Telegram, cross-agent memory)
├── Agent: coach (Sonnet, no channel, isolated memory)
├── Scheduler (croniter, fires through router)
├── Hooks (pre/post-route middleware)
├── FileWatcher (hot-reload on config/skill changes)
├── API (FastAPI :7890, serves dashboard)
└── Router (any source → correct agent → response)
All messages — whether from Telegram, the API, the CLI, or the scheduler — flow through the same router.
CLI
smolclaw init # Initialize project (first run)
smolclaw up # Start gateway (all agents + API)
smolclaw chat <agent> # Interactive REPL with session persistence
smolclaw status # Show agents, jobs, config, issues
smolclaw doctor # Check system health and dependencies
smolclaw add <name> # Scaffold a new agent
smolclaw remove <name> # Remove an agent (with confirmation)
smolclaw list # List discovered agents
smolclaw send <agent> "message" # Send a one-shot message
smolclaw logs # Tail the gateway log file
smolclaw config # View gateway config
smolclaw config get <key> # Get a config value
smolclaw config set <key> <value> # Set a config value
smolclaw cron list # List scheduled jobs
smolclaw cron add \
--agent tars \
--schedule "0 8 * * 1-5" \
--prompt "morning briefing" \
--delivery telegram \
--chat-id 123456789 # Add a cron job with delivery
smolclaw cron edit <job_id> \
--schedule "0 9 * * 1-5" \
--prompt "updated prompt" # Edit an existing job
smolclaw cron run <job_id> # Manually trigger a job (for debugging)
smolclaw cron enable <job_id> # Enable a disabled job
smolclaw cron disable <job_id> # Disable a job without removing
smolclaw memory stats <agent> # Memory statistics
smolclaw memory list <agent> # List stored facts
smolclaw memory search <agent> "q" # Search memory
smolclaw memory add <agent> "fact" # Add a fact
smolclaw memory get <agent> <id> # Show a single fact
smolclaw memory update <agent> <id> \
--content "new text" -c category # Update a fact
smolclaw memory delete <agent> <id> # Delete a fact
smolclaw export <agent> # Export agent as portable .tar.gz
smolclaw import <archive> # Import agent from .tar.gz archive
smolclaw add-skill <agent> <skill> # Symlink shared skill to agent
smolclaw install # Auto-start on login (macOS LaunchAgent)
smolclaw version # Show version
REST API
The gateway exposes a full REST API on :7890 (auto-documented at /docs):
# Send a message
curl -s localhost:7890/api/agents/tars/send \
-H "Content-Type: application/json" \
-d '{"text": "What is the weather?"}' | jq .response
# Search agent memory
curl -s "localhost:7890/api/agents/tars/memory/search?q=weather&mode=hybrid"
# Add a fact to memory
curl -s localhost:7890/api/agents/tars/memory/facts \
-H "Content-Type: application/json" \
-d '{"content": "User prefers metric units", "category": "preference"}'
# Get / update / delete a fact
curl -s localhost:7890/api/agents/tars/memory/facts/1 | jq
curl -s -X PUT localhost:7890/api/agents/tars/memory/facts/1 \
-H "Content-Type: application/json" \
-d '{"content": "User prefers imperial units"}'
# List agents, health, cron jobs
curl -s localhost:7890/api/agents | jq
curl -s localhost:7890/api/health | jq
curl -s localhost:7890/api/cron/jobs | jq
API Authentication
Protect your API with an optional Bearer token. Add api_key to your config.yaml:
# ~/.smolclaw/config.yaml
api_key: "your-secret-key-here"
Then include the key in requests:
curl -s localhost:7890/api/agents \
-H "Authorization: Bearer your-secret-key-here" | jq
Health (/api/health) and dashboard (/) are always public. When no api_key is set, all endpoints are open (default).
Dashboard
A built-in dark-mode dashboard runs at http://localhost:7890 when the gateway starts. Shows agent status, config, and lets you send messages.
The dashboard uses WebSocket live updates — changes to agents, jobs, and memory are pushed instantly to all connected browsers. Falls back to 10-second polling automatically if WebSocket is unavailable.
Custom Channels
smolclaw supports three ways to add channel adapters:
1. Programmatic registration
from smolclaw.channel import Channel, register_channel
class WhatsAppChannel(Channel):
channel_type = "whatsapp"
async def start(self): ...
async def stop(self): ...
async def send(self, chat_id: str, text: str): ...
register_channel("whatsapp", WhatsAppChannel)
2. Entry-point plugins
Third-party packages declare channel adapters in their pyproject.toml:
[project.entry-points."smolclaw.channels"]
whatsapp = "smolclaw_whatsapp:WhatsAppChannel"
Once installed, the channel is automatically available in agent.yaml:
channels:
whatsapp:
token_env: WHATSAPP_TOKEN
authorized_users: ["+46701234567"]
3. Built-in channels
telegram and webhook are included out of the box.
Development
git clone https://github.com/mandgie/smolclaw.git
cd smolclaw
# With uv (recommended — fast, handles venv automatically)
uv sync --extra dev
uv run pytest
uv run ruff check smolclaw/
# Or with pip
python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
pytest
ruff check smolclaw/
ruff format --check smolclaw/
Project Structure
smolclaw/ # Python package (~6300 lines)
├── gateway.py # Single-process orchestrator
├── agent.py # Agent class (loads identity, wraps Claude SDK)
├── router.py # Message routing
├── channel.py # Channel adapters (Telegram, Webhook)
├── hooks.py # Pre/post-route message hooks (middleware)
├── memory.py # Namespaced SQLite memory (FTS5 + vector search)
├── scheduler.py # Cron scheduler (croniter)
├── tracing.py # Optional OpenTelemetry instrumentation
├── watcher.py # Hot-reload file watcher (watchfiles)
├── api.py # FastAPI REST endpoints
├── config.py # Filesystem-based agent discovery
├── cli.py # Click CLI
└── dashboard/
└── index.html # Single-file dashboard
Roadmap
- MCP server support (stdio/SSE/HTTP — Claude SDK managed)
- Extended thinking & effort config
- Budget limits, fallback models, structured output, file checkpointing
- REST API + dark-mode dashboard
- Cron scheduler with delivery to Telegram
- CLI: init, status, doctor, add, remove, add-skill, logs, install
- Session persistence (save/resume per agent per chat)
- CLI interactive REPL (
smolclaw chat <agent>) - Vector search in memory (sqlite-vec + FTS5 + RRF hybrid)
- Hot-reload on config/skill/context changes
- Cross-agent awareness (peer agents visible in prompts, API-based messaging)
- Multiple Telegram bots (one per agent, unique token per bot)
- Webhook channel (outgoing HTTP POST delivery)
- Discord / Slack channel adapters
- PyPI publish (v0.2.0 on PyPI)
Contributing
Contributions are welcome! See CONTRIBUTING.md for guidelines.
License
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file smolclaw-0.2.0.tar.gz.
File metadata
- Download URL: smolclaw-0.2.0.tar.gz
- Upload date:
- Size: 162.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ae0ab47436447f8530ca17949ebf80b2c934a070ac97929b4e93f7b7a323d9e1
|
|
| MD5 |
99ca3d968ef0d6ff3aaba573acc54974
|
|
| BLAKE2b-256 |
a1e561074b74a0373d9983fdfefea0fdd2246516f70454c00192c75619ba4207
|
Provenance
The following attestation bundles were made for smolclaw-0.2.0.tar.gz:
Publisher:
publish.yml on mandgie/smolclaw
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
smolclaw-0.2.0.tar.gz -
Subject digest:
ae0ab47436447f8530ca17949ebf80b2c934a070ac97929b4e93f7b7a323d9e1 - Sigstore transparency entry: 1148123673
- Sigstore integration time:
-
Permalink:
mandgie/smolclaw@2350816caede9b7f3ab4f2be8d4647a91026a1a9 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/mandgie
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@2350816caede9b7f3ab4f2be8d4647a91026a1a9 -
Trigger Event:
release
-
Statement type:
File details
Details for the file smolclaw-0.2.0-py3-none-any.whl.
File metadata
- Download URL: smolclaw-0.2.0-py3-none-any.whl
- Upload date:
- Size: 76.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e3d245734713f2e437a756cdf79afd7ac3a2c975870d9b4dfaacf8a711020986
|
|
| MD5 |
2fa7fe6c5f240db8e63b8171dcc50275
|
|
| BLAKE2b-256 |
f1925b2d14dd074dc580f91d7bf29d0777e5bc204fe4493496599a018b6aab33
|
Provenance
The following attestation bundles were made for smolclaw-0.2.0-py3-none-any.whl:
Publisher:
publish.yml on mandgie/smolclaw
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
smolclaw-0.2.0-py3-none-any.whl -
Subject digest:
e3d245734713f2e437a756cdf79afd7ac3a2c975870d9b4dfaacf8a711020986 - Sigstore transparency entry: 1148124041
- Sigstore integration time:
-
Permalink:
mandgie/smolclaw@2350816caede9b7f3ab4f2be8d4647a91026a1a9 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/mandgie
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@2350816caede9b7f3ab4f2be8d4647a91026a1a9 -
Trigger Event:
release
-
Statement type: