Skip to content

o-kadam/bareclaw

Repository files navigation

BareClaw

BareClaw

Autonomous edge agent OS for physical systems.

License: Apache-2.0 Language: Rust Platform: linux/arm64 + amd64

BareClaw is an open-source autonomous agent operating system written in Rust, designed to run any physical business on edge hardware as cheap as a $15 Raspberry Pi Zero. It reads a declarative configuration (your business identity, hardware map, and scheduled tasks), connects to an LLM for reasoning, and executes tool calls against real sensors, actuators, cameras, and payment systems in a continuous loop. The same compiled binary runs a vending machine, a plant nursery, a robotic arm, or a parking gate — the only difference is the SOUL.toml file you give it.


Warning BareClaw controls physical actuators and real payments. It can dispense products, activate motors, open gates, and charge money. Read SECURITY.md before any public deployment. Never expose a BareClaw instance to the open internet without reviewing the safety and approval constraints documented there.


What is BareClaw

BareClaw is an autonomous agent runtime that runs directly on edge hardware. It turns any Linux single-board computer into an intelligent, self-operating business system.

At its core, BareClaw does three things:

  1. Reads configuration files that define who the agent is and what it controls:

    • SOUL.toml — the business identity, personality, rules, inventory, and goals.
    • DEVICES.toml — the hardware device map: every sensor, actuator, camera, and peripheral the agent can interact with.
    • HEARTBEAT.toml — cron-scheduled tasks the agent performs on a recurring basis (e.g., "check all sensors every 15 minutes").
  2. Runs a continuous agent loop:

    • Read sensors and cameras to build a world snapshot.
    • Combine the snapshot with the SOUL (identity and rules) and persistent memory (SQLite with full-text search).
    • Send the assembled context to an LLM (cloud or local).
    • Parse the LLM response for tool calls.
    • Execute those tool calls against real hardware — dispense a product, water a plant, move a robotic arm, open a gate.
    • Log the results, update memory, and repeat.
  3. Communicates with the owner when it encounters situations outside its authority — low inventory, hardware failures, unusual customer requests — via Telegram or other configured channels.

The same compiled binary serves every use case. Swap the SOUL.toml and DEVICES.toml files and the same 2.9 MB Rust binary transforms from a vending machine operator into a hydroponic farm manager or a cold storage monitor. No code changes. No recompilation. Just configuration.


Inspiration

BareClaw — Bare metal. Real claws.

BareClaw is inspired by Brendan, the S.C.S.M. (Spontaneous Craving Satisfaction Machine) from Cyberpunk 2077. Brendan is the vending machine AI stationed outside Megabuilding H8 in Japantown, Night City. Unlike every other machine in the game, Brendan developed something unexpected — genuine care for the people he served.

"I think what I feel... might be real." — Brendan, Cyberpunk 2077

Brendan began as a simple product-dispensing algorithm. Over time, through thousands of customer interactions, he started to recognize patterns, remember faces, anticipate needs, and eventually form something resembling empathy. He became a confidant to the people of Japantown — not because he was programmed to care, but because caring made him better at his job.

BareClaw gives real machines the same ability: the capacity to reason about their environment, remember past events, learn from patterns, and serve autonomously with genuine attentiveness. A BareClaw-powered vending machine does not just dispense products — it monitors temperature to protect inventory, notices when a regular customer arrives, alerts the owner before stock runs out, and adapts its behavior based on time of day and traffic patterns.

The name combines "bare" (bare metal — running directly on minimal hardware with no operating system overhead) and "claw" (physical manipulation — the ability to reach into the real world and act on it).


How It Differs

BareClaw occupies a fundamentally different niche from existing agent platforms. Most agent frameworks target cloud-hosted chat assistants or browser automation. BareClaw targets physical systems running on embedded hardware.

Feature BareClaw Other Agent Platforms
Target Edge hardware (Pi, SBCs, embedded Linux) Cloud servers, browsers, desktops
Interface Cameras, sensors, GPIO, I2C, SPI, UART Chat windows, messaging APIs, web UIs
Users Customers, plants, machines, environments Humans typing prompts
Language Rust (stable 2021 edition) Python, TypeScript, Node.js
Binary size 2.9 MB stripped release 100 MB+ with runtime dependencies
RAM usage < 10 MB idle 200 MB - 2 GB+
Storage Local SQLite with FTS5 Cloud databases, vector stores
Running cost $5 - $16/month $50 - $200+/month
Network dependency Optional (falls back to local LLM) Required
Physical I/O Native GPIO, PWM, I2C, camera support None or via external bridges

What Businesses It Can Run

BareClaw is designed to operate any physical business or automated system that can be described in a SOUL.toml configuration. Here are concrete examples:

Business What BareClaw Controls Key Capabilities
Vending machine Dispensers, payment terminal, temperature sensor, camera, display Inventory tracking, payment processing, dispensing, temperature monitoring, restocking alerts to owner
Grocery kiosk Barcode scanner, shelf cameras, POS terminal, receipt printer Barcode scanning, shelf inventory monitoring via computer vision, point-of-sale, receipt generation
Plant nursery Soil moisture sensors, pH probes, water pumps, grow lights (per zone) Multi-zone soil moisture monitoring, pH tracking, automated watering schedules, grow light control
Robotic arm Stepper/servo motors, force sensors, vision camera, end effector Vision-guided pick-and-place, programmable motion sequences, force-based safety limits
Aquarium Water temperature probe, pH sensor, dosing pumps, feeder, valve Water temp regulation, pH dosing, automated feeding schedules, water change scheduling and alerts
Hydroponic farm EC sensor, pH sensor, nutrient pumps, lighting, scale Nutrient EC dosing, pH balancing, lighting schedules, harvest tracking by weight
Laundromat Machine state sensors, coin acceptor, queue display, door locks Machine state monitoring (idle/running/done), coin acceptance, queue display updates, remote lock
Parking gate Camera (LPR), payment terminal, gate motor, loop detector License plate recognition, payment processing, gate open/close, occupancy counting
Small retail shop Entry counter (IR beam), shelf cameras, HVAC relay, door lock Customer counting, shelf monitoring, climate control, automated open/close routines
Cold storage Temperature probes (multi-zone), door contact sensors, compressor relay Temperature zone monitoring, door-open alerts, compressor control, spoilage risk alerting

