Geary has a rig, and now he takes my Meet calls
We commissioned a rigged 3D model of Geary, the Utility Materials mascot. Last night it became GEARY CAM, a Chrome extension that puts him in my Google Meet tile, blinking when I blink.
Geary is the mascot of Utility Materials. He's a maintenance unit with a gear for a head, orange overalls and a pair of sunglasses parked on his brim. He shows up in the UMI app and in our films, and as of yesterday he shows up to my calls.
The rig
We commissioned a rigged 3D model of Geary so he could move.
The file still lives in our Google Drive, next to a little family of variants: a toon-shaded one, one with a guitar, one in a T-shirt, one set up for motion capture. It's a Blender 4.1 file with a 28-bone skeleton and a body skinned to it, so turning a bone moves the mesh with it. It also has four shape keys on the face: eyes closed, mouth open, eyes left and eyes right.

For a long time the rig mostly sat in that folder. On October 15 I was building a 3D maintenance unit for the UMI app, with Claude Code driving Blender through an MCP server. It started by modeling a robot from scratch in a Python script, a tracked maintenance unit with a bent antenna and a cracked right lens. After its second pass I told it to use the Geary rig already in Drive.
An hour later the robot was gone. The build script appends the skeleton and body from the original file without editing it, bakes the procedural materials into one texture atlas, keeps the glass in his eyes transparent and exports the result for iOS. Before midnight he also had a home screen widget.
The app and the widget both pose those same 28 bones. Six days later GEARY CAM did too.
GEARY CAM
On October 21 I typed this into Claude Code: "can we make a 'vtuber' skin google meet effect with our rigged geary?"
Meet's camera menu now has an entry called GEARY CAM, listed next to my FaceTime camera. When I pick it, Geary takes my tile. His head turns and tilts with mine, his eyes blink when I blink and his mouth moves when I talk. When I raise a hand he raises his, with an open palm, a fist or a wave. It all runs in real time in Chrome on my Mac. Nothing is installed at the system level, there are no API keys, and no network service is involved.
The extension adds a fake camera to the list of devices Meet sees. When Meet asks for that camera, the extension opens my real webcam from inside Meet's page and passes small frames to a hidden iframe that belongs to the extension. That iframe runs MediaPipe's Face Landmarker on the GPU, smooths every signal with one-euro filters, poses Geary's bones in three.js and paints the background and a UMI // MAINTENANCE UNIT lower third. Finished 1280 by 720 frames go back to Meet at 30 frames per second. Hand tracking runs MediaPipe's Hand Landmarker in a Web Worker on its own thread.
The mapping is all rotation. Nothing scales or stretches. The head bone takes 75 to 88 percent of a turn and the torso takes the rest, so he turns like someone with a body. His mouth stops at 72 percent open to stay on model. The first twenty or so tracked frames set his neutral pose, because a laptop camera looks up your nose. No new shape keys were needed. The four in the commissioned rig covered blinking, talking and looking around.
The face in the demo footage belongs to nobody. Claude generated it with an image model so it could test turns, blinks and talking without me sitting in front of the camera.

The first commit landed at 5:45 that evening and the eighth at 6:34.
What broke on the way
The first live test in Meet showed GEARY CAM in the menu and then sat on its boot card. Meet only lets meet.google.com itself use the camera, so an iframe from the extension can't open it. That's why the webcam now opens inside Meet's page and only the rendering happens in the iframe.
Once that worked, the boot card came back. Meet asks for the remembered camera while it loads and then rebuilds the page's <body>, which deleted the renderer along with everything else. The renderer now hangs off <html>, and a watchdog reattaches it if it goes missing. The test page that stands in for Meet rebuilds its body the same way, and the old code fails it.
MediaPipe's library always sends a usage ping to a Google endpoint and has no setting to turn it off. The renderer's content security policy blocks it, and the tests check that it's refused.
Meet mirrors your own preview. Geary turned the opposite way from my reflection, so mirroring is now the default, with a switch in the toolbar popup.
When hands went in, my first note was one word, "CLIPPING." His arms are about 8.5 cm long and his gear head is about 11 cm in radius, so a hand raised beside his head always ended up behind the gear. A raised arm now goes out at shoulder height, where the gear is narrowest, swings 24 degrees forward and bends the hand up at the wrist. Claude checked it from the front, at three quarters and from both sides.
On the main loop, hand tracking cost 8 frames per second whenever the machine was under load. In the worker the loop holds 30, with an Xcode build and an iOS Simulator running in other sessions.
Then I tested it live and sent my review:
VTUBER GOOD BUT FISTS CLOSE BACKWARDS
With his palm facing the camera, the finger curl had the wrong sign, so his fingers folded toward his back. The sign is flipped now, the thumb wraps across the front of the fist, and the resting hands didn't change.

The last step is one Claude can't do. Branded Chrome has ignored the --load-extension flag since version 137, and the browser extension Claude uses can't open chrome:// pages. So I clicked Load unpacked myself, once, and picked GEARY CAM in Meet's video settings.
When I leave the frame he holds still for half a second, eases back to center and idles. He breathes, and every few seconds he blinks on his own.