C3PO, part 1: Claude Code drives a robot in Isaac Sim
I’m giving Claude a body.
The project is called C3PO, and it started as a school project. Frontier LLMs can reason and use tools, humanoid robots have become capable hardware, and hardly anyone connects the two. I wanted to. The end goal is a real Unitree G1 humanoid that perceives, decides, and moves in the physical world with Claude in control. The G1 costs real money and can break, so I started in simulation.
The dumbest thing that could work
The first implementation is deliberately crude. It has three pieces:
- Isaac Sim on a separate Ubuntu host, running a G1
- A Python bridge that exposes the robot’s controls as MCP tools and talks DDS (CycloneDDS and Unitree’s SDK) to the sim
- Claude Code as the brain
Using Claude Code as the brain meant I didn’t have to write a UI, a backend, or any orchestration code. The bridge is an MCP server registered in the project’s .mcp.json, so any Claude Code session opened in the repo gets tools like walk_to and get_state next to its normal file tools. I type what I want in the terminal, and Claude calls robot tools the same way it usually calls grep.
The core tools are get_state, walk_to, turn, and stop_everything. get_state streams live pose, battery, posture, and faults from the sim at about 100 Hz. walk_to runs a velocity control loop toward a world coordinate, with a minimum stop distance so the robot doesn’t faceplant into things. stop_everything cancels every running task and sets velocity to zero. The rest of the twenty tools cover the G1’s built-in postures and gestures, such as sit, squat, wave, shake hands, and hug.
It works end to end. The robot walks a meter or two per command, turns 90° or 180° on request, and reports its position the whole time.
It’s also full of the quirks that make robotics fun. The sim’s walk policy is so conservative that the effective forward speed is 10 to 15% of what you command. DDS multicast doesn’t work reliably on macOS, so the bridge writes a unicast peer config by hand.
You can watch it reason about the gap between what it asked for and what it got: “moved 0.74 m of the 1 m target before reaching stop_distance”, and on the turn, “total 177° — within 3° of the 180° target, finished cleanly.”
What I learned
MCP turns out to be a good robotics interface. Skills are just tools with JSON schemas, and the model never needs to know DDS topics or firmware modes exist. Because a frontier model was driving from day one, I could test the whole skill interface in hours instead of weeks.
Next
Using Claude Code as the driver was only a way to get started. The control flow lives inside a coding tool on my laptop, and nobody else can use it. The next step is to move the agent into a proper backend with a real interface. That’s part 2.
The whole thing is open source: github.com/mercho40/C3PO.