A minimal starter project for controlling a Raspberry Pi robot car with Claude Code, using an MCP server to expose motors and a camera as tools.
CLAUDE.md— system prompt that gives Claude its identity, hardware info, and behavior guidelines as "Saras".mcp.json— MCP server configservers/robot_server.py— MCP server exposingmove,stop,get_encoders,reset_encoders, andcapture_imagehardware/motor.py— simple serial driver for a motor controller (ESP32/Arduino over USB)
- Raspberry Pi 4B
- Raspberry Pi Camera Module 3
- LDROBOT LD06 LiDAR
- DFRobot VL53L7CX Time-of-Flight Sensor (8x8 grid)
- JGA25 DC Motors with Encoders (x4)
- ESP32 Microcontroller
- Dual Channel H-Bridge Motor Driver (DC 5-12V, 0-30A)
- 18650 Li-ion Cells in 3S2P configuration with BMS
- 7-inch HDMI Display
- USB Omnidirectional Microphone
- USB Speaker
- USB Webcam (lens + PCB only, housing removed)
- 3D Printed Chassis (designed in Fusion 360)
- Heat Set Inserts
- A Raspberry Pi (any model with USB + camera connector)
- A Pi Camera Module (accessed via
rpicam-jpeg) - A microcontroller (ESP32/Arduino) wired to a motor driver, connected to the Pi over USB serial at 115200 baud
The microcontroller is expected to understand a tiny serial protocol:
M <left> <right> -> set motor speeds, -255..255, positive = forward
S -> stop
RESET -> zero encoder counters
ENC:<m1>:<m2>:<m3>:<m4> -> encoder values streamed back continuously
You can implement this with a basic Arduino sketch driving an H-bridge motor driver (e.g. L298N) — that part is up to you.
-
Install dependencies:
pip install pyserial mcp pillow
-
Check your serial port (usually
/dev/ttyUSB0or/dev/ttyACM0) and updatehardware/motor.pyif needed. -
Make sure the Pi camera works:
rpicam-jpeg -o /tmp/test.jpg
-
Launch Claude Code from the project root — it will pick up
.mcp.jsonautomatically:claude
-
Try it out:
move forward for half a second, then take a photo and tell me what you see
This is intentionally minimal — just enough to drive around and see. From here you could add:
- Distance sensors (LiDAR, ultrasonic, ToF) — add a new module under
hardware/, expose aread_distance()-style tool inservers/robot_server.py, and teach Claude inCLAUDE.mdwhen to use it for obstacle avoidance. - Speech — add a TTS tool (e.g. via ElevenLabs or
espeak) so Saras can talk, and aspeak()tool in the MCP server. - A face/display — drive a small screen to show expressions.
- Persistent memory — have Claude read/write a
memory/memory.jsonfile at the start and end of each session to remember places, people, and past observations. - Wakeword / voice commands — run a lightweight wakeword listener that
drops tasks into an
inbox.txtfile, and have Claude poll it.
The pattern is always the same: add a hardware driver, wrap it as an MCP
tool, then describe it in CLAUDE.md so Claude knows when and how to use it.
If you'd rather have Claude Code generate this whole setup for you, create an
empty project folder, run claude inside it, and give it a prompt like:
I'm building a robot car on a Raspberry Pi, controlled by Claude Code.
Set up a minimal project with:
- A CLAUDE.md that gives you an identity as a robot named "Saras", explains
you control the car through MCP tools, and gives basic safety/movement
guidance.
- A .mcp.json that runs a local MCP server (servers/robot_server.py).
- An MCP server (using the `mcp` Python SDK / FastMCP) exposing tools:
move(direction, speed, duration), stop(), get_encoders(),
reset_encoders(), and capture_image() (using rpicam-jpeg).
- A hardware/motor.py module that talks to an ESP32/Arduino over USB serial
(115200 baud) using a simple text protocol: "M <left> <right>" to set
motor speeds, "S" to stop, "RESET" to zero encoders, and "ENC:a:b:c:d"
lines streamed back for encoder feedback.
- A README explaining hardware assumptions and how to run it.
Keep it minimal — this is a starting point I'll extend with sensors,
speech, and memory later.
From there, iterate with Claude Code to add whatever sensors and behaviors you want.