"Coding never changes. But your input device just did."
Vibe-code from your couch. Connect your Xbox Wireless Controller to Claude Code via MCP. Approve with A, deny with B, interrupt with X. Execute fighting game combos to commit+push. Feel haptic feedback when Claude finishes thinking.
macOS + SDL2:
brew install cmake sdl2claude mcp add claudepad -- npx -y claudepadThat's it. Restart Claude Code and connect your Xbox controller via Bluetooth.
npx claudepad-test| Button | Action | Description |
|---|---|---|
| A (green) | Approve | y + Enter |
| B (red) | Deny | n + Enter |
| X (blue) | Interrupt | Ctrl+C |
| Y (yellow) | Skip | Escape |
| LB | Scroll Up | tmux page up |
| RB | Scroll Down | tmux page down |
| D-pad | Navigate | Arrow keys |
| Menu | Confirm | Enter |
| View | Interrupt | Ctrl+C |
| Xbox | Voice Input | /voice + Enter |
| L3 | Autocomplete | Tab |
| R3 | Slash Commands | / |
Fighting game input sequences trigger special actions:
| Combo | Sequence | Window | Action |
|---|---|---|---|
| Hadouken | Down, Right, A | 500ms | git commit + push |
| Shoryuken | Right, Down, Right, B | 600ms | Reset conversation |
| Quick Approve | A, A | 300ms | Double approve |
| Turbo Mode | LB + RB | 200ms | Toggle turbo |
| Konami Code | Up Up Down Down Left Right Left Right B A | 3s | Rainbow rumble |
Your controller vibrates to communicate state — no need to look at the screen.
| Pattern | Feel | When |
|---|---|---|
success |
Gentle double pulse | Task completed |
error |
Hard long buzz | Something broke |
warning |
Medium single pulse | Heads up |
approval_prompt |
Triple tap rhythm | Claude needs input |
task_complete |
Rising crescendo | Major milestone |
combo_activated |
Sharp snap | Combo detected |
voice_start |
Light click | Voice recording started |
rainbow |
Wave crescendo | Easter egg activated |
Xbox Controller --Bluetooth--> macOS SDL2 --> GamepadManager
|
+---------+---------+
| |
ButtonMapper ComboDetector
|
KeystrokeInjector
(tmux / osascript)
|
Claude Code
When running as an MCP server, Claude gains access to:
| Tool | Description |
|---|---|
gamepad_get_state |
Read button/axis/connection state |
gamepad_wait_button |
Block until a specific button press |
gamepad_get_analog |
Read analog stick and trigger values |
gamepad_rumble |
Send haptic feedback (preset or custom) |
gamepad_wait_combo |
Wait for a combo input |
gamepad_configure_mapping |
View or update button mappings |
Run standalone (no MCP, just keystrokes):
npx tsx src/daemon.tsOr install as a persistent launchd service:
cp com.claudepad.daemon.plist ~/Library/LaunchAgents/
launchctl load ~/Library/LaunchAgents/com.claudepad.daemon.plistnpm test # Run tests
npm run test:watch # Watch mode
npm run dev # Dev mode with file watchingTypeScript + tsx | @modelcontextprotocol/sdk | sdl2-gamecontroller (SDL2 native addon) | zod | vitest | tmux
See CONTRIBUTING.md.