Pure C AI assistant firmware for ESP32-C3 / C5 / S3. Runs a ReAct agent with 20 tools and 10 notification channels on a $2 microcontroller with no PSRAM.
esp32c5.mp4
esp32c5_demo.mp4
ESPClaw remembers user preferences across reboots via NVS storage:
| Target | Cores | PSRAM | Flash | Profile |
|---|---|---|---|---|
| ESP32-C3 | 1 | No | 4MB | MINIMAL |
| ESP32-C5 | 1 | No | 4MB | MINIMAL |
| ESP32-S3 | 2 | 8MB | 16MB | FULL |
# Set target (first time or after switching)
idf.py set-target esp32c5 # or esp32c3 / esp32s3
# Configure
idf.py menuconfig
# -> ESPClaw Configuration -> LLM Settings (API key, model, etc.)
# -> ESPClaw Configuration -> Telegram (optional)
# Build, flash, and monitor
idf.py build flash monitorImportant: When switching targets, delete
sdkconfigfirst:rm sdkconfig && idf.py set-target esp32c5 && idf.py build
Supports any OpenAI-compatible API endpoint plus official Anthropic API.
| Backend | Wire Format | Default Endpoint |
|---|---|---|
| Anthropic | Messages API | api.anthropic.com/v1/messages |
| OpenAI | Chat Completions | api.openai.com/v1/chat/completions |
| OpenRouter | OpenAI-compatible | openrouter.ai/api/v1/chat/completions |
| Ollama | OpenAI-compatible | localhost:11434/v1/chat/completions |
| Custom | OpenAI-compatible | any URL you set |
Tested with: GPT-4o-mini, Claude 3 Haiku, GLM-4.5, DeepSeek, Qwen, etc.
| Category | Tools | Count |
|---|---|---|
| GPIO | gpio_write, gpio_read, gpio_read_all, delay |
4 |
| Memory | memory_set, memory_get, memory_delete, memory_list |
4 |
| Cron | cron_schedule, cron_list, cron_cancel, cron_cancel_all |
4 |
| Time | get_time, set_timezone |
2 |
| System | get_diagnostics, get_version |
2 |
| Persona | set_persona, get_persona |
2 |
| Network | wifi_scan, get_network_info |
2 |
Status: Serial and Telegram are fully tested and stable. Other channels are compiled and structurally complete but not yet verified on real hardware/services.
| Channel | Type | Protocol | Status |
|---|---|---|---|
| Serial | Bidirectional | UART console (always on) | Verified |
| Telegram | Bidirectional | Bot API long polling | Verified |
| MQTT | Bidirectional | IoT standard (Home Assistant / Node-RED) | WIP |
| DingTalk | Outbound | Webhook + HMAC signature | WIP |
| Discord | Outbound | Webhook | WIP |
| Slack | Outbound | Incoming Webhook | WIP |
| WeCom | Outbound | Enterprise WeChat bot | WIP |
| Lark | Outbound | Feishu bot + signature | WIP |
| Pushplus | Outbound | Unified push service | WIP |
| Bark | Outbound | iOS push notification | WIP |
All channels are conditionally compiled via CONFIG_ESPCLAW_CHANNEL_xxx.
Natural language scheduling with second-level precision:
espclaw> remind me every 15 seconds to check
espclaw> remind me every day at 9am to stand up
espclaw> remind me in 30 minutes to check the oven
| Command | Description |
|---|---|
/help |
Show available commands |
/tools |
List registered tools |
/heap |
Show free heap memory |
/gpio |
Show allowed GPIO pin range |
/reset |
Software reset |
+---------------------------------------------------------------------+
| Channels (conditional) |
| Serial | Telegram | MQTT | DingTalk | Discord | Slack | ... |
+-----------------------------+---------------------------------------+
|
+---------v---------+
| Message Bus | FreeRTOS Queue
| inbound/outbound |
+---------+---------+
|
+---------v---------+
| Agent Loop | ReAct cycle
| Session + Context|
+---------+---------+
|
+---------------------+---------------------+
| | |
+-------v-------+ +-------v--------+ +-------v------+
| Provider | | Tool Registry | | Service |
| Anthropic | | 20 tools | | cron |
| OpenAI | | GPIO/Memory/ | | ratelimit |
| Ollama | | Cron/Network | | wifi_mgr |
+---------------+ +-------+--------+ +--------------+
|
+--------v--------+
| HAL | Safety guardrails
| GPIO guardrail |
+-----------------+
- 8,478 lines of pure C (59 source files)
- 0 dependencies on third-party AI libraries
- Binary size: ~920KB (78% of 4MB partition free)
main/
├── main.c # Entry point
├── config.h # Compile-time constants
├── platform.h # C3/C5/S3 conditional compilation
├── messages.h # Message queue types
├── agent/
│ ├── agent_loop.c # ReAct loop + tool dispatch
│ ├── session.h/.c # Conversation history
│ ├── context_builder.h/.c # System prompt assembly
│ └── persona.h/.c # AI personality system
├── channel/
│ ├── channel.h # Channel vtable interface
│ ├── channel_serial.c # Serial console
│ ├── channel_telegram.c # Telegram Bot (long polling)
│ ├── telegram_helpers.h/.c # Telegram utility functions
│ ├── channel_dingtalk.c # DingTalk webhook
│ ├── channel_discord.c # Discord webhook
│ ├── channel_slack.c # Slack webhook
│ ├── channel_wecom.c # WeCom (Enterprise WeChat)
│ ├── channel_lark.c # Lark/Feishu
│ ├── channel_pushplus.c # Pushplus
│ ├── channel_bark.c # iOS push (Bark)
│ └── channel_mqtt.c # MQTT IoT
├── provider/
│ ├── provider.h # Provider vtable
│ ├── provider_anthropic.c # Anthropic Messages API
│ └── provider_openai.c # OpenAI/OpenRouter/Ollama
├── tool/
│ ├── tool.h # Tool interface
│ ├── tool_registry.h/.c # Registration + dispatch
│ ├── builtin_tools.def # X-macro tool table
│ ├── tool_gpio.c # GPIO tools (4)
│ ├── tool_memory.c # Memory tools (4)
│ ├── tool_cron.c # Cron + Time tools (6)
│ ├── tool_system.c # System tools (2)
│ ├── tool_persona.c # Persona tools (2)
│ └── tool_network.c # Network tools (2)
├── bus/
│ └── message_bus.h/.c # Inbound/outbound queues
├── service/
│ ├── cron_service.h/.c # Task scheduler
│ └── ratelimit.h/.c # API rate limiting
├── mem/
│ └── nvs_manager.h/.c # NVS key-value storage
└── hal/
└── hal_gpio.h/.c # GPIO HAL + safety guardrails
ESP32-C5: Requires WPA2-PSK or WPA2/WPA3 mixed mode on your router. "WPA only" mode will cause authentication failures.
See PLAN.md for the incremental roadmap.
MIT
