R CLI
██████╗ ██████╗██╗ ██╗
██╔══██╗ ██╔════╝██║ ██║
██████╔╝█████╗██║ ██║ ██║
██╔══██╗╚════╝██║ ██║ ██║
██║ ██║ ╚██████╗███████╗██║
╚═╝ ╚═╝ ╚═════╝╚══════╝╚═╝
Local AI Agent Runtime
A tool orchestrator that connects local LLMs to 74 system tools via function calling.
Installation · Quick Start · All Skills · Why Not Just Terminal Access? · Docs
What is R CLI?
R CLI is a tool orchestrator for local LLMs. It exposes 74 "skills" (PDF generation, SQL queries, git, docker, etc.) as structured function calls that any OpenAI-compatible model can invoke.
This is NOT an operating system. It's a Python CLI that sits between your local LLM (Ollama, LM Studio) and real system tools.
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ You │────▶│ R CLI │────▶│ Local LLM │
│ (prompt) │ │ (orchestrator)│ │ (Ollama) │
└─────────────┘ └──────┬──────┘ └──────┬──────┘
│ │
▼ │
┌─────────────┐ │
│ Skills │◀────────────┘
│ (74 tools) │ function call
└─────────────┘
$ r chat "Create a PDF report about Python"
# LLM calls pdf.generate_pdf() -> creates python_report.pdf
$ r sql sales.csv "SELECT product, SUM(revenue) FROM data GROUP BY product"
# Runs actual SQL against CSV using DuckDB
$ r rag --add ./docs/ && r rag --query "how does auth work"
# ChromaDB vectors, semantic search across your docs
Why Structured Tools Instead of Terminal Access?
You could just give an LLM shell access. But structured function calling provides:
| Raw Terminal Access | R CLI Structured Tools |
|---|---|
| Model guesses bash syntax | Model sees JSON schema for each tool |
"Run zip *.py" can fail in many ways |
archive.create_zip(files=["*.py"]) with validation |
| Hard to add confirmation gates | Each tool can require user approval |
| No type checking | Pydantic validates all inputs |
| Unpredictable output parsing | Structured return values |
Example: When you ask "compress python files", the LLM doesn't generate bash. It calls:
{
"tool": "archive.create_zip",
"arguments": {
"source_path": ".",
"pattern": "*.py",
"output": "python_files.zip"
}
}
R CLI validates the arguments, executes the tool, and returns structured results.
Features
| Feature | Description |
|---|---|
| 100% Local | Your data never leaves your machine |
| 74 Skills | PDF, SQL, code, git, docker, RAG, voice, and more |
| REST API | OpenAI-compatible server for IDE integration |
| Plugin System | Add custom skills in Python |
| Voice Interface | Whisper STT + Piper TTS (optional) |
| Hardware Skills | GPIO, Bluetooth, WiFi for Raspberry Pi |
Installation
# Basic
pip install r-cli-ai
# With all features
pip install r-cli-ai[all]
# R OS Simulator (Textual TUI)
pip install r-cli-ai[simulator]
# Raspberry Pi (with GPIO)
pip install r-cli-ai[all-rpi]
Requirements
Quick Start
1. Start your LLM
# Ollama
ollama pull qwen3:4b && ollama serve
# Or use LM Studio GUI
2. Run R CLI
# Interactive chat
r
# Direct command
r chat "Explain quantum computing in simple terms"
# Start API server
r serve --port 8765
R OS - Terminal UI (Experimental)
A terminal-based interface that looks like Android. Built with Textual. This is an experimental feature for Raspberry Pi and edge devices - not an actual OS.
┌─────────────────────────────────────────────────────────┐
│ ▁▂▄█ 📶 R OS 12:45 🔋 85% │
├─────────────────────────────────────────────────────────┤
│ │
│ 💬 Messages 📞 Phone 📧 Email 🌐 Browser │
│ │
│ 📷 Camera 🖼️ Gallery 🎵 Music 🎬 Video │
│ │
│ 📁 Files 📅 Calendar ⏰ Clock 🔢 Calculator │
│ │
│ 🤖 R Chat 🎤 Voice 🌍 Translate 📝 Notes │
│ │
│ ⚙️ Settings 📶 WiFi 🔵 Bluetooth 🔋 Battery │
│ │
│ 💡 GPIO 💻 Terminal 🔌 Network 📊 System │
│ │
├─────────────────────────────────────────────────────────┤
│ ◀ Back ● Home ▢ Recent │
└─────────────────────────────────────────────────────────┘
Launch
r-os # Material theme
r-os --theme amoled # AMOLED black
r-os --theme light # Light theme
Keyboard Shortcuts
| Key | Action |
|---|---|
t |
Cycle themes |
n |
Notifications panel |
h |
Home |
Esc |
Back |
q |
Quit |
Raspberry Pi Setup
# One-command installer
curl -sSL https://raw.githubusercontent.com/raym33/r/main/r_os/rpi/install.sh | bash
All 74 Skills
📄 Documents
pdf · latex · markdown · pdftools · template · resume · changelog
💻 Code & Data
code · sql · json · yaml · csv · regex · schema · diff
🤖 AI & Knowledge
rag · multiagent · translate · faker
🎨 Media
ocr · voice · design · image · video · audio · screenshot · qr · barcode
📁 Files
fs · archive · clipboard · env
📅 Productivity
calendar · email · ical · vcard
🔧 DevOps
git · docker · ssh · http · web · network · system · metrics
🔍 Dev Tools
logs · benchmark · openapi · cron · jwt
📝 Text
text · html · xml · url · ip · encoding
🔢 Data
datetime · color · math · currency · crypto · semver · mime
🌐 Web
rss · sitemap · manifest · hublab · weather
🔌 Hardware (R OS)
gpio · bluetooth · wifi · power · android
🧩 Extensions
plugin
REST API
# Start server
r serve --port 8765
# Chat (OpenAI-compatible)
curl -X POST http://localhost:8765/v1/chat \
-H "Content-Type: application/json" \
-d '{"messages": [{"role": "user", "content": "Hello!"}]}'
# Call skill directly
curl -X POST http://localhost:8765/v1/skills/call \
-d '{"skill": "pdf", "tool": "generate_pdf", "arguments": {"content": "Hello"}}'
Swagger UI: http://localhost:8765/docs
Configuration
# ~/.r-cli/config.yaml
llm:
backend: ollama
model: qwen3:4b
base_url: http://localhost:11434/v1
ui:
theme: ps2 # ps2, matrix, minimal, retro
skills:
disabled: [] # Skills to disable
Create Custom Skills
# ~/.r-cli/skills/my_skill.py
from r_cli.core.agent import Skill
from r_cli.core.llm import Tool
class MySkill(Skill):
name = "my_skill"
description = "My custom skill"
def get_tools(self) -> list[Tool]:
return [
Tool(
name="my_function",
description="Does something useful",
parameters={"type": "object", "properties": {"input": {"type": "string"}}},
handler=self.my_function,
)
]
def my_function(self, input: str) -> str:
return f"Processed: {input}"
Development
git clone https://github.com/raym33/r.git
cd r
pip install -e ".[dev]"
pytest tests/ -v
ruff check . && ruff format .
Links
Honest Limitations
- Sandboxing is basic - Skills run with your user permissions. Working on better isolation.
- Small models (4B) sometimes pick the wrong tool - Larger models (7B+) work better.
- It's a tool layer, not magic - Prompt quality still matters.
- Some skills need external dependencies - OCR needs Tesseract, voice needs Whisper, etc.
License
MIT License
R CLI - A tool orchestrator for local LLMs.
Created by Ramón Guillamón
Metadata
Release files for r-cli-ai 0.3.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| r_cli_ai-0.3.2.tar.gz | 334.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| r_cli_ai-0.3.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 737.9 kB
Release files / r_cli_ai-0.3.2.tar.gz
| Download URL | r_cli_ai-0.3.2.tar.gz |
|---|---|
| Size | 334.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
4b737d9e6ca8e56625db2ab1d9940a668460a4ca96f1ccfbcd83f32e56300344
|
|
BLAKE2b-256 checksum How to use checksums |
0425235828542b9ea4f6fea41be55288e8c2002b0cff94ea40273692e7dbac17
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Dec 17, 2025.
Transparency logRelease files / r_cli_ai-0.3.2-py3-none-any.whl
| Download URL | r_cli_ai-0.3.2-py3-none-any.whl |
|---|---|
| Size | 403.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
19c4376b832f1cc89f3a6bd5cc31ebf2d990ef2fe100a76ba942f737903e4abc
|
|
BLAKE2b-256 checksum How to use checksums |
bdd231de15cd51e7d5addd4a2f55d005a9839c1dc469b9219fb6906cdf36a5e0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Dec 17, 2025.
Transparency log