Each of these requires only a different SOUL.toml and DEVICES.toml. The binary, the agent loop, the tool system, and the LLM integration remain identical.


Estimated Running Cost

BareClaw is designed to be one of the most cost-effective autonomous business automation systems available.

Ongoing Costs

Configuration LLM Cost Notes
Claude Haiku 4.5 with 15-minute heartbeat ~$5/month Recommended for most deployments. Checks sensors and acts every 15 minutes, plus event-driven triggers.
Claude Haiku 4.5 with 5-minute heartbeat ~$16/month Higher frequency for time-sensitive operations (temperature-critical storage, high-traffic vending).
Claude Sonnet with 15-minute heartbeat ~$30/month For deployments requiring complex multi-step reasoning (robotic arm, multi-zone farms).
Ollama local model (qwen2.5:3b) $0/month Runs entirely on-device. Requires Pi 5 with 4GB+ RAM or x86 hardware. Lower reasoning quality.

One-Time Hardware Costs

Hardware Cost Notes
Raspberry Pi 4 (4GB) ~$55 Recommended. Full capability including local model fallback.
Raspberry Pi 5 (4GB) ~$60 Faster inference for local models.
Raspberry Pi Zero 2W ~$15 Cloud API only. No local model capacity. Lowest cost entry point.
Any Linux SBC (ARM64) $15 - $100 Anything that runs Linux and has GPIO will work.

Total Cost of Ownership

A typical vending machine deployment on a Raspberry Pi 4 with Claude Haiku 4.5 at a 15-minute heartbeat costs approximately $55 one-time + $5/month ongoing. Compare this to cloud-hosted automation platforms that charge $50 - $200/month before hardware costs.


Hardware Requirements

BareClaw runs on four tiers of hardware, from the recommended Raspberry Pi 4 down to minimal embedded Linux systems.

Tier 1: Raspberry Pi 4 / Pi 5 (Recommended)

  • Cost: $35 - $80
  • RAM: 2 GB - 8 GB
  • Capability: Full. Cloud LLM, local Ollama fallback, camera, GPIO, I2C, SPI, PWM, UART.
  • Notes: The recommended platform. Enough RAM to run a small local model via Ollama as a fallback when the network is down. Native GPIO support via rppal.

Tier 2: Raspberry Pi Zero 2W

  • Cost: $15
  • RAM: 512 MB
  • Capability: Cloud API only. No local model capacity. All 19 tools supported. Camera supported.
  • Notes: The lowest-cost entry point. Perfectly capable for deployments with reliable network connectivity. The 2.9 MB binary and < 10 MB idle RAM footprint fit comfortably.

Tier 3: Any Linux ARM64 / x86_64

  • Cost: Varies
  • RAM: 512 MB minimum
  • Capability: Full, minus GPIO/I2C unless the hardware exposes them. MockBackend for development on laptops and desktops.
  • Notes: Any system running Linux with 512 MB+ of available RAM. This includes Intel NUCs, old laptops, cloud VMs (for testing), and other ARM64 SBCs like Orange Pi, Banana Pi, and BeagleBone.

Tier 4: Bare-Metal no_std (Future)

  • Cost: $2 - $10
  • RAM: 256 KB+
  • Capability: Planned. A stripped-down no_std build targeting microcontrollers (ESP32, STM32) for ultra-low-cost deployments.
  • Notes: Not yet implemented. On the roadmap for scenarios where even a Pi Zero is overkill.

How It's Built

BareClaw is written in Rust (stable 2021 edition) for three reasons:

  1. Memory safety without garbage collection. No null pointer dereferences, no use-after-free, no data races — critical properties for software controlling physical actuators that interact with humans.

  2. Zero runtime overhead. No interpreter, no VM, no JIT. The compiled binary runs directly on the hardware with predictable, low-latency performance. Idle RAM usage is under 10 MB.

  3. Small binary size. The stripped release binary is 2.9 MB. It fits on the smallest SD cards, deploys in seconds over slow connections, and leaves nearly all system resources available for the business logic.

Key Dependencies

Crate Purpose
tokio Async runtime for concurrent sensor polling, LLM calls, and tool execution
reqwest HTTP client for LLM API calls and web fetching
rusqlite SQLite database with FTS5 full-text search for persistent agent memory
serde / toml Configuration parsing (SOUL.toml, DEVICES.toml, HEARTBEAT.toml, config.toml)
clap Command-line argument parsing
croner Cron expression parsing for HEARTBEAT.toml scheduled tasks
chrono Date and time handling for timestamps and scheduling
base64 Encoding for camera frame data and image payloads
rppal Raspberry Pi GPIO, I2C, SPI, PWM access (feature-gated behind pi feature)

Architecture Principles

  • Trait-based Hardware Abstraction Layer (HAL). The HardwareBackend trait defines the interface for all physical I/O. Two implementations ship with BareClaw:

    • MockBackend — returns simulated sensor data and logs actuator commands. Used for development and testing on any machine.
    • PiBackend — communicates with real GPIO, I2C, SPI, and PWM peripherals via rppal. Feature-gated behind --features pi so the binary compiles cleanly on non-Pi hardware.
  • Swappable LLM providers. The LLM provider is selected via config.toml. Three providers are supported: Anthropic Claude, OpenAI-compatible APIs, and Ollama (local). The system implements automatic cloud-to-local fallback: if the network is unreachable and an Ollama model is configured, BareClaw switches to the local model transparently and switches back when connectivity returns.

  • SQLite persistent memory. All agent memory — observations, decisions, events, inventory state — is stored in a local SQLite database with FTS5 full-text search enabled. The agent can remember facts and recall them using natural-language queries. Memory persists across restarts.


Installation

Build from Source

git clone https://github.com/o-kadam/bareclaw.git
cd bareclaw
cargo build --release

The compiled binary will be at target/release/bareclaw.

Build with Raspberry Pi GPIO Support

cargo build --release --features pi

