Describe it.Rebind builds it.
Rebind is an input platform for your computer. Tell your AI agent what your keyboard, mouse and controller should do, and it writes the script for you.
windows / macos
❯ in figma only, make caps lock flip between the hand and move tools
● Write(figma-tools/main.luau)
-- rebind: process=Figma
local hand = false
rb.bind("CapsLock", rb.async(function()
hand = not hand
rb.hid.press(if hand then "H" else "V")
end))
● Bash(rebind check figma-tools)
⎿ ok manifest / modeline / require graph (1 module) / compile / permissions
● Done. Caps Lock flips Hand and Move in Figma only.
❯ works great, can you save it to autostart for me?
● rebind - screenshot_window (MCP)(title: "Rebind")
⎿ Scripts > figma-tools > Options, Auto-start off
● rebind - click (MCP)(x: 1184, y: 412)
⎿ landed on Auto-start; it now reads on
● Autostart is on, so figma-tools now loads every time Rebind starts. It only acts while Figma is your active window.❯ watch me play this fishing game, then write a rebind script that fishes in a loop ● rebind - observe_start (MCP) ⎿ recording keys, clicks and frames ● rebind - observe_events (MCP) ⎿ 3 casts: hold Mouse1 1.2s, wait for the dip, click to reel ● rebind - observe_frame (MCP)(file: crops/000041.png) ⎿ the bobber dips, a splash where it sat ● Write(fishing-loop/main.luau) ● Bash(rebind run fishing-loop) ● fishing-loop casts, waits for the dip, reels in and casts again. F8 stops it.
❯ which tool is active in figma? ● rebind - list_windows (MCP)(filter: "Figma") ⎿ Figma process Figma "Design system" 1440x900 ● rebind - screenshot_window (MCP)(title: "Figma") ⎿ 1440x900, toolbar in view ● Move is active: V is lit in the toolbar.
❯ publish figma-tools to the rebind marketplace ● Bash(rebind pack figma-tools) ⎿ packaged figma-tools.rbp (3 files, 850 B) ● Bash(rebind publish figma-tools) ⎿ submitted figma-tools v0.0.1 for review ● It's on its way to the marketplace. You wrote no code.
Rebind is a crowbar for the USB stack.
- Your firmware has opinions. Your Luau scripts outrank them.
- Vendor software lets you select behavior. Rebind lets you write it.
- The defaults came preinstalled. Authority did not.
Scripts run on your computer and decide what every key, click and button does. With Rebind Link, their output leaves a real USB device.
-- left stick moves the mouse (hardware mode)rb.on("axis", function(axis, value) -- tilt -1 to 1 moves up to 10 px per event local d = math.round(value * 10) if axis == "LeftX" then rb.hid.move(d, 0) end if axis == "LeftY" then rb.hid.move(0, d) endend)-- Ctrl+B types a message, one key at a timerb.bind("Ctrl+B", rb.async(function() -- rb.async lets typewriter wait between keys rb.hid.typewriter("brb, two minutes", 90)end))
Left stick moves the mouse
How it works
Your devices go through Rebind first.
With Rebind Link, your USB devices are forwarded into a hypervisor instead of your OS. Rebind decodes every event in Rust, runs your script on it, and Link sends the result to your computer as real USB.
Mice, keyboards, controllers
As many as you already own, plugged in as usual.Processed in a hypervisor
Rebind hands your devices to a hypervisor, which reads their raw input before your OS can.Decoded in Rust
Every key, click, axis and button becomes an event your Luau script can read, change or drop.Out as real USB
Link sends the result to your computer as a USB keyboard, mouse or gamepad.
Without Link, software mode reads input through your OS instead, and mouse movement can't be blocked there.
Luau SDK
Any button can become any key, click or stick.
Scripts are Luau, the fast, typed Lua from Roblox. Think of an AutoHotkey macro that runs on Windows and macOS, sees input before your apps do, and can drive real USB hardware.
-- rebind: min_sdk=3.9.0 -- rebind: name=Push to Talk -- rebind: version=1.0.0 rb.on("down", function(key) if key == "Mouse4" then rb.hid.down("F13") return false end return true end) rb.on("up", function(key) if key == "Mouse4" then rb.timer.after(250, function() rb.hid.up("F13") end) return false end return true end)
Hold the side button to talk. Let go and the mic stays open a quarter second longer, so your last word never gets clipped.
-- rebind: min_sdk=3.9.0 -- rebind: name=Copy and Paste -- rebind: version=1.0.0 rb.bind.remap("Mouse4", "LCtrl+C") rb.bind.remap("Mouse5", "LCtrl+V")
Each side button holds its shortcut for as long as you hold the button. Only the two bound buttons are taken; every other key stays a real key.
-- rebind: min_sdk=3.9.0 -- rebind: name=Numpad Shortcuts -- rebind: version=1.0.0 -- rebind: hardware_only=true -- "numpad" is the keyboard's nickname in Peripherals. Its keys -- send shortcuts; the full-size keyboard's numpad still works as usual local shortcuts = { Kp1 = "LCtrl+Z", Kp2 = "LCtrl+LShift+Z", Kp3 = "LCtrl+S", } for key, chord in shortcuts do rb.bind(key, function() rb.hid.combo(chord) end, { device = "numpad" }) end
Needs hardware mode, with Rebind Link or BYOH, where Rebind tells keyboards apart. Give the numpad a nickname in Peripherals; the same keys on your full-size keyboard still work as usual.
-- rebind: min_sdk=3.11.0 -- rebind: name=Mouse Combo -- rebind: version=1.0.0 -- rebind: hardware_only=true -- one side button, two devices: the joypad holds left -- and taps B, then the mouse turns and clicks rb.bind("Mouse5", rb.async(function() rb.hid.axis("LeftX", -1) rb.hid.press("PadB", 60) rb.hid.joypad_reset() rb.hid.move(400, 0) rb.sleep(30) rb.hid.press("Mouse1", 40) end))
Needs hardware mode and a Rebind Link whose USB profile includes a joypad. The side button plays the joypad and the mouse in order, so a game sees one move across both.
-- rebind: min_sdk=3.11.0 -- rebind: name=Joypad Remap -- rebind: version=1.0.0 -- rebind: hardware_only=true rb.bind.remap("PadA", "PadB") rb.bind.remap("PadB", "PadA") rb.on("axis", function(axis, value) if axis == "LeftY" then rb.hid.axis("LeftY", -value) return false end end)
Needs hardware mode and a Rebind Link whose USB profile includes a joypad. The game sees the joypad, so the remap holds in every game.
Marketplace
One click, new behavior.
Install a script and it works: window snapping, pointer tuning, remote control for AI agents. From the app or the command line, no Luau required.

gaming
GCD Goblin for WoW Forever
World of Warcraft turbo keypress for Rebind: hold a key to auto repeat it, record a rotation and replay it with one key, plus anti-AFK.
streaming
Keystroke Overlay
A keyboard and mouse on screen that light up as you press them, for streams, recordings, and tutorials.
apps
Deskling: A Tiny Life
A cozy pixel neighbor with a house, routines, and a mind of their own — your stream's smallest main character.
utility
Dev Spy
See the pointer, window, and color under it while you write a script, record observations and macros, and try AI calls.
apps
Pocket Deck
Use your phone as a trackpad, media remote, and clipboard bridge.
productivity
break-coach
Timed posture and eye-break reminders with a calm countdown HUD.
gaming
Controller Map
A live controller tester that shows buttons, axes, and Rebind input names.
productivity
Hydration Tracker
A daily water counter with a compact HUD and one-key logging.
Rebind Link
MITM yourself.
Every keypress, click, and movement passes through your code before any app sees it.
8000hz
Eight times the report rate of a 1000hz gaming mouse.
Optional hardware for the free software: your scripts leave as a real USB keyboard and mouse, and as a joypad when its USB profile includes one.
Your peripherals.Your rules.
Rebind is free. Install it, start from an example, and write the behavior you want.