Minimalistic AI assistant with tool-calling, Telegram & CLI
Project description
๐ฆพ UnoClaw โ Minimalistic AI Assistant
SINGLE FILE. CONFIG-DRIVEN. SQLITE MEMORY.
UnoClaw is a lightweight, self-contained, single file AI agent that runs locally. It answers you on Telegram or via an interactive CLI. It connects to any OpenAI-compatible LLM (local or remote), manages a permanent SQLite memory, triggers its own background tasks, and exposes a set of sandboxed tools the model can call autonomously โ all in under 500 lines of Python (with ~60 of those being just comments and extra whitespace for readability)
Inspired by OpenClaw and the minimalist philosophy of NanoBot, we put a strong emphasis on simplicity and readability. Because the entire core logic lives in a single file, you can easily read it from top to bottom, hack it to your exact needs, or use it as a learning resource to understand how AI agents and tool-calling work under the hood.
Check it out if you want to play around with AI driven assistant that is highly hackable, requires zero external databases and lives in a single file.
GitHub Repository ยท Installation ยท Quick Start ยท Configuration ยท Extending & Tools ยท Security
Installation
Runtime: Python โฅ 3.10.
๐ Using uv (Recommended)
uv is the fastest way to install and manage unoclaw.
As a global tool with Telegram:
uv tool install unoclaw --with "unoclaw[telegram]"
As a global tool CLI only (no Telegram):
uv tool install unoclaw
From PyPI with Telegram
pip install "unoclaw[telegram]"
From PyPI without Telegram
pip install unoclaw
From Source (For Hacking/Development)
If you want to modify the code or contribute, we recommend using uv for a seamless experience:
git clone [https://github.com/2coderok/unoclaw.git](https://github.com/2coderok/unoclaw.git)
cd unoclaw
# Create environment and install all dependencies (including dev tools)
uv sync --all-extras
Alternatively, using standard pip:
git clone [https://github.com/2coderok/unoclaw.git](https://github.com/2coderok/unoclaw.git)
cd unoclaw
# Create a virtual environment
python -m venv .venv
source .venv/bin/activate # (Windows: .venv\Scripts\activate)
# Install in editable mode with Telegram and Dev support
pip install -e ".[telegram,dev]"
Quick start (TL;DR)
-
Configure: Copy the example config and add your llm endpoint/telegram settings.
cp config.example.json config.json
-
Run: Start the agent in your terminal using the conifg.
unoclaw --config path/to/your/config.json
UnoClaw will look for
config.jsonin current working directory if --config was not provided.
If you provided a telegram.token, it will start polling immediately. If omitted, it will drop you into the interactive CLI mode.
Highlights
- Agentic Scheduler โ Background loop triggers the LLM to autonomously perform scheduled prompts.
- SQLite Memory โ Seamless, permanent conversation and task storage without messy text files.
- Tool-calling โ The LLM can execute shell commands, read/write files, and fetch web pages.
- Telegram + CLI โ Runs as a Telegram bot; falls back to CLI when no token is configured.
- Workspace sandboxing โ Optionally restricts all file and command access to a single directory.
- Async tool dispatch โ Tool functions run in threads via
asyncio.to_thread().
Everything we built so far
Core platform
- Context trimming: Chat history is automatically trimmed by message count and token heuristics (
max_context_tokens,max_context_messages). - Config validation: Pydantic models validate
config.jsonat startup with clear error messages. - Agent Loop: Handles native tool-calling natively through the official OpenAI SDK structure.
Memory & Persistence
- Automatic Storage: Every time the LLM replies to the user, the exchange is automatically saved to the
memorySQLite table. - On-Demand Recall: When the user sends a new message, UnoClaw scans it for keywords, queries the database, and invisibly injects relevant historical memories directly into the LLM's system prompt.
Tools + automation
- Native Tools:
execute_command,read_file,write_file,read_web. - Task Management:
add_task,list_tasks,remove_task. - Agentic Cron: Unlike traditional schedulers, UnoClaw saves natural language prompts to the DB. When the timer hits zero, the background thread wakes up and messages the LLM:
[SYSTEM: AUTOMATED BACKGROUND TASK TRIGGERED]: <prompt>. The agent autonomously executes tools and sends you a message with the result.
How it works (short)
Telegram / CLI User
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ UnoClaw โโโโ config.json
โ (main.py) โ (API Keys, Settings, Tools)
โ [Memory & Scheduler loop] โ
โโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโ
โ โ
โ โโ Tools (Shell, Web, File I/O)
โ โโ SQLite DB (unoclaw.db)
โผ
OpenAI-Compatible LLM
Supported LLMs
Because UnoClaw uses the standard OpenAI SDK with a configurable base_url, it supports virtually any Large Language Model that exposes an OpenAI-compatible API endpoint.
This means you are not locked into a single provider. You can seamlessly switch between local open-source models and powerful cloud APIs just by changing two lines in your config.json.
Local Inference Engines (Free & Private)
If you have the hardware, you can run models entirely locally. Just point UnoClaw's base_url to your local server:
- Ollama:
http://localhost:11434/v1(Supports Llama 3, Qwen, Mistral, Phi, etc.) - LM Studio:
http://localhost:1234/v1 - vLLM:
http://localhost:8000/v1 - Llama.cpp (Server):
http://localhost:8080/v1 - Text-Generation-WebUI (Oobabooga):
http://localhost:5000/v1
Cloud API Providers
If you want to use hosted models, just paste your API key and their base URL into the config:
- OpenAI: GPT-4o, GPT-4-turbo, GPT-3.5
- Groq: Ultra-fast inference for open-source models (Llama 3, Mixtral)
- OpenRouter: Access to hundreds of models including Claude, Gemini, and DeepSeek through a single unified API.
- Together AI: Hosted open-source models.
- DeepSeek: Direct API access to DeepSeek models.
- Mistral API: Direct access to Mistral Large, Nemo, etc.
Minimum Model Requirements
To fully utilize UnoClaw's features, the model you choose must support Tool Calling (Function Calling).
- Recommended Open-Source: Qwen 2.5 (Instruct), Llama 3.1 (Instruct), or Mistral Nemo.
- Recommended Cloud: GPT-4o, Claude 3.5 Sonnet (via OpenRouter), or Groq-hosted Llama 3.1.
Configuration
Settings live in config.json. Missing required fields (like llm) will produce a clear validation error on startup.
{
"telegram": {
"token": "YOUR_BOT_TOKEN",
"allowed_usernames": ["your_handle"]
},
"llm": {
"base_url": "http://localhost:8088/v1",
"model": "qwen2.5-7b-instruct",
"api_key": "not-needed"
},
"workspace": {
"path": ".",
"restrict": true
},
"max_context_tokens": 8000,
"max_context_messages": 40
}
Context Limits & Soft Token Budgets
To prevent runaway API costs and context-window crashes, UnoClaw manages conversation history using a soft token budget:
max_context_tokens: UnoClaw estimates the token count of your active conversation. If it exceeds this limit, it automatically prunes the oldest messages (while always preserving your system prompts).max_context_messages: The absolute maximum number of back-and-forth messages kept in the active LLM context before older messages are trimmed.
Note: For the full schema, check config.example.json.
The System Prompt (AGENT.md & SKILLS.md)
UnoClaw builds its system prompt dynamically on startup by reading two markdown files from the docs/ directory. You can (and should) edit these to completely customize your assistant.
docs/AGENT.md (Core Personality & Rules)
This file defines who the agent is, its core rules, and its constraints. Use this file to set the agent's behavior:
- Personality: e.g., "You are a sarcastic but highly skilled DevOps engineer."
- Formatting Rules: e.g., "Always provide code snippets without markdown blocks."
- Environment Context: Tell the LLM what OS it is running on! Add a line like
You are running on Windows 11 using PowerShell.orYou are running on Ubuntu Linux 22.04.to ensure it uses the correct syntax (dirvsls) when executing autonomous shell commands.
docs/SKILLS.md (Tool Documentation)
This file defines what the agent can do. It is appended directly below the AGENT.md text and contains the documentation for your Native Tools and the step-by-step logic for your Composite Skills (detailed in the next section).
Extending UnoClaw (Adding Skills & Tools)
UnoClaw is designed to be highly hackable. You can give it new superpowers in two ways: by writing plain English workflows (Composite Skills) or by writing native Python functions (Native Tools).
1. The "No-Code" Way: Composite Skills
Because UnoClaw connects to powerful LLMs, you do not need to write a new Python script for every minor feature. You can simply teach the agent a "workflow" by editing the SKILLS.md file and instructing it to use its existing tools (like read_web or read_file).
To add a new skill, just append a clear, step-by-step instruction block to SKILLS.md.
Example: Adding a Bitcoin Price Tracker
Paste the following into your SKILLS.md file. UnoClaw will read this and instantly know how to pull real-time crypto prices without any new Python code:
### get_bitcoin_price_usd
* **Trigger:** When the user asks for the current Bitcoin or BTC price.
* **Execution Workflow:** 1. Call the `read_web` tool with the URL: `https://min-api.cryptocompare.com/data/generateAvg?fsym=BTC&tsym=USD&e=coinbase`
2. Analyze the returned JSON text.
3. Locate the `RAW` object, and extract the numeric value associated with the `PRICE` field.
4. Respond to the user using exactly this format: `BTC price is <PRICE> USD`.
2. The Python Way: Native Tools
If you need UnoClaw to interact with a specific local database, control hardware, or execute complex logic, you can easily add a native tool directly inside unoclaw.py.
Step 1: Define your Python function
Write your function inside unoclaw.py. Crucially, you must include type hints and a clear docstring. UnoClaw parses this to automatically generate the tool schema for the LLM.
def get_system_uptime() -> str:
"""
Returns the current uptime of the host machine.
Call this when the user asks how long the server has been running.
"""
import uptime
return f"System has been running for {uptime.uptime()} seconds."
Step 2: Register the tool
Find the available_tools dictionary in unoclaw.py and map your new function:
available_tools = {
"execute_command": execute_command,
"read_file": read_file,
"write_file": write_file,
"read_web": read_web,
"get_system_uptime": get_system_uptime, # <-- Your new tool registered here
}
Step 3: Document the tool for the LLM
Finally, open your AGENT.md or SKILLS.md file and add an entry so the LLM knows the tool exists, what it does, and what parameters it requires.
Add this to SKILLS.md under the Native Tools section:
### get_system_uptime
* **Description:** Returns the current uptime of the host machine in seconds. Use this when asked about server status or uptime.
* **Parameters:** None.
Security model (important)
UnoClaw connects to your host environment. Treat tool access with care!
- Workspace restriction: When
workspace.restrictistrue, the agent cannot access files outsideworkspace.path, runcdcommands with absolute paths, or make network requests. - Allowed usernames: In Telegram mode, only users listed in
telegram.allowed_usernamescan interact with the bot. Any other user is silently ignored. - Shell access: The
execute_commandtool runs arbitrary shell commands. Use workspace restriction and allowed-user lists to limit exposure. - No credential storage: Never commit
config.jsonto version control.
Project Structure
unoclaw/
โโโ LICENSE # License file
โโโ README.md # This file
โโโ pyproject.toml # Build configuration
โโโ .gitignore
โโโ assets/
โ โโโ unoclaw_text_logo.png # UnoClaw logo
โโโ tests/
โ โโโ test_unoclaw.py # Test suite (pytest)
โโโ unoclaw/
โโโ __init__.py
โโโ main.py # The entire agent โ single file
โโโ config.example.json # Template configuration
โโโ docs/
โโโ AGENT.md # Auto-loaded agent instructions
โโโ SKILLS.md # Auto-loaded agent skills
Project details
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 unoclaw-0.1.3.tar.gz.
File metadata
- Download URL: unoclaw-0.1.3.tar.gz
- Upload date:
- Size: 151.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.0 {"installer":{"name":"uv","version":"0.10.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
53a120ace439b3869d1bc05d5ee402642e3dd676505ca475839dd01c3d0ee25a
|
|
| MD5 |
40c19369b2504fd79fa18163a81a10d6
|
|
| BLAKE2b-256 |
40a2b460c8b57b8ac544cf20c750d95fd4f7309b15c0c461b0889d7bab4eadcf
|
File details
Details for the file unoclaw-0.1.3-py3-none-any.whl.
File metadata
- Download URL: unoclaw-0.1.3-py3-none-any.whl
- Upload date:
- Size: 18.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.0 {"installer":{"name":"uv","version":"0.10.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
69307744820e7dcba4a6baa42a57270bc295f8a43fa3aa12b4dd394bd56880f7
|
|
| MD5 |
6aa76beef6501940d062210d3927f32a
|
|
| BLAKE2b-256 |
387a4cb576def6d92d2e3d62dec6b31f5793ce235255f5a01658101b20a86bb8
|