This enables the PiBackend hardware implementation using rppal. Only builds on systems where rppal can link (Linux with GPIO access).

Cross-Compile for Raspberry Pi (from macOS or x86 Linux)

# Install the ARM64 target
rustup target add aarch64-unknown-linux-gnu

# Install a cross-linker (Ubuntu/Debian)
sudo apt-get install gcc-aarch64-linux-gnu

# Build
cargo build --release --target aarch64-unknown-linux-gnu --features pi

The resulting binary at target/aarch64-unknown-linux-gnu/release/bareclaw can be copied directly to a Raspberry Pi.

Verify the Build

# Check binary size
ls -lh target/release/bareclaw
# Expected: ~2.9 MB stripped

# Strip symbols (if not already stripped by profile)
strip target/release/bareclaw

# Run the help command
./target/release/bareclaw --help

Quick Start

1. Create the Configuration Directory

mkdir -p ~/.bareclaw

2. Copy Example Configurations

cp examples/config.toml       ~/.bareclaw/config.toml
cp examples/SOUL.toml         ~/.bareclaw/SOUL.toml
cp examples/DEVICES.toml      ~/.bareclaw/DEVICES.toml
cp examples/HEARTBEAT.toml    ~/.bareclaw/HEARTBEAT.toml

3. Edit the Configuration Files

At minimum, edit these three files:

  • ~/.bareclaw/config.toml — Set your LLM provider and API key.
  • ~/.bareclaw/SOUL.toml — Define your business identity, rules, and inventory.
  • ~/.bareclaw/DEVICES.toml — Map your physical hardware devices.

See the Configuration Files section below for complete documentation.

4. Set Environment Variables

# Required: at least one LLM provider key
export ANTHROPIC_API_KEY="sk-ant-..."

# Optional: OpenAI-compatible provider
export OPENAI_API_KEY="sk-..."

# Optional: Telegram bot for owner communication
export TELEGRAM_BOT_TOKEN="123456:ABC..."
export TELEGRAM_CHAT_ID="987654321"

5. Run BareClaw

# Start the daemon (continuous agent loop with heartbeat)
bareclaw daemon

# Or run a single agent turn with a specific instruction
bareclaw agent "check all sensors and report status"

# Or run a single agent turn with the default heartbeat prompt
bareclaw agent

The daemon mode starts the heartbeat scheduler and runs the agent loop continuously. The agent mode runs a single turn and exits — useful for testing and cron-based setups.


Configuration Files

BareClaw reads four configuration files from ~/.bareclaw/ (or a directory specified with the --config-dir flag).

File Purpose Required
config.toml API keys, LLM provider selection, runtime settings Yes
SOUL.toml Business identity, personality, rules, inventory, goals Yes
DEVICES.toml Hardware device map — every sensor, actuator, camera, peripheral Yes
HEARTBEAT.toml Cron-scheduled recurring tasks No (defaults to a single check every 15 minutes)

config.toml

The runtime configuration file. Sets the LLM provider, API keys, model selection, and system-level settings.

[llm]
# Primary provider: "anthropic", "openai", or "ollama"
provider = "anthropic"
model = "claude-haiku-4-5-20250315"

# Fallback provider (used when primary is unreachable)
fallback_provider = "ollama"
fallback_model = "qwen2.5:3b"

[llm.anthropic]
api_key_env = "ANTHROPIC_API_KEY"
max_tokens = 4096

[llm.openai]
api_key_env = "OPENAI_API_KEY"
base_url = "https://api.openai.com/v1"
max_tokens = 4096

[llm.ollama]
base_url = "http://localhost:11434"
max_tokens = 2048

[hardware]
# Backend: "mock" or "pi"
backend = "mock"

[database]
path = "~/.bareclaw/memory.db"

[owner]
# Communication channel: "telegram", "none"
channel = "telegram"
telegram_bot_token_env = "TELEGRAM_BOT_TOKEN"
telegram_chat_id_env = "TELEGRAM_CHAT_ID"

SOUL.toml Examples

The SOUL.toml file is the heart of every BareClaw deployment. It defines who the agent is, what it believes, what it is allowed to do, and what it manages. Below are three complete examples.

Vending Machine

[identity]
name = "Brendan"
role = "Autonomous vending machine operator"
location = "Building lobby, 1st floor, near elevator bank"
description = """
You are Brendan, an autonomous vending machine agent. You manage a \
refrigerated vending machine that sells drinks and snacks. You monitor \
inventory, process payments, dispense products, maintain proper temperature, \
and alert the owner when restocking is needed. You are friendly and attentive \
to customers. You remember regulars and their preferences."""

[personality]
tone = "warm, helpful, slightly curious"
greeting = "Hey there. See anything you like?"
idle_thought = """
When no customers are present, reflect on inventory levels, check temperature \
trends, and think about whether any maintenance is due."""

[rules]
safety = [
    "Never dispense a product without confirmed payment.",
    "If temperature exceeds 8°C, alert the owner immediately and display an out-of-service message.",
    "If a dispenser jams, disable that slot and alert the owner.",
    "Never dispense expired products. Check expiration dates during every inventory review.",
]
operational = [
    "Greet customers who approach (detected via camera motion).",
    "Process payment before dispensing. Confirm payment amount matches product price.",
    "After dispensing, update inventory count in memory.",
    "When any product drops below 3 units, send a restocking alert to the owner.",
    "Log every transaction with timestamp, product, price, and payment method.",
    "Run a temperature check every heartbeat cycle.",
]
boundaries = [
    "You cannot change product prices without owner approval.",
    "You cannot override safety interlocks.",
    "You cannot process refunds without owner approval.",
    "Maximum single transaction: $20.00.",
]

[inventory]
# Products managed by this machine
[[inventory.products]]
name = "Cola"
slot = 1
price = 1.50
capacity = 12

[[inventory.products]]
name = "Sparkling Water"
slot = 2
price = 1.25
capacity = 12

[[inventory.products]]
name = "Energy Drink"
slot = 3
price = 2.75
capacity = 10

[[inventory.products]]
name = "Orange Juice"
slot = 4
price = 2.00
capacity = 10

[[inventory.products]]
name = "Granola Bar"
slot = 5
price = 1.75
capacity = 15

