quackd README

The project's README from github.com/rokbenko/quackd. As one markdown file: README.md.

quackd

Give your Microduck a brain. Or one of seven other small robots, from a Reachy Mini head to a ToddlerBot humanoid. Any LLM, one .duck file.
quackd, pronounced “quacked”: the brain daemon Microduck was missing, named like its siblings robotd, mediad, padd and tofd. Eight robots today, every one of them in a simulator or a mock so far, and one of them a duck you can print and build yourself.

State a goal from a terminal or from a chat with Claude. Either way the same contract decides which of the robot's skills the model may use, how many steps it gets, and when it has to ask you first.

CI PyPI Python 3.11+ Apache 2.0 MCP ready robots: 8 bodies, simulated and mocked

Hey, my name is Rok and this is why I built quackd 👋

I see quackd as a ChatGPT like moment for robotics. Let me explain what I mean.

LLMs existed long before ChatGPT. What ChatGPT actually did was take LLMs and hand them to ordinary people in a chat interface everyone already knew, like Facebook Messenger or Instagram. That was the real unlock.

Right now, in 2026, most people still think robots belong in science fiction movies or in a lab at Tesla. That is not true anymore. There are already open source robots you can build yourself for under $1000. And they actually work. They can go to your fridge, open it, grab a can of Coke, close the fridge and bring it to you.

The problem is they have a huge limitation. You can teach them dozens of moves, like "get a coke". But the robot itself is still dumb. It knows the moves, it just cannot connect them on its own. For robots to become truly useful, they need to become AI first and agentic. You give them a goal and they figure out the steps themselves.

Imagine telling your robot "I want to eat and drink something". It walks to the fridge, checks what is inside, finds your Coke, grabs a plate and some cutlery, brings them to you, and at the same time tells you what food it found so you can pick. You choose, it goes back, gets the food, brings it to you and wishes you a good meal. Sounds like science fiction, right? We are closer than you think!

To get there, robots need a brain. And here is the catch. Today's robots simply do not have enough hardware on board to think, reason and plan. Their skull is too small for the brain this kind of intelligence needs.

This is exactly where quackd comes in. It gives your robot a brain that lives outside of it, in the cloud or on your own computer, and that brain can grow as big as you need. The robot itself stays small and light while all the heavy thinking happens somewhere else.

Now the only thing left to solve is the interface. quackd lets you talk to that outside brain, and through it to your robot, using a simple chat, the same kind of chat you already use on Messenger or Instagram. You just say "hey, I want to eat something" and it takes it from there.

That is basically what ChatGPT did for LLMs. And that is why I see quackd as a ChatGPT like moment for robotics.

— Rok Benko, August 2026

Two Microduck robots side by side in a MuJoCo physics simulator, running the same world. On the left, with quackd, the duck walks a square and a top-down inset traces its path. On the right, without quackd, the duck stands still and its inset shows a single unmoving dot.
The same sentence, the same duck, with and without quackd. Left: you type walk in a square, a pilot picks the robot's own verbs one at a time, and the contract decides which it may use. Nobody wrote a square. It walks a leg, reads the pose it actually reached and corrects, because a real gait delivers about 0.42 of what you ask for. Right: the identical world, robot and walking policy, minus quackd. A Microduck takes a twist, which is three numbers, so an English sentence has nowhere to go and it stands there. Physics is MuJoCo in the Microduck's own scene, the gait is the policy Pollen trained, the pilot is scripted so this needs no API key, and each inset is the path walked so far. See docs/assets.

quackd connects a small robot to a large language model and turns a request like "find the ball and kick it" into the right sequence of the robot's own skills. The model picks one skill at a time from the list the robot's manifest declares, quackd runs it, looks at the camera, and asks again until the job is done or clearly impossible. Claude, OpenAI, Gemini and Grok work over their APIs. Open source models work on your own machine through Ollama, vLLM, llama.cpp or LM Studio, with no key.

The first robot is the Microduck from Pollen Robotics, a biped that already knows how to walk, turn, kick, scoop something off the floor, look around and quack. Seven more bodies follow it through adapters that declare what each can do: an Open Duck Mini v2 you can print and build yourself, a Reachy Mini head, an SO-101 class arm through LeRobot, any wheeled base over rosbridge, an XLeRobot dual-arm cart, an AlohaMini with two arms on a lift, and a ToddlerBot humanoid.

