Skip to content

tejassudsfp/midicode

Repository files navigation

MIDICode

Turn your Akai MPK Mini into a macOS system controller. Map drum pads, knobs, joystick, and piano keys to keyboard shortcuts, app switching, volume control, media playback, and more.

Built for the MPK Mini 3, but works with any MIDI controller that sends standard note/CC/pitchwheel messages.

What it does

Input Action
Drum Pad 1 Previous tab (Cmd+Shift+[)
Drum Pad 2 Next tab (Cmd+Shift+])
Drum Pad 3 Cmd+Tab app switcher (hold + joystick to navigate)
Drum Pad 4 Wispr Flow voice control (hold=record, double-tap=hands-free)
Drum Pad 5 Play/pause music
Drum Pad 6 Open Spotify (configurable to any app)
Drum Pad 7 Delete key (repeats while held)
Drum Pad 8 Return/Enter
Knob 2 Next/previous track
Knob 3 System volume (0-100%)
Joystick Arrow keys (fires at extremes, repeats while held)
Piano keys Jump to tabs 1-9 (Cmd+1 through Cmd+9)

Everything is configurable via config.json.

Setup

Prerequisites

  • macOS (uses Quartz for key simulation)
  • Python 3.10+
  • An Akai MPK Mini (or any MIDI controller)

Install

git clone https://github.com/tejassudsfp/midicode.git
cd midicode
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

Grant Accessibility Access

System Settings → Privacy & Security → Accessibility → add your terminal app (Terminal, iTerm2, etc.)

This is required for simulating key presses.

Run

# Direct
source .venv/bin/activate
python3 midi_controller.py

# Or use the launcher
./start.sh

# Menu bar app (shows in top bar, click to start/stop)
./start-menubar.sh

Useful flags

python3 midi_controller.py --list    # List available MIDI devices
python3 midi_controller.py --scan    # See raw MIDI input from your controller

Configure with Claude

This project is designed to be configured using Claude Code. Just tell Claude what you want each button to do:

"Map pad 5 to open Safari and pad 6 to mute/unmute"

Claude will read the CLAUDE.md file in this repo and understand the full architecture, then modify config.json and midi_controller.py for you.

How it works

  • MIDI input via mido + python-rtmidi
  • Key simulation via pyobjc-framework-Quartz (CGEvents)
  • Media keys via NSEvent system-defined events
  • Menu bar via rumps

All key presses use kCGEventSourceStatePrivate to prevent modifier leaking (e.g., Cmd not bleeding into arrow keys). Wispr Flow uses kCGEventSourceStateCombinedSessionState specifically because it needs to see system-level modifier state.

Auto-start on login

# Create a LaunchAgent
cat > ~/Library/LaunchAgents/com.midicode.plist << 'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.midicode</string>
    <key>ProgramArguments</key>
    <array>
        <string>/path/to/midicode/start-menubar.sh</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
</dict>
</plist>
EOF

# Load it
launchctl load ~/Library/LaunchAgents/com.midicode.plist

Replace /path/to/midicode/ with your actual path.

Built with

  • Claude Code — AI pair programmer that wrote and configured this entire project
  • Wispr Flow — voice-to-text dictation (Pad 4 triggers push-to-talk and hands-free modes)
  • Akai MPK Mini — the MIDI keyboard this was designed for

This project was built entirely through voice (Wispr Flow) and AI (Claude Code) — no manual typing.

License

MIT License — see LICENSE.

Created by Tejas Sudarshantejas@fandesk.ai

About

Use any MIDI Controller to Code

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors