keybridged is a Go HTTP daemon that sends key events to hardware bridges over UART or USB CDC. It is the companion backend for bridge firmwares:
- PicoUSBKeyBridge (UART -> USB HID keyboard)
- NordicBTKeyBridge (USB CDC -> BLE HID keyboard)
If you’re deciding which bridge to use:
- Need a wired USB keyboard presented to the target host → PicoUSBKeyBridge
- Need a Bluetooth LE keyboard presented to the target host → NordicBTKeyBridge
- Keeps a persistent connection to the bridge’s serial transport (USB CDC or a USB-to-UART adapter).
- Retries forever and logs device output to stdout.
- Exposes a small HTTP API for sending key events.
go run github.com/2opremio/keybridged/cmd/keybridged@latest
macOS deployment:
./scripts/deploy_macos.sh
Flags:
-host(default:localhost)-port(default:9876)-send-timeout(default:2) seconds to wait when queueing an event-vid(default:0x1915) USB VID for the serial transport device-pid(default:0x520F) USB PID for the serial transport device
Note: these flags do not refer to the HID keyboard identity (USB HID VID/PID or BLE PnP ID). They are only used to locate the serial device that keybridged talks to.
Examples:
- NordicBTKeyBridge (nRF52840 USB CDC, default):
./keybridged -vid 0x1915 -pid 0x520F
- PicoUSBKeyBridge using an FT232 USB-to-UART adapter (example hardware):
./keybridged -vid 0x0403 -pid 0x6001
POST /pressandrelease sends a single event (press + release). If type is
omitted, it defaults to keyboard.
Request body:
{
"type": <string> ("keyboard"|"consumer"),
"code": <uint16>,
"modifiers": {
"left_ctrl": <bool>,
"left_shift": <bool>,
"left_alt": <bool>,
"left_gui": <bool>,
"right_ctrl": <bool>,
"right_shift": <bool>,
"right_alt": <bool>,
"right_gui": <bool>,
"apple_fn": <bool>
}
}
type:"keyboard": standard key presses (letters, numbers, modifiers, function keys)."consumer": media/system controls (volume, play/pause, keyboard layout toggle).
codeis a HID usage ID. See the on-wire details and code references in the serial protocol docs: PicoUSBKeyBridge#serial-protocol.keyboard: USB HID Keyboard/Keypad keycode (8-bit; the JSON field isuint16for convenience).code: 0means "modifier-only" (no key pressed).consumer: USB HID Consumer Page (0x0C) usage (16-bit).
- Keyboard modifiers (optional, macOS symbols/Apple names):
left_ctrl(⌃ Ctrl),left_shift(⇧ Shift),left_alt(⌥ Option),left_gui(⌘ Command)right_ctrl(⌃ Ctrl),right_shift(⇧ Shift),right_alt(⌥ Option),right_gui(⌘ Command)apple_fn(Fn) sets the Apple Fn bit in the keyboard report
If there’s demand, we can add a WebSocket API for more efficient key-event streaming than one HTTP request per key, and for real-time device log streaming.
Send letter A (a (HID code 4) + Shift):
curl -X POST "http://localhost:9876/pressandrelease" \
-H "Content-Type: application/json" \
-d '{"type":"keyboard","code":4,"modifiers":{"left_shift":true}}'
Hide/show iPad keyboard (AL Keyboard Layout / consumer usage 0x01AE):
curl -X POST "http://localhost:9876/pressandrelease" \
-H "Content-Type: application/json" \
-d '{"type":"consumer","code":430}'
Play/Pause (consumer usage 0x00CD):
curl -X POST "http://localhost:9876/pressandrelease" \
-H "Content-Type: application/json" \
-d '{"type":"consumer","code":205}'
Send only Apple Fn (modifier-only, no key):
curl -X POST "http://localhost:9876/pressandrelease" \
-H "Content-Type: application/json" \
-d '{"type":"keyboard","code":0,"modifiers":{"apple_fn":true}}'
There is a small Go client in client/ for calling the HTTP API.
package main
import "github.com/2opremio/keybridged/client"
kbClient := client.New(client.Config{
Host: "localhost:9876",
})
err := kbClient.SendPressAndRelease(ctx, client.PressAndReleaseRequest{
Type: "keyboard",
Code: 0x04,
Modifiers: &client.PressAndReleaseModifiers{
LeftShift: true,
},
}) // A with ShiftSerial protocol documentation lives in PicoUSBKeyBridge#serial-protocol.