You do not need a robot to try it. Two simulators ship with quackd. The physics one puts the real Microduck in MuJoCo and runs the walking policy Pollen trained for it, so the duck walks instead of sliding and a command below its gait floor produces nothing at all. The cartoon starts in a second, downloads nothing, and is what the four other bodies that have a simulator use, along with every seeded sweep in CI. These goals succeed on 10 of 10 seeds with the scripted pilot and a ground truth check:

"Find the ball and kick it." · "Find the ball, walk up to it and say where it is." (an Open Duck Mini v2, which cannot kick) · "Find the ball with your gaze and say where it is." (a Reachy Mini head, no legs) · "Split the search, the closest duck kicks." (a flock) · "The head spots, the duck kicks, the head judges." (two bodies, one contract)

The first of those also passes 10 of 10 on the physics simulator, with the duck on its own gait rather than a sprite on rails: that is test_find_and_kick_on_the_real_duck, which needs upstream's model in the cache, so a nightly job fetches it the way your first run would and CI's own gating job runs the stand-in. The rest are cartoon only, because the other seven bodies have no physics model here.

Nothing here has run on a real robot yet, on any of the eight adapters. Every hardware backend speaks names read from upstream source at a pinned commit and has only ever talked to fakes. For the Open Duck Mini and the ToddlerBot those fakes are the daemons quackd itself ships for the robot, exercised over loopback, so there only the body is untested. Goals like "find my keys" are where this is going, not what it does yet. The honest label for today is LLM driven, goal directed control of simulated robots, and Which robots work says exactly how far each one has got.


Table of Contents


Try it in 60 seconds

uvx --from "quackd[mujoco]" quackd run --goal "walk in a square" --robot microduck:mujoco --provider fake   # the duck above: real physics, its own trained gait (first run fetches about 10 MB)
uvx quackd run find-and-kick --provider fake                                        # the cartoon: no download, done in a second
claude mcp add quackd -- uvx quackd serve-mcp --robot microduck:sim2d               # or just chat with it: "find the ball and kick it"
uvx quackd run open-duck-scout --provider fake                                     # a duck you can build: it finds the ball and walks up, no kick
uvx quackd run reachy-spotter --provider fake                                       # another body: a Reachy Mini head, no legs, same loop
uvx --from "quackd[mujoco,anthropic]" quackd run find-and-kick --provider anthropic --robot microduck:mujoco   # a real model on the real gait, needs ANTHROPIC_API_KEY
uvx --from "quackd[openai]" quackd run find-and-kick --provider ollama --model qwen3:8b          # local model, no key
open runs/*/run.gif                                                                 # a GIF in either simulator, a transcript every time

Or open the browser demo and install no quackd at all. It is live at https://www.quackd.org/simulator, with the same physics, the same two upstream policies, seven of the same verbs and a contract of its own, in a page. Type a sentence, paste your own API key or point it at Ollama, and watch what the model chose. The keyboard beside the box is live at the same time, so a key can take the duck off the model mid-run. To run that same page from a checkout, clone this repository, run python web/serve.py and open http://localhost:8000/simulator/. That server is one stdlib file, Python but not quackd. The page is web/, and The browser demo says what it does.

Put keys in the environment or in a .env file (copy .env.example). quackd doctor tells you what is missing. Needs Python 3.11 or newer and uv, nothing else.


Why?

A modern small robot is not short of skills. The Microduck's onboard controllers already balance it, walk, kick, sit, stand up after a fall and scoop with its beak. A Reachy Mini head looks around and emotes, an arm picks with its own learned policy, a wheeled base drives. Each is the robot's own skill, trained, written or recorded, and each works without any help from an AI model. What the robot lacks is any idea of what those skills are for.

Traditional control:   walk forward, turn left, walk, look down, scoop, ...   (you plan every step)
This project:          "Pick up the ball."                                    (you state the goal)

Low level skills and high level goals are different layers. The robot knows the words, but it cannot hold a conversation. quackd is an open source attempt to connect the two layers, with an LLM doing the planning and the robot's own controllers doing the moving.


What is this?

The first robot. The Microduck is a 25 cm, 800 g biped shaped like a duck: fifteen small servos, a camera in its head, a depth sensor, a speaker, an onboard computer, and a set of learned behaviours (walk, kick, sit and stand, ground pick, roll, roller skate with clip on wheels) that run at 50 Hz on the robot itself. It is open source, costs about $399, and is deliberately small and friendly, the opposite of an intimidating humanoid. The bet behind projects like this one is that useful robots at home or in an office will be small ones people actually enjoy having around.

This project. quackd is an independent, unofficial brain for it, and for any small robot that has an adapter. It takes a goal in human language, from a chat, a command line or a .duck task file, and enforces a contract the model cannot talk its way out of: which skills are allowed, how many steps, when a human must say yes, when to abort.

It ships with two simulators, so all of this can be developed and demoed before the hardware exists, and with an MCP server so Claude Code or Claude Desktop can drive one robot or a fleet interactively.


How it works (the simple version)

flowchart TD
    YOU["You<br/>“find the ball and kick it”"]
    LLM["LLM<br/>looks at the camera, the robot's state and the last result<br/>picks ONE of the robot's own skills (a verb) and its parameters"]
    Q["quackd<br/>checks the rules: allowed? budget left? needs confirmation?<br/>then runs the verb"]
    R["Robot or simulator<br/>executes the skill with its own controllers<br/>(walking, grasping and looking are not the LLM's job)"]
    O["quackd observes the result<br/>new camera frame, new state"]
    YOU --> LLM --> Q --> R --> O
    O -- "next verb, until done or impossible" --> LLM

The verbs the model can pick from are the robot's real, existing capabilities and nothing more. They come from its manifest, and a verb that is not in the manifest does not exist:

Kind Verbs What they are
Core observe report_state stop say move go_to search_scan approach_and on any robot whose manifest satisfies their requirements (a camera, a twist intent, a sound intent)
Microduck sit stand stand_up kick grab gaze quack one each per behaviour the robot ships with, each an intent the robot's own controllers execute
Reachy Mini gaze express play_sound wake_up a stationary head that looks, expresses and plays sounds. wake_up moves every joint, so it is confirm gated. The SDK has no text to speech, so say is voiced as the closest expression
LeRobot arm move_joints gripper place pick an SO-101 class arm. pick is one skill intent the arm's own learned policy executes, confirm gated and present only when a policy is loaded
rosbridge base (core only) a wheeled base over ROS 2. It gets move, stop and report_state, plus observe, go_to, search_scan and approach_and once an image topic is configured
Open Duck Mini v2 gaze express quack a 42 cm biped. No sit, no kick, no stand_up: its runtime has no such skill, so the verb does not exist rather than being refused
XLeRobot move_joints gripper a dual-arm cart. The arm joints are a normalised -100..100 range, not degrees, and gripper takes a side because there are two of them
AlohaMini lift move_joints gripper home_arms two arms on a motorised lift. The arm verbs refuse until quackd's own host wrapper is running on the robot, because upstream's leaves the arms limp
ToddlerBot look stand perform grip a humanoid. look turns a two joint neck, stand slews to the safe pose and is not a way up from a fall, and perform plays only the keyframe motions the daemon actually loaded. grip appears on the gripper builds, which carry two more motors
Aliases get_frame walk_to walk the 0.3 names of observe, go_to and move. They keep working in every .duck file
Learned (none yet) v2: policies trained from LLM written rewards, registered like any other verb

go_to (still spelled walk_to in the older starter files) is a small closed loop in plain Python that steers toward whatever the camera sees, ten times a second, without asking the model. The LLM says "go to the ball" and never "turn 4° left". The same code steers a duck, a cart and a wheeled base, clamped to each manifest's speed limits. On a head that cannot walk, go_to does not exist and search_scan sweeps the head instead of turning the body.


Example

A find-and-kick run in the cartoon simulator, from its transcript (runs/<timestamp>-find-and-kick/transcript.jsonl). This one is the scripted pilot, so model says so and usage is an estimate from character counts (no tokenizer). A real provider records the API's own counts.

{"kind": "llm",  "step": 0, "tool_calls": [{"name": "search_scan", "arguments": {"target": "ball"}}], "usage": {"input_tokens": 689, "output_tokens": 16}}
{"kind": "verb", "step": 1, "name": "search_scan", "ok": true, "summary": "ball found: ball at bearing 18° left ~0.58 m (after 4 turn steps)"}
{"kind": "llm",  "step": 1, "tool_calls": [{"name": "walk_to", "arguments": {"target": "ball", "stop_distance": 0.22}}]}
{"kind": "verb", "step": 2, "name": "walk_to", "canonical": "go_to", "ok": true, "summary": "reached the ball: ~0.22 m away, bearing +0°", "data": {"distance_m": 0.217, "ticks": 27}}
{"kind": "llm",  "step": 2, "tool_calls": [{"name": "kick", "arguments": {"leg": "right"}}]}
{"kind": "verb", "step": 3, "name": "kick", "ok": true, "summary": "kicked with right leg, ball moved 0.53 m"}
{"kind": "llm",  "step": 3, "tool_calls": [{"name": "quack", "arguments": {"text": "yay, got it!"}}]}
{"kind": "llm",  "step": 4, "tool_calls": [{"name": "declare_success", "arguments": {"reason": "ball displaced by the kick"}}]}

The same thing as a conversation, through MCP in Claude Code or Claude Desktop:

You: List the duck's verbs, then find the ball and kick it. Claude: (calls robot_list_verbs, robot_observe, robot_run_verb("search_scan"), robot_run_verb("go_to"), robot_run_verb("kick"), robot_say) Done. The ball moved about half a metre.


Status

Version 0.7, simulator and mocks. What has been built, and how far each piece has actually been exercised:

Piece Status
sim2d bundled simulator (default) ✅ 10 of 10 seeds on find-and-kick, GIF and transcript per run
mujoco physics simulator (quackd[mujoco]) ✅ 10 of 10 seeds on find-and-kick twice over: once on the kinematic stand-in and once with the duck walking on upstream's own trained policy, both ground truth checked, and both named tests rather than remembered numbers. The trained-gait sweep needs upstream's model in the cache, so a nightly job runs it and the gating job on every push runs the stand-in. The model and the policy are fetched from upstream at a pinned commit and hash checked, never shipped
Browser demo (web/) 🧪 the same physics, the same two upstream policies, seven of the same verbs and the same allowlist-and-budget machinery in a static page, with the sentence box and the keyboard live on one duck at the same time. Bring your own key, or point it at Ollama. CI checks what it can without a browser (the ids the script looks up, the pins and gait numbers it shares with Python, each module's syntax, the argument validator run un

quackd (rokbenko/quackd)

Searching Database…

263 ·GitHub
What is this?quackd is an open-source daemon that gives small robots a brain: it takes a goal in plain language and plans the right sequence of the robot's own existing skills to carry it out, using an LLM like Claude, OpenAI, Gemini, Grok or a local model.
Does the brain run on the robot, or somewhere else?The brain runs off the robot entirely, on your laptop or in the cloud, while the robot stays small and only executes the skills it already has (walking, kicking, gripping, etc).
How do I try it without owning a robot?You don't need any hardware: quackd ships with a MuJoCo physics simulator and an instant-start cartoon simulator, and there is also a hosted browser demo you can open with no install at all.
Which LLMs can drive the robot, and do I need an API key?Claude, OpenAI, Gemini and Grok work over their APIs, while open-source models run locally through Ollama, vLLM, llama.cpp or LM Studio with no API key needed.
Has quackd actually been tested on real hardware?No, not yet: every one of the eight supported robots has so far only been driven through a simulator or a mock, not a physical robot.
What is a .duck file?A .duck file is a task file written in plain language that states a goal for the robot; quackd reads it (or a chat message) and plans the sequence of the robot's own skills needed to reach that goal.
Can multiple robots work together?Yes, quackd has a flock mode where several robots split a goal between them, for example having the closest duck kick a ball while another watches and judges.
Can I control the robot from inside Claude Code or Claude Desktop?Yes, quackd ships with an MCP server so Claude Code or Claude Desktop can list a robot's verbs, send it a goal, and drive one robot or a fleet interactively through chat.
Why did the author build quackd?Rok Benko built it to give cheap, open-source robots like the Microduck an outside brain that turns a spoken goal into real actions, comparing it to the leap ChatGPT made for LLMs by putting them in an everyday chat interface.
Creator
rokbenko
Size
23.2 MB
Stars
263
Age
1mo
Commits · 90 Days