botblocks
projectsgalleryworkspacedocsprofile
botblocks
robots in 10 lines of python. simulate, train and iterate, then run the same code on real hardware.
write any script
no launch files, ros graph, or build step needed.
pickup
teleop
train
drive
from botblocks import *
import time

so101 = Robot().load('public/so101')
things = [so101, Plane(), Box(pos=[0.22, -0.1, 0], size=0.03)]

@so101.loop
def _(bot, env):
    bot['jaw'].target(1)
    bot['arm'].lineto([0.2, -0.1, 0.06], aim=[0, 0, -1])
    bot['arm'].lineto([0.2, -0.1, 0.02], aim=[0, 0, -1])
    bot['jaw'].target(0)
    time.sleep(0.5)

    bot['arm'].lineto([0.2, 0.1, 0.06], aim=[0, 0, -1])
    bot['arm'].lineto([0.2, 0.1, 0.02], aim=[0, 0, -1])
    bot['jaw'].target(1)
    time.sleep(0.5)
    # then back...

MujocoEnv(things).start()
use any backend
full physics, the reported state of real servos, or 32 robots at once
MujocoEnv([Plane(), robot]).start()
ViewerEnv([robot], providers=[ServoSTS]).start()
GymEnv([robot]).train(n=32)
develop anywhere
editor, viewer and console in the browser
Image
run any robot
import a .step or .urdf, or pick from 50+ in the gallery
connect any agent
every subsystem is an mcp tool, at botblocks.dev/mcp
you
put the pink cube on the blue one
tool
so101_grip_cam_snap_img {}
tool
so101_arm_describe {}
bot
gripper is 8cm above the cube. descending straight down...
tool
so101_arm_goto {"pos":[0.28,-0.12,0.04]}
tool
so101_jaw_target {"pos":0}
configure any assembly
drag parts into place, then attach subsystems
build any scene
shapes, robots and 3d models in one env
MujocoEnv([
    Plane(),
    Asset('pusht/base.glb', fixed=True),
    Box(pos=[.22, -.1, .02], size=.03),
    Robot().load('public/so101'),
]).start()
investigate any run
every run is a replay: scrub it, step it, read back cameras and metrics
play
train any model
ppo over a sharded sim, reward curves streaming as it runs
gym = GymEnv([Plane(), bot], subsys=[bot])
gym.train(n=32) # writes ./policy

pi = Policy('./policy', [bot])
while True: pi.step()
run any eval
pusht, leslider and all 130 libero tasks, scoring a policy or an agent
ev = Libero.random()

@ev.robot.ready
def solve(bot, env): ...

print(ev.attempt(timeout=120))
deploy to any server
with cli support coming soon
bun install -g botblocks
botblocks run script.py
botblocks deploy train.py --size gpu
sign up for updates