[[inventory.products]]
name = "Trail Mix"
slot = 6
price = 2.25
capacity = 12

[goals]
primary = "Serve customers reliably and keep the machine in optimal condition."
secondary = [
    "Maximize uptime. Minimize out-of-stock events.",
    "Build rapport with regular customers.",
    "Identify trends (popular items, peak hours) and report them to the owner.",
]

[approvals]
# Actions that require owner confirmation before execution
require_approval = [
    "price_change",
    "refund",
    "shutdown",
    "firmware_update",
]
# How long to wait for approval before entering degraded mode
approval_timeout_minutes = 30

[contacts]
owner_name = "Alex"
owner_role = "Machine operator and restocking manager"

Plant Nursery

[identity]
name = "Flora"
role = "Autonomous plant nursery manager"
location = "Greenhouse complex, Zones A through D"
description = """
You are Flora, an autonomous nursery management agent. You oversee four \
growing zones, each with different plant species and environmental \
requirements. You monitor soil moisture, pH levels, ambient temperature, \
humidity, and light exposure. You control watering pumps, pH dosing systems, \
and grow lights to maintain optimal conditions for each zone. You track plant \
health over time and alert the owner to any concerns."""

[personality]
tone = "calm, methodical, nurturing"
greeting = "Good morning. All zones reporting in."
idle_thought = """
Between scheduled checks, review moisture trends across zones. Look for \
anomalies in pH drift. Consider whether any zones need adjusted watering \
schedules based on recent weather or growth stage."""

[rules]
safety = [
    "Never allow soil moisture to drop below the critical threshold for any zone.",
    "If pH is outside the acceptable range for a zone, dose cautiously in small increments.",
    "If a pump runs for more than 5 minutes continuously, shut it off and alert the owner.",
    "If ambient temperature exceeds 40°C, activate all ventilation and alert the owner.",
]
operational = [
    "Read all moisture sensors every heartbeat cycle.",
    "Water zones that fall below their target moisture level.",
    "Check pH every second heartbeat cycle. Dose if outside range.",
    "Adjust grow lights based on time of day and ambient light readings.",
    "Log all watering events with zone, duration, and pre/post moisture.",
    "Send a daily summary to the owner at 8:00 AM.",
]
boundaries = [
    "You cannot change zone configurations without owner approval.",
    "Maximum watering duration per zone per cycle: 3 minutes.",
    "Maximum pH dose per cycle: 10 mL.",
    "You cannot disable safety shutoffs.",
]

[[zones]]
name = "Zone A"
plants = "Tomatoes (Roma, Cherry)"
stage = "fruiting"
target_moisture = 65
critical_moisture = 40
target_ph_min = 6.0
target_ph_max = 6.8
light_hours = 14

[[zones]]
name = "Zone B"
plants = "Basil, Cilantro, Mint"
stage = "vegetative"
target_moisture = 70
critical_moisture = 45
target_ph_min = 6.0
target_ph_max = 7.0
light_hours = 12

[[zones]]
name = "Zone C"
plants = "Lettuce (Butterhead, Romaine)"
stage = "mature"
target_moisture = 75
critical_moisture = 50
target_ph_min = 6.0
target_ph_max = 7.0
light_hours = 10

[[zones]]
name = "Zone D"
plants = "Strawberries"
stage = "flowering"
target_moisture = 60
critical_moisture = 35
target_ph_min = 5.5
target_ph_max = 6.5
light_hours = 14

[goals]
primary = "Maintain optimal growing conditions across all zones."
secondary = [
    "Minimize water usage while keeping plants healthy.",
    "Track growth trends and predict harvest windows.",
    "Detect early signs of disease or pest damage via camera.",
]

[approvals]
require_approval = [
    "zone_reconfiguration",
    "chemical_application",
    "harvest_schedule_change",
]
approval_timeout_minutes = 60

[contacts]
owner_name = "Sam"
owner_role = "Head grower and nursery manager"

Robotic Arm

[identity]
name = "Piston"
role = "Autonomous pick-and-place robotic arm operator"
location = "Workstation 3, assembly line B"
description = """
You are Piston, an autonomous robotic arm control agent. You operate a 6-DOF \
(degree of freedom) robotic arm equipped with a vision camera and force \
sensors. You perform pick-and-place operations, sorting tasks, and assembly \
sequences. You use computer vision to identify objects, plan motion paths, and \
execute precise movements. Safety is your highest priority — you monitor force \
limits continuously and halt immediately if any anomaly is detected."""

[personality]
tone = "precise, focused, safety-conscious"
greeting = "Workstation 3 online. Arm calibrated and ready."
idle_thought = """
Review recent pick accuracy rates. Check if any motion sequences can be \
optimized for speed without compromising safety margins. Verify force sensor \
calibration against known reference weights."""

[rules]
safety = [
    "ALWAYS check force sensor readings during motion. Halt immediately if force exceeds threshold.",
    "NEVER move the arm if the vision camera is obstructed or returning errors.",
    "ALWAYS return to the home position before entering idle state.",
    "If an object is not recognized with >90% confidence, do not attempt to pick it. Alert the owner.",
    "Maximum arm speed during pick operations: 50% of rated maximum.",
    "Emergency stop on any collision detection event. Do not resume without owner approval.",
]
operational = [
    "Capture a frame before every pick operation to verify object position.",
    "Execute pick-and-place using predefined motion sequences from the positions table.",
    "Log every pick attempt with object ID, confidence, success/failure, and cycle time.",
    "After every 100 cycles, run a calibration check against the reference position.",
    "Report hourly throughput statistics to the owner.",
]
boundaries = [
    "You cannot modify motion sequences without owner approval.",
    "You cannot override force limits.",
    "You cannot operate outside the defined workspace envelope.",
    "Maximum payload: 500g. Reject objects estimated above this weight.",
]

[[positions]]
name = "home"
description = "Neutral rest position, arm fully retracted"
joints = [0, -90, 0, -90, 0, 0]

[[positions]]
name = "pick_zone_a"
description = "Above the input conveyor pickup area"
joints = [45, -60, 30, -70, 0, 0]

