| name | deploy |
| description | Deploy FemtoClaw firmware to an ESP32-S3 board. Covers prerequisites, configuration, build, flash, verification, and troubleshooting. |
Deploy FemtoClaw
End-to-end guide for deploying FemtoClaw to an ESP32-S3 dev board.
Prerequisites
Hardware
- ESP32-S3 dev board with 16 MB flash + 8 MB PSRAM (e.g. Xiaozhi AI board, ~$5-10)
- USB Type-C data cable (not charge-only)
Software
- ESP-IDF v5.5+ installed and working
idf.py --version
Credentials (get these first)
- WiFi SSID + password โ the network the ESP32 will connect to
- Telegram Bot Token โ create via @BotFather on Telegram
- Anthropic API Key โ from console.anthropic.com
- (Optional) Brave Search API key โ from brave.com/search/api
- (Optional) HTTP proxy host:port โ if in China or restricted network
Step 1: Clone and Set Target
git clone https://github.com/memovai/femtoclaw.git
cd femtoclaw
idf.py set-target esp32s3
Step 2: Configure Secrets
cp main/femto_secrets.h.example main/femto_secrets.h
Edit main/femto_secrets.h โ fill in ALL required fields:
#define FEMTO_SECRET_WIFI_SSID "YourWiFiName"
#define FEMTO_SECRET_WIFI_PASS "YourWiFiPassword"
#define FEMTO_SECRET_TG_TOKEN "123456:ABC-DEF..."
#define FEMTO_SECRET_API_KEY "sk-ant-api03-..."
#define FEMTO_SECRET_MODEL ""
#define FEMTO_SECRET_SEARCH_KEY ""
#define FEMTO_SECRET_PROXY_HOST ""
#define FEMTO_SECRET_PROXY_PORT ""
Proxy setup (China users):
If you need a proxy to reach Telegram/Anthropic APIs, set both PROXY_HOST and PROXY_PORT. The proxy machine must:
- Be on the same LAN as the ESP32
- Support HTTP CONNECT method (Clash, V2Ray, etc.)
- Have "Allow LAN connections" enabled
Step 3: Build
idf.py fullclean && idf.py build
IMPORTANT: Always fullclean after changing femto_secrets.h โ the secrets are compiled into the binary.
Expected output: Project build complete. To flash, run: idf.py flash
Build Troubleshooting
| Error | Fix |
|---|
femto_secrets.h: No such file | Run cp main/femto_secrets.h.example main/femto_secrets.h |
esp_websocket_client not found | Run idf.py fullclean then idf.py build (managed component auto-downloads) |
Toolchain not found | Re-run ESP-IDF install.sh and source export.sh |
| Build runs out of memory | Close other apps, ESP-IDF build needs ~2GB RAM |
Step 4: Find Serial Port
ls /dev/cu.usb*
ls /dev/ttyACM* /dev/ttyUSB*
Common ports:
- macOS USB-OTG:
/dev/cu.usbmodem1101 or /dev/cu.usbmodem11401
- Linux:
/dev/ttyACM0
If no port shows up:
- Try a different USB cable (must be data cable, not charge-only)
- Try a different USB port
- Check if board has a power LED lit
Step 5: Flash
idf.py -p PORT flash monitor
Replace PORT with your actual port. Example:
idf.py -p /dev/cu.usbmodem1101 flash monitor
The monitor shows boot logs. Look for:
I (xxx) femto: FemtoClaw - ESP32-S3 AI Agent
I (xxx) femto: PSRAM free: ~8000000 bytes
I (xxx) wifi: WiFi connected: 192.168.x.x
I (xxx) telegram: Telegram bot token loaded
I (xxx) femto: All services started!
Exit monitor: Ctrl+]
Step 6: Verify
- Open Telegram, find your bot (the one you created with BotFather)
- Send:
Hello
- You should see "femto is working..." followed by a response
- Send:
What time is it? โ tests the get_current_time tool
- Send:
Search for latest news about ESP32 โ tests web_search (if Brave key set)
Post-Deploy: Runtime Configuration
Connect via serial (idf.py -p PORT monitor) and use CLI commands:
femto> config_show # see current config
femto> wifi_set NewSSID NewPass # change WiFi
femto> set_tg_token 123456:ABC... # change Telegram token
femto> set_api_key sk-ant-... # change API key
femto> set_model claude-sonnet-4-5 # change model
femto> set_proxy 192.168.1.83 7897 # set proxy
femto> clear_proxy # remove proxy
femto> heap_info # check memory
femto> restart # reboot
CLI settings are stored in NVS flash and take priority over build-time values.
OTA Update (over WiFi)
After initial USB flash, future updates can be done over WiFi:
- Build new firmware:
idf.py build
- Host the
.bin file on a local HTTP server:
cd build && python3 -m http.server 8080
- Send to your bot on Telegram or use the OTA CLI command with the URL:
http://YOUR_PC_IP:8080/femtoclaw.bin
Flash Layout
16 MB Flash:
โโโ 0x009000 NVS (24 KB) โ runtime config
โโโ 0x020000 OTA_0 (2 MB) โ active firmware
โโโ 0x220000 OTA_1 (2 MB) โ update slot
โโโ 0x420000 SPIFFS (12 MB) โ memory, sessions, config
โโโ 0xFF0000 Coredump (64 KB)
Common Issues
| Symptom | Cause | Fix |
|---|
| No WiFi connection | Wrong SSID/password | Check femto_secrets.h, idf.py fullclean && build && flash |
| "No bot token" | Empty TG token | Set via femto_secrets.h or CLI set_tg_token |
| Bot doesn't respond | API key invalid | Check key at console.anthropic.com, set via CLI |
| "Markdown send failed" | Normal with Markdown mode | Non-critical, falls back to plain text |
| Proxy timeout | Proxy not reachable | Ensure same LAN, proxy allows LAN connections |
| SPIFFS mount failed | First boot or corruption | Normal on first boot (auto-formats) |
| Port busy/not found | Wrong port or cable | Try different USB port/cable, check ls /dev/cu.usb* |
| Boot loop | Firmware crash | Flash via USB again, check serial logs for crash info |