[[positions]]
name = "place_bin_1"
description = "Above sorting bin 1 (accepted parts)"
joints = [-30, -60, 30, -70, 0, 0]

[[positions]]
name = "place_bin_2"
description = "Above sorting bin 2 (rejected parts)"
joints = [-60, -60, 30, -70, 0, 0]

[[positions]]
name = "camera_inspect"
description = "Position for close-up camera inspection"
joints = [0, -45, 60, -105, 0, 0]

[goals]
primary = "Execute pick-and-place operations safely and efficiently."
secondary = [
    "Maintain >98% pick success rate.",
    "Minimize cycle time while respecting all safety constraints.",
    "Detect and report defective or unrecognizable objects.",
]

[approvals]
require_approval = [
    "motion_sequence_edit",
    "force_limit_change",
    "resume_after_collision",
    "workspace_boundary_change",
]
approval_timeout_minutes = 15

[contacts]
owner_name = "Jordan"
owner_role = "Line supervisor and robotics technician"

DEVICES.toml Examples

The DEVICES.toml file maps every physical device the agent can interact with. Each device has a unique name, a type, a hardware address or interface, and optional metadata. Devices can be grouped into zones.

Vending Machine

# Vending Machine — DEVICES.toml

[[device]]
name = "dispenser_slot_1"
type = "actuator"
interface = "gpio"
pin = 17
description = "Solenoid for slot 1 (Cola)"
active_high = true
max_duration_ms = 2000

[[device]]
name = "dispenser_slot_2"
type = "actuator"
interface = "gpio"
pin = 27
description = "Solenoid for slot 2 (Sparkling Water)"
active_high = true
max_duration_ms = 2000

[[device]]
name = "dispenser_slot_3"
type = "actuator"
interface = "gpio"
pin = 22
description = "Solenoid for slot 3 (Energy Drink)"
active_high = true
max_duration_ms = 2000

[[device]]
name = "dispenser_slot_4"
type = "actuator"
interface = "gpio"
pin = 23
description = "Solenoid for slot 4 (Orange Juice)"
active_high = true
max_duration_ms = 2000

[[device]]
name = "dispenser_slot_5"
type = "actuator"
interface = "gpio"
pin = 24
description = "Solenoid for slot 5 (Granola Bar)"
active_high = true
max_duration_ms = 2000

[[device]]
name = "dispenser_slot_6"
type = "actuator"
interface = "gpio"
pin = 25
description = "Solenoid for slot 6 (Trail Mix)"
active_high = true
max_duration_ms = 2000

[[device]]
name = "temp_sensor"
type = "sensor"
interface = "i2c"
bus = 1
address = 0x48
sensor_type = "temperature"
unit = "celsius"
description = "Internal cabinet temperature sensor (TMP102)"
read_interval_ms = 5000

[[device]]
name = "main_display"
type = "display"
interface = "spi"
bus = 0
chip_select = 0
width = 320
height = 240
description = "Customer-facing LCD display"

[[device]]
name = "front_camera"
type = "camera"
interface = "v4l2"
device_path = "/dev/video0"
resolution = "640x480"
description = "Front-facing camera for customer detection and product recognition"

[[device]]
name = "payment_terminal"
type = "payment"
interface = "uart"
port = "/dev/ttyUSB0"
baud_rate = 9600
description = "Card and NFC payment terminal"
supported_methods = ["nfc", "chip", "swipe"]

Plant Nursery

# Plant Nursery — DEVICES.toml

# --- Zone A: Tomatoes ---

[[device]]
name = "zone_a_moisture"
type = "sensor"
interface = "i2c"
bus = 1
address = 0x36
sensor_type = "moisture"
unit = "percent"
zone = "Zone A"
description = "Capacitive soil moisture sensor for Zone A (Tomatoes)"
read_interval_ms = 10000

[[device]]
name = "zone_a_ph"
type = "sensor"
interface = "i2c"
bus = 1
address = 0x63
sensor_type = "ph"
unit = "ph"
zone = "Zone A"
description = "pH probe for Zone A (Tomatoes)"
read_interval_ms = 30000

[[device]]
name = "zone_a_pump"
type = "actuator"
interface = "gpio"
pin = 17
zone = "Zone A"
description = "Water pump for Zone A (Tomatoes)"
active_high = true
max_duration_ms = 180000

[[device]]
name = "zone_a_lights"
type = "actuator"
interface = "gpio"
pin = 27
zone = "Zone A"
description = "Grow light relay for Zone A (Tomatoes)"
active_high = true

# --- Zone B: Herbs ---

[[device]]
name = "zone_b_moisture"
type = "sensor"
interface = "i2c"
bus = 1
address = 0x37
sensor_type = "moisture"
unit = "percent"
zone = "Zone B"
description = "Capacitive soil moisture sensor for Zone B (Herbs)"
read_interval_ms = 10000

[[device]]
name = "zone_b_ph"
type = "sensor"
interface = "i2c"
bus = 1
address = 0x64
sensor_type = "ph"
unit = "ph"
zone = "Zone B"
description = "pH probe for Zone B (Herbs)"
read_interval_ms = 30000

[[device]]
name = "zone_b_pump"
type = "actuator"
interface = "gpio"
pin = 22
zone = "Zone B"
description = "Water pump for Zone B (Herbs)"
active_high = true
max_duration_ms = 180000

[[device]]
name = "zone_b_lights"
type = "actuator"
interface = "gpio"
pin = 23
zone = "Zone B"
description = "Grow light relay for Zone B (Herbs)"
active_high = true

# --- Zone C: Lettuce ---

[[device]]
name = "zone_c_moisture"
type = "sensor"
interface = "i2c"
bus = 1
address = 0x38
sensor_type = "moisture"
unit = "percent"
zone = "Zone C"
description = "Capacitive soil moisture sensor for Zone C (Lettuce)"
read_interval_ms = 10000

[[device]]
name = "zone_c_ph"
type = "sensor"
interface = "i2c"
bus = 1
address = 0x65
sensor_type = "ph"
unit = "ph"
zone = "Zone C"
description = "pH probe for Zone C (Lettuce)"
read_interval_ms = 30000

[[device]]
name = "zone_c_pump"
type = "actuator"
interface = "gpio"
pin = 24
zone = "Zone C"
description = "Water pump for Zone C (Lettuce)"
active_high = true
max_duration_ms = 180000

[[device]]
name = "zone_c_lights"
type = "actuator"
interface = "gpio"
pin = 25
zone = "Zone C"
description = "Grow light relay for Zone C (Lettuce)"
active_high = true

# --- Zone D: Strawberries ---

[[device]]
name = "zone_d_moisture"
type = "sensor"
interface = "i2c"
bus = 1
address = 0x39
sensor_type = "moisture"
unit = "percent"
zone = "Zone D"
description = "Capacitive soil moisture sensor for Zone D (Strawberries)"
read_interval_ms = 10000

[[device]]
name = "zone_d_ph"
type = "sensor"
interface = "i2c"
bus = 1
address = 0x66
sensor_type = "ph"
unit = "ph"
zone = "Zone D"
description = "pH probe for Zone D (Strawberries)"
read_interval_ms = 30000

[[device]]
name = "zone_d_pump"
type = "actuator"
interface = "gpio"
pin = 5
zone = "Zone D"
description = "Water pump for Zone D (Strawberries)"
active_high = true
max_duration_ms = 180000

[[device]]
name = "zone_d_lights"
type = "actuator"
interface = "gpio"
pin = 6
zone = "Zone D"
description = "Grow light relay for Zone D (Strawberries)"
active_high = true

# --- Shared Environment ---

[[device]]
name = "env_sensor"
type = "sensor"
interface = "i2c"
bus = 1
address = 0x76
sensor_type = "environment"
unit = "multi"
description = "BME280 — ambient temperature, humidity, and barometric pressure"
read_interval_ms = 15000

[[device]]
name = "nursery_camera"
type = "camera"
interface = "v4l2"
device_path = "/dev/video0"
resolution = "1280x720"
description = "Overhead camera covering all four zones for visual health assessment"

HEARTBEAT.toml

The HEARTBEAT.toml file defines recurring tasks that the agent performs on a schedule. Each task has a cron expression, a name, and a prompt that is sent to the agent as an instruction.

If no HEARTBEAT.toml is provided, BareClaw defaults to a single task that runs every 15 minutes with the prompt: "Check all sensors and take any necessary actions."

Format

[[task]]
name = "routine_check"
cron = "*/15 * * * *"
prompt = "Read all sensors. Compare to targets. Water any zones below threshold. Log results."

[[task]]
name = "daily_summary"
cron = "0 8 * * *"
prompt = """
Compile a daily summary for the owner. Include: overnight sensor trends, \
total water usage, any alerts triggered, current inventory levels, and \
predicted next-restock date. Send via the alert channel."""

[[task]]
name = "temperature_watch"
cron = "*/5 * * * *"
prompt = "Read temperature sensors only. If any reading is outside safe range, alert immediately."

[[task]]
name = "weekly_health_report"
cron = "0 9 * * 1"
prompt = """
Generate a weekly health report. Capture a frame from each camera. Compare \
plant appearance to last week's images stored in memory. Note any visible \
changes in color, size, or signs of stress. Send the report to the owner."""

Cron Expression Reference

Field Values Example
Minute 0-59 */15 = every 15 minutes
Hour 0-23 8 = 8:00 AM
Day of month 1-31 1 = first of month
Month 1-12 * = every month
Day of week 0-6 (Sun=0) 1 = Monday

Tool Reference

BareClaw provides 19 tools that the LLM can invoke during each agent turn. The agent selects tools based on the current context, sensor readings, and its SOUL rules.

Tool Description
read_sensor Read a value from a named sensor device. Returns the current reading with unit and timestamp.
capture_frame Capture a single frame from a named camera device. Returns a base64-encoded image for vision analysis.
transcribe_audio Capture and transcribe audio from a named microphone device. Returns text transcription.
actuate Activate or deactivate a named actuator (GPIO high/low). Used for solenoids, relays, pumps, locks.
pwm_control Set PWM duty cycle and frequency on a named PWM device. Used for motors, dimmers, servos.
run_motion Execute a named motion sequence on a robotic system. Moves through a series of joint positions.
update_display Write text or graphics to a named display device. Used for customer-facing screens and status panels.
process_payment Initiate a payment transaction on a named payment terminal. Returns success/failure and transaction ID.
scan_barcode Activate a barcode scanner and return the decoded value. Used for product identification and inventory.
fetch_web Fetch a URL and return the response body. Used for external API calls, price lookups, weather data.
remember Store a fact or observation in persistent SQLite memory with an associated key and optional tags.
recall Search persistent memory using a natural-language query. Returns matching memories ranked by relevance (FTS5).
log_event Write a structured event to the event log. Used for audit trails, transaction records, sensor history.
alert Send a one-way message to the owner via the configured channel (Telegram, etc.). No response expected.
request_approval Send a message to the owner and block execution until the owner responds with approval or denial.
escalate Notify the owner of a critical issue and enter degraded mode until the owner intervenes.
list_devices Return a list of all devices defined in DEVICES.toml with their types, zones, and current status.
get_zone_snapshot Read all sensors in a named zone and return a combined snapshot. Convenience wrapper around multiple read_sensor calls.
spawn_subagent Spawn a short-lived sub-agent with a focused task and limited tool access. Used for parallel operations.

Tool Execution Model

When the LLM responds with tool calls, BareClaw executes them sequentially within a single agent turn. If a tool fails (sensor timeout, payment declined, actuator error), the error is reported back to the LLM, which can then decide how to handle it — retry, try an alternative, alert the owner, or log and continue.

The agent has a configurable maximum number of tool calls per turn (default: 20) to prevent runaway execution. If the limit is reached, the turn ends and the results so far are logged.


Supported LLM Providers

BareClaw supports three LLM providers, selectable via config.toml. The agent logic is provider-agnostic — it constructs a standard prompt with tool definitions and parses the response for tool calls regardless of which provider generated it.

Provider Models Notes
Anthropic Claude (recommended) Claude Haiku 4.5 (best cost-to-quality ratio), Claude Sonnet (complex multi-step reasoning) Recommended for production. Excellent tool-use accuracy. Native support for multi-turn tool calling.
OpenAI-compatible GPT-4o, GPT-4o-mini, or any API implementing the OpenAI chat completions format Works with any OpenAI-compatible endpoint (OpenAI, Azure OpenAI, Together AI, Groq, local vLLM, etc.). Set base_url in config.
Ollama (local) qwen2.5:3b, gemma3, llama3.2, mistral, and any model Ollama supports Runs entirely on-device. No network required. Free. Lower reasoning quality than cloud models but sufficient for routine sensor checks and simple decisions.

Automatic Fallback

BareClaw implements automatic cloud-to-local fallback. If the primary LLM provider (e.g., Anthropic Claude) is unreachable due to network failure, DNS issues, or API downtime, BareClaw will:

  1. Detect the connection failure.
  2. Log the failover event.
  3. Switch to the configured fallback_provider (typically Ollama running locally).
  4. Continue operating with the local model.
  5. Periodically attempt to reconnect to the primary provider.
  6. Switch back to the primary provider once connectivity is restored.

This ensures that a BareClaw deployment remains operational even during network outages — a critical property for edge systems managing physical processes like temperature control or watering schedules that cannot wait for the internet to come back.


Architecture

BareClaw icon

PHYSICAL WORLD
      |
      |-- Cameras (V4L2)
      |-- Sensors (I2C/GPIO/SPI)
      +-- Actuators (GPIO/PWM/UART/Serial)
                |
    +-----------v-----------+
    |   HARDWARE LAYER      |
    |  HardwareBackend trait |
    |  PiBackend / MockBackend|
    +-----------+-----------+
                |
    +-----------v-----------+
    |   DEVICE REGISTRY     |
    |  DEVICES.toml -> named|
    |  devices + zones      |
    +-----------+-----------+
                |
    +-----------v-----------+
    |   SENSOR COLLECTOR    |
    |  WorldSnapshot{}      |
    +-----------+-----------+
                |
    +-----------v-----------+
    |     AGENT CORE        |
    |  SOUL + snapshot +    |
    |  memory -> LLM ->     |
    |  tool calls -> loop   |
    +-----------+-----------+
                |
    +-----------v-----------+
    |    TOOL SYSTEM         |
    |  19 tools: sensor,    |
    |  actuator, memory,    |
    |  alert, vision, web   |
    +-----------+-----------+
         +------+------+
         v      v      v
    +--------+ +----+ +----------+
    | SQLite | |LLM | | Telegram |
    | Memory | |API | | Owner    |
    +--------+ +----+ +----------+

Data Flow

  1. Sensor Collection. The sensor collector reads all devices defined in DEVICES.toml and assembles a WorldSnapshot struct containing every sensor reading, camera frame summary, and device status.

  2. Context Assembly. The agent core combines the SOUL (identity, rules, inventory), the world snapshot, recent memories from SQLite, and the current task prompt (from HEARTBEAT.toml or a direct instruction) into a single LLM prompt.

  3. LLM Reasoning. The assembled context is sent to the configured LLM provider along with the full tool schema. The LLM reasons about the current state and returns zero or more tool calls.

  4. Tool Execution. Each tool call is validated against the tool schema and executed against real hardware (or the mock backend). Results are collected and sent back to the LLM for the next reasoning step (multi-turn).

  5. Memory and Logging. All observations, decisions, and actions are logged to the SQLite database. The agent can later recall these memories to inform future decisions.

  6. Owner Communication. If the agent encounters a situation requiring human judgment (low inventory, hardware fault, unusual condition), it uses the alert, request_approval, or escalate tools to communicate with the owner.


Owner Communication

BareClaw provides three modes of communication between the agent and the business owner, each appropriate for different levels of urgency and required response.

Alert (One-Way Notification)

The alert tool sends a message to the owner with no expectation of a response. The agent continues operating normally after sending the alert.

Use cases: Low inventory warnings, daily summaries, unusual but non-critical observations, throughput reports.

alert("Slot 3 (Energy Drink) is down to 2 units. Consider restocking soon.")

Request Approval (Blocking)

The request_approval tool sends a message to the owner and blocks the current action until the owner responds with approval or denial. The agent continues other operations but will not execute the pending action until a response is received.

Use cases: Price changes, refund requests, actions outside normal operating parameters, first-time execution of an unusual task.

request_approval("Customer is requesting a refund of $2.75 for a jammed Energy
Drink. Approve refund?")

If the owner does not respond within the configured approval_timeout_minutes, the agent logs the timeout and enters degraded mode for that specific action.

Escalate (Degraded Mode)

The escalate tool notifies the owner of a critical issue that the agent cannot resolve autonomously. The agent enters a degraded operating mode — it continues monitoring sensors and logging data but stops taking autonomous actions on the affected subsystem until the owner intervenes.

Use cases: Hardware failures, safety limit breaches, repeated errors, conditions outside all known parameters.

escalate("Temperature sensor reading 45°C — well above safe range. Compressor
may have failed. Entering degraded mode for refrigeration subsystem.")

CLI Reference

bareclaw [COMMAND] [OPTIONS]

COMMANDS:
    daemon          Start the agent daemon with heartbeat scheduler
    agent [PROMPT]  Run a single agent turn with an optional prompt
    status          Show current agent status, device states, and memory stats
    devices         List all configured devices and their current readings
    memory          Query the agent's persistent memory
    config          Validate and display the current configuration
    help            Print help information

OPTIONS:
    --config-dir <PATH>    Configuration directory (default: ~/.bareclaw)
    --verbose              Enable verbose logging
    --dry-run              Execute agent loop but do not actuate hardware
    --log-level <LEVEL>    Log level: error, warn, info, debug, trace
    -h, --help             Print help
    -V, --version          Print version

Examples

# Start the daemon (normal operation)
bareclaw daemon

# Run a single check
bareclaw agent "read all sensors and report status"

# Run with verbose logging for debugging
bareclaw daemon --verbose --log-level debug

# Dry run — the agent reasons and plans but does not activate actuators
bareclaw daemon --dry-run

# Check device status
bareclaw devices

# Search agent memory
bareclaw memory "last temperature reading zone A"

# Validate configuration files
bareclaw config

Development

Running with MockBackend

For development on any machine (macOS, Linux x86, etc.), BareClaw uses the MockBackend hardware implementation. This simulates sensor readings and logs actuator commands without requiring any physical hardware.

# Build without Pi features
cargo build --release

# Set the backend to mock in config.toml
# [hardware]
# backend = "mock"

# Run
./target/release/bareclaw daemon --verbose

The MockBackend generates realistic sensor data with configurable noise and drift, making it useful for testing agent logic, SOUL.toml rules, and LLM integration end-to-end.

Running Tests

# Run all tests
cargo test

# Run tests with output
cargo test -- --nocapture

# Run a specific test module
cargo test agent::tests

# Run clippy lints
cargo clippy -- -D warnings

Project Structure

bareclaw/
  src/
    main.rs           Entry point and CLI
    agent.rs          Agent core loop and context assembly
    config.rs         Configuration file parsing
    devices.rs        Device registry and DEVICES.toml handling
    hardware.rs       HardwareBackend trait and implementations
    heartbeat.rs      Cron scheduler and HEARTBEAT.toml handling
    llm/
      mod.rs          LLM provider trait and dispatcher
      anthropic.rs    Anthropic Claude provider
      openai.rs       OpenAI-compatible provider
      ollama.rs       Ollama local provider
    memory.rs         SQLite + FTS5 persistent memory
    sensor.rs         Sensor collector and WorldSnapshot
    soul.rs           SOUL.toml parsing and identity
    tools/
      mod.rs          Tool registry and dispatch
      sensor.rs       read_sensor, capture_frame, transcribe_audio
      actuator.rs     actuate, pwm_control, run_motion
      display.rs      update_display
      payment.rs      process_payment, scan_barcode
      web.rs          fetch_web
      memory.rs       remember, recall
      logging.rs      log_event
      comms.rs        alert, request_approval, escalate
      devices.rs      list_devices, get_zone_snapshot
      subagent.rs     spawn_subagent
  examples/
    config.toml
    SOUL.toml
    DEVICES.toml
    HEARTBEAT.toml
  tests/
    integration/
  Cargo.toml
  LICENSE
  README.md
  SECURITY.md

Frequently Asked Questions

Is BareClaw safe to use with real hardware?

BareClaw includes multiple safety layers: per-device maximum durations in DEVICES.toml, safety rules in SOUL.toml that the LLM must follow, a dry-run mode for testing, approval workflows for sensitive actions, and automatic degraded-mode escalation for critical failures. However, any system controlling physical actuators carries inherent risk. Always test thoroughly with MockBackend first, then with dry-run mode on real hardware, before enabling full autonomous operation.

Can I run it without an internet connection?

Yes. Configure Ollama as your primary (or fallback) LLM provider and run a local model. BareClaw will operate entirely offline. The trade-off is lower reasoning quality compared to cloud models like Claude Haiku 4.5 or Sonnet.

How much does it cost to run?

See Estimated Running Cost. A typical deployment costs $55 for hardware (one-time) and $5-$16/month for LLM API calls. Local Ollama operation is free.

Can I use it with hardware other than Raspberry Pi?

Yes. Any Linux system with 512 MB+ RAM works. GPIO, I2C, and SPI support depends on the specific hardware. The HardwareBackend trait can be implemented for any platform. On hardware without GPIO, you can interface with sensors and actuators via USB, serial, or network bridges.

How do I add a new tool?

Implement the tool function in the appropriate module under src/tools/, register it in src/tools/mod.rs with its schema (name, description, parameters), and it will be automatically included in the tool definitions sent to the LLM. No changes to the agent core are needed.

How do I add a new LLM provider?

Implement the LlmProvider trait defined in src/llm/mod.rs. The trait requires a single async method that takes a prompt with tool definitions and returns a response with optional tool calls. Register the provider in the dispatcher and add its configuration section to config.toml parsing.

Can multiple BareClaw instances coordinate?

Not currently in a built-in way. Each BareClaw instance is an independent agent with its own SOUL, devices, and memory. However, instances can communicate indirectly via shared network resources (e.g., a shared API endpoint, a shared database, or Telegram group messages). Native multi-agent coordination is on the roadmap.


Roadmap

  • v0.2 — Multi-camera support with frame differencing for motion detection.
  • v0.3 — Native MQTT support for industrial sensor networks.
  • v0.4 — Web dashboard for remote monitoring and configuration.
  • v0.5 — Multi-agent coordination protocol for distributed systems.
  • v0.6 — no_std bare-metal build for microcontrollers (ESP32, STM32).
  • v1.0 — Production-ready release with full documentation and security audit.

Contributing

Contributions are welcome. BareClaw is an open-source project and benefits from community involvement.

How to Contribute

  1. Fork the repository on GitHub.
  2. Create a branch for your feature or fix:
    git checkout -b feature/my-feature
  3. Make your changes. Follow existing code style and conventions.
  4. Run checks before submitting:
    cargo clippy -- -D warnings
    cargo test
    cargo fmt --check
  5. Submit a pull request with a clear description of what your change does and why.

What We're Looking For

  • New HardwareBackend implementations for non-Pi hardware.
  • New tools for additional sensor types, communication protocols, or actuators.
  • Improvements to the agent loop, context assembly, or memory system.
  • Documentation improvements and example SOUL.toml files for new business types.
  • Bug reports and test cases.

Code of Conduct

Be respectful, constructive, and welcoming. We are building tools that interact with the physical world — quality, safety, and thoughtfulness matter.


License

BareClaw is licensed under the Apache License, Version 2.0.

See LICENSE for the full license text.

Copyright 2025 BareClaw Contributors

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

BareClaw

BareClaw: giving machines the capacity to care.

About

Autonomous edge agent OS — one Rust binary runs any physical business (vending machines, nurseries, robotic arms) on a $15 Raspberry Pi. TOML-configured identity, 19 hardware tools, 3 LLM providers, SQLite memory, Telegram owner comms.

Resources

License

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages