Technical Appendix & Errata
This appendix provides detailed technical documentation for developers and power users interested in the inner workings of MBXRemote and the ARiA protocol.
ARiA Protocol Architecture
The ARiA (Arbitrary Remote Initiated Actions) system is a command-agnostic transport protocol. The protocol itself doesn't interpret commands - it simply transports action scripts from client to server for execution.
[MBXRemote Client] ──TCP/JSON──> [MusicBee Plugin] ──Execute──> [Windows/MusicBee]
| | |
Action Script Command-Agnostic SendKeys/Commands
"sndKeys(CTRL ALT Q)" Transport ExecutionProtocol Message Format
{
"context": "playerinitiatoraction",
"data": "sndKeys(CTRL ALT Q)"
}\r\nThe data field contains an action script string passed unchanged to the plugin's execution engine. The protocol layer never parses or validates this content.
SendKeys Notation Reference
ARiA uses .NET System.Windows.Forms.SendKeys notation for keyboard automation.
Modifier Keys
| Modifier | SendKeys Symbol | ARiA Notation |
|---|---|---|
| Control | ^ | CTRL or CONTROL |
| Alt | % | ALT |
| Shift | + | SHIFT |
| Windows | # (unofficial) | WIN or WINDOWS |
Special Keys
| Key | Syntax |
|---|---|
| Enter | {ENTER} or ~ |
| Tab | {TAB} |
| Escape | {ESC} |
| Backspace | {BACKSPACE} or {BS} |
| Delete | {DELETE} or {DEL} |
| Arrow Keys | {UP} {DOWN} {LEFT} {RIGHT} |
| Page Up/Down | {PGUP} {PGDN} |
| Home/End | {HOME} {END} |
| Function Keys | {F1} through {F24} |
| Space | {SPACE} or literal space |
| Insert | {INSERT} |
| Print Screen | {PRTSC} |
| Caps Lock | {CAPSLOCK} |
| Num Lock | {NUMLOCK} |
| Scroll Lock | {SCROLLLOCK} |
| Break | {BREAK} |
| Application/Menu | {APPS} |
Key Repeat Syntax
{TAB 3} // Tab 3 times
{RIGHT 5} // Right arrow 5 times
+{RIGHT 5} // Shift+Right 5 times (select 5 characters)DuckyScript Notation
As an alternative to SendKeys symbols, ARiA also accepts DuckyScript-style notation for key combinations - a more readable, space-separated format.
DuckyScript vs SendKeys
| Action | SendKeys Notation | DuckyScript Notation |
|---|---|---|
| Ctrl+Alt+Q | sndKeys(^%q) | sndKeys(CTRL ALT Q) |
| Ctrl+Shift+Delete | sndKeys(^+{DELETE}) | sndKeys(CTRL SHIFT DELETE) |
| Alt+F4 | sndKeys(%{F4}) | sndKeys(ALT F4) |
| Ctrl+A | sndKeys(^a) | sndKeys(CTRL A) |
| Windows+R | sndKeys(#{r}) | sndKeys(GUI R) or sndKeys(WIN R) |
DuckyScript Modifiers
| Modifier | DuckyScript | SendKeys Equivalent |
|---|---|---|
| Control | CTRL or CONTROL | ^ |
| Alt | ALT | % |
| Shift | SHIFT | + |
| Windows | GUI or WIN or WINDOWS | # |
DuckyScript Examples
sndKeys(CTRL ALT A) // MusicBee Goto Tab 1 sndKeys(CTRL ALT S) // MusicBee Goto Tab 2 sndKeys(CTRL ALT L) // MusicBee Goto Tab 9 sndKeys(CTRL SHIFT DELETE) // Ctrl+Shift+Delete sndKeys(ALT F4) // Close window sndKeys(GUI R) // Windows Run dialog sndKeys(CTRL A);delay(100);sndKeys(CTRL C) // Select all, copy
Both notations can be used interchangeably. Use whichever is more readable for your use case.
Complete Key Mapping Reference
| Key/Action | SendKeys | DuckyScript |
|---|---|---|
| Ctrl+A | ^a | CTRL A |
| Alt+F4 | %{F4} | ALT F4 |
| Shift+Tab | +{TAB} | SHIFT TAB |
| Ctrl+Alt+A | ^%a | CTRL ALT A |
| Ctrl+Shift+Esc | ^+{ESC} | CTRL SHIFT ESCAPE |
| Win+D | #{d} | GUI D or WIN D |
| Win+R | #{r} | GUI R or WIN R |
| Enter | {ENTER} or ~ | ENTER |
| Tab | {TAB} | TAB |
| Escape | {ESC} | ESCAPE or ESC |
| Space | {SPACE} | SPACE |
| Backspace | {BACKSPACE} | BACKSPACE |
| Delete | {DELETE} | DELETE |
| Up Arrow | {UP} | UP |
| Down Arrow | {DOWN} | DOWN |
| Left Arrow | {LEFT} | LEFT |
| Right Arrow | {RIGHT} | RIGHT |
| F1-F12 | {F1} - {F12} | F1 - F12 |
| Home | {HOME} | HOME |
| End | {END} | END |
| Page Up | {PGUP} | PAGEUP |
| Page Down | {PGDN} | PAGEDOWN |
| Insert | {INSERT} | INSERT |
| Print Screen | {PRTSC} | PRINTSCREEN |
Focus Control Prefixes
Control whether MusicBee receives focus before sending keys:
| Prefix | Behavior | Use Case |
|---|---|---|
| (none) | Focus MusicBee first (default) | Tab navigation, MusicBee commands |
!mb! | Explicitly focus MusicBee | Same as default, explicit |
!nofocus! | Send to current focused window | Alt+Tab, system commands |
Examples
sndKeys(CTRL ALT Q) // Focus MusicBee, send Ctrl+Alt+Q (RIA1) sndKeys(!mb!CTRL S) // Explicitly focus MusicBee, save sndKeys(!nofocus!ALT TAB) // Alt+Tab without changing focus sndKeys(!nofocus!WIN D) // Show desktop (current window)
Windows Key Limitation
SendKeys class does NOT have native support for the Windows key. The # symbol is unofficially supported in some implementations but is not part of the standard.
For Windows key combinations, the plugin uses Windows API (P/Invoke) when WIN or # is detected:
WIN Dor#d- Show DesktopWIN Lor#l- Lock ComputerWIN Ror#r- Run DialogWIN TABor#{TAB}- Task View
MusicBee API Status
Working APIs
| Category | Status | Examples |
|---|---|---|
| Player Control | Working | Play, Pause, Stop, Next, Previous, Volume, Mute |
| Now Playing | Working | Track info, metadata, artwork, lyrics |
| Now Playing List | Working | Queue management, reorder, clear |
| Library | Working | Browse, search, tag reading/writing |
| Playlists | Working | Create, delete, modify playlists |
| Settings | Working | Storage paths, skin info |
Non-Working APIs
Navigation API
MB_InvokeCommand(Command.NavigateTo) does not work for tab switching. This is why ARiA uses SendKeys as a workaround.
Visualizer API EXPERIMENTAL
playervisualizer and playervisualizerlist commands require "Enable Experimental Features" to be checked in the plugin settings. These commands are implemented but may not work with all MusicBee configurations - MusicBee's API may return empty data.
ARiA Security Model
Plugin Version Requirement
ARiA requires plugin version 1.5+. The plugin version determines ARiA support:
| Plugin Version | ARiA Support |
|---|---|
| < 1.5 | Not supported (no response to ARiA commands) |
| >= 1.5 | Supported (responds with status) |
ARiA Command Responses (v1.5+)
When ARiA commands are sent to plugin 1.5+, the plugin responds with one of three values:
| Response | Meaning |
|---|---|
Ok | ARiA is enabled and command executed successfully |
Not Enabled | ARiA is disabled by user in plugin settings |
Error: [message] | Command failed with error details |
Enable/Disable Control
ARiA is controlled via a checkbox in the MusicBee Remote plugin settings:
- Location: MusicBee → Edit → Preferences → Plugins → MusicBee Remote → Configure
- Setting: "Enable ARiA (Arbitrary Remote Initiated Actions)"
- Default: Disabled (for security)
- Storage:
%APPDATA%\MusicBee\mb_remote\settings.xml
What Works When ARiA is Disabled
- Standard music controls (play, pause, next, previous)
- Volume control
- Library browsing
- Playlist management
- Now playing information
- All non-keyboard-automation features
Security Considerations
- System commands (Alt+F4, Ctrl+Alt+Del)
- Application control in any focused window
- Text input to any focused field
- Run dialog commands (Win+R)
Mitigations:
- ARiA disabled by default - explicit opt-in required
- Use firewall to restrict plugin access to local network only
- Never expose plugin port to internet
- Default focus behavior targets MusicBee (safer)
!nofocus!prefix required for system-wide control
Protocol Version History
| Version | Features | Plugin Version |
|---|---|---|
| v4.0 | Standard playback, library, playlists, now playing | Standard plugin v1.4.1 |
| v4.5 | ARiA, Initiator Actions, tab navigation, focus control, enhanced metadata (year/rating/bitrate/format), album navigation, podcasts | v1.5.x |
Protocol Negotiation
Plugin v1.5+ performs protocol negotiation based on client request:
- Client requests v4 → Server responds v4.0 (legacy mode, no extended metadata)
- Client requests v4.5 → Server responds v4.5 (extended metadata enabled)
This ensures backwards compatibility: legacy clients (Android/iOS v4.0) continue to work while modern clients (MBXRemote) get extended features.
Additive Fields (Always Sent)
These fields are always included regardless of protocol version:
AlbumCountinbrowseartistsresponseArtistCountinbrowsegenresresponse
Extended Metadata (v4.5 Only)
These fields are only included when v4.5 is negotiated:
year,rating,bitrate,format,playcount,skipcount,lastplayed,dateadded,lovedinbrowsetracksresponse
Library Metadata Sync
MBXRemote syncs library metadata from MusicBee to a local SQLite cache. This section documents the sync direction for each field.
Field Sync Direction
| Field | Direction | Status | Notes |
|---|---|---|---|
playcount | One-Way (MB → MBX) | ✅ Implemented | Read-only: Auto-incremented by MusicBee during playback |
skipcount | One-Way (MB → MBX) | ✅ Implemented | Read-only: Auto-incremented by MusicBee when skipped |
lastplayed | One-Way (MB → MBX) | ✅ Implemented | Read-only: Auto-updated by MusicBee during playback |
dateadded | One-Way (MB → MBX) | ✅ Implemented | Read-only: Set when file added to library, cannot be changed |
rating | Two-Way | ✅ Implemented | User-editable: Right-click → Set Rating (0-5 stars) syncs to MusicBee |
loved | Two-Way | ✅ Implemented | User-editable: Right-click → Love Status syncs to MusicBee |
playcount, skipcount, lastplayed, and dateadded are managed automatically by MusicBee and cannot be modified by external applications. These are always one-way sync (MusicBee → MBXRemote).
Sync Direction Legend
| Direction | Description |
|---|---|
| One-Way (MB → MBX) | Data flows from MusicBee to MBXRemote only. Changes in MBXRemote are not pushed back to MusicBee. |
| Two-Way | Data can be modified in MBXRemote and pushed back to MusicBee. Requires EnableTwoWaySync setting enabled. |
Remote Library Editing Settings
Remote library editing is controlled via Settings > Database > Remote Library Editing:
| Setting | Default | Description |
|---|---|---|
EnableTwoWaySync | false | Master toggle for all two-way sync |
EnableTwoWayRating | true | Enable rating sync to MusicBee |
EnableTwoWayLove | true | Enable love/ban sync to MusicBee |
EnableRealTimeSync | true | Subscribe to real-time library events |
Protocol Testing
MBXRemote includes a hidden Protocol Compatibility Tester for developers and advanced users to verify plugin compatibility.
Access the Protocol Tester
Press Ctrl+Shift+Alt+T in MBXRemote to open the Protocol Tester dialog.
Tests Performed
- Protocol Negotiation: Verifies v4 clients get v4.0 responses, v4.5 clients get v4.5
- Extended Metadata: Validates v4 excludes and v4.5 includes year/rating/bitrate/format
- ARiA Availability: Tests if ARiA is enabled (sends harmless
delay(1)command) - Browse Endpoints: Tests browseartists, browsegenres, browsealbums, browsetracks
- Additive Fields: Detects new fields like AlbumCount, ArtistCount
- Backwards Compatibility: Generates warnings if legacy clients might break
- Service Discovery: Tests UDP multicast discovery on 239.1.5.10:45345
- JSON Serialization: Validates Newtonsoft.Json format compatibility
XML/DB Comparison
The Protocol Tester also includes an XML/DB Comparison tool to validate cache integrity:
- Compare: MusicBee library XML export vs local SQLite cache
- Supported Formats: MusicBee XML, iTunes XML, generic XML
- Reports: Tracks only in XML, only in DB, and field differences
- Usage: Click "XML/DB Compare" button and select a MusicBee library export file
The tester generates detailed reports that can be saved to text files for analysis.
Troubleshooting Reference
Keys Not Working
- Verify MusicBee hotkeys are configured (Ctrl+Alt+Q through P for RIA1-10)
- Check plugin logs show "Sending keys:" messages
- Ensure no security software blocks SendKeys
- Verify ARiA is enabled in plugin settings
Wrong Window Receives Keys
- Use
!mb!prefix to ensure MusicBee focus - Check which window has focus before sending
- Add delays between focus change and key send
Debug Logging
Plugin logs are stored at:
%APPDATA%\MusicBee\mb_remote\
Key log entries to check:
"Executing action script: [script]" "Sending keys: [keys]" "Focused MusicBee window" "ARiA functionality is disabled"
Local Database Architecture
MBXRemote uses a local SQLite database for caching library data, enabling fast browsing and searching without constant network requests to MusicBee.
Technology Stack
| Component | Technology | Purpose |
|---|---|---|
| Database Engine | SQLite 3 | Lightweight, zero-config, file-based database |
| ORM | Entity Framework Core 8 | Object-relational mapping, LINQ queries |
| Connection Pooling | DbContextPool (128 connections) | Performance optimization for concurrent access |
| Settings Storage | JSON file | User preferences separate from cache data |
Database Location
%APPDATA%\MBXRemote\musicbee.db
Cached Entities
| Entity | Table | Key Fields | Indexes |
|---|---|---|---|
| Tracks | CachedTracks | Title, Artist, Album, AlbumArtist, Genre, Year, Duration, TrackNo, DiscNo, Bitrate, Rating | Title, Artist, Album, AlbumArtist, Genre, Year |
| Albums | CachedAlbums | Name, Artist, Year, TrackCount, CoverArtHash | Name, Artist, Year |
| Artists | CachedArtists | Name, AlbumCount, TrackCount | Name (unique) |
| Genres | CachedGenres | Name, ArtistCount | Name (unique) |
| Playlists | CachedPlaylists | Name, TrackCount, Duration | Name |
| Connections | Connections | Host, Port, Name, IsDefault, LastUsed | Host, IsDefault, LastUsed |
| Sync Metadata | SyncMetadata | DataType, LastSyncTime, TotalCount, CollectionHash | DataType (unique) |
Synchronization Strategy
Library data is synchronized from MusicBee on-demand:
- Full Sync: Downloads entire library on first connection or manual refresh
- Incremental Sync: Uses collection hash to detect changes
- Pagination: Large libraries synced in batches (default: 500 items per request)
- Progress Tracking:
SyncMetadatatable tracks last sync time, count, and duration
Virtual List Mode
For large libraries (200,000+ tracks), MBXRemote uses virtual list mode to avoid loading all data into memory:
- ListView only loads visible rows + buffer
- Database queries fetch data on-demand as user scrolls
- Supports libraries with millions of tracks without performance degradation
- Memory usage stays constant regardless of library size
Database Schema (EF Core)
// Entity Framework Core model configuration
public class MusicBeeContext : DbContext
{
public DbSet<CachedTrack> CachedTracks { get; set; }
public DbSet<CachedAlbum> CachedAlbums { get; set; }
public DbSet<CachedArtist> CachedArtists { get; set; }
public DbSet<CachedGenre> CachedGenres { get; set; }
public DbSet<CachedPlaylist> CachedPlaylists { get; set; }
public DbSet<Connection> Connections { get; set; }
public DbSet<SyncMetadata> SyncMetadata { get; set; }
}SQLite Connection String
Data Source=%APPDATA%\MBXRemote\musicbee.db; Mode=ReadWriteCreate; Cache=Shared; Pooling=True
Database Management
MBXRemote provides a Database Manager dialog (Settings tab) for:
- Viewing cache statistics (track/album/artist counts)
- Clearing cached data
- Forcing full re-sync
- Viewing sync history
musicbee.db and restart MBXRemote - it will rebuild the cache from MusicBee.
ETL Use Case: Library Data Export
MBXRemote's caching system functions as an ETL (Extract, Transform, Load) pipeline for MusicBee library data. The SQLite database can be used independently for:
- Data Analysis: Query your music collection with SQL
- Reporting: Generate statistics, play count reports, genre breakdowns
- Integration: Feed data into other applications (BI tools, scripts, web apps)
- Backup: Portable snapshot of library metadata
- Cross-Platform: Access MusicBee data from Linux/macOS via SQLite
ETL Pipeline
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ MusicBee │────>│ MBXRemote │────>│ SQLite │
│ Library │ │ Protocol │ │ Database │
└─────────────┘ └─────────────┘ └─────────────┘
EXTRACT TRANSFORM LOAD
- browsetracks - Normalize - CachedTracks
- browsealbums - Index - CachedAlbums
- browseartists - Deduplicate - CachedArtists
- browsegenres - Type casting - CachedGenresExample SQL Queries
-- Top 10 artists by track count SELECT Name, TrackCount, AlbumCount FROM CachedArtists ORDER BY TrackCount DESC LIMIT 10; -- Genre distribution SELECT Name, (SELECT COUNT(*) FROM CachedTracks WHERE Genre = CachedGenres.Name) as Tracks FROM CachedGenres ORDER BY Tracks DESC; -- Albums from a specific year SELECT Name, Artist, TrackCount FROM CachedAlbums WHERE Year = '2024'; -- Tracks with high bitrate SELECT Title, Artist, Album, Bitrate FROM CachedTracks WHERE Bitrate >= 320 ORDER BY Bitrate DESC;
Access Methods
| Tool | Command/Usage |
|---|---|
| SQLite CLI | sqlite3 "%APPDATA%\MBXRemote\musicbee.db" |
| DB Browser for SQLite | Open musicbee.db directly |
| Python | sqlite3.connect(path) |
| PowerShell | Invoke-SqliteQuery (PSSQLite module) |
| DBeaver / DataGrip | Add SQLite connection |
SyncMetadata table shows when each entity type was last synchronized.
Diagnostics and Performance Monitoring
MBXRemote includes comprehensive diagnostic logging for troubleshooting and performance analysis.
DiagnosticsService
A singleton service that tracks performance metrics throughout application lifecycle:
| Metric | Description | Log Level |
|---|---|---|
| Memory Snapshots | Working set, private bytes, GC heap, handles, threads | Info/Debug |
| Command Timing | RTT for network commands with min/max/avg/P95 | Debug |
| Slow Commands | Commands exceeding 1000ms threshold | Warn |
| Bytes Sent/Received | Network I/O totals | Debug |
| Performance Summary | Aggregate stats logged at shutdown | Info |
Log Markers for Analysis
Use these markers to filter logs for specific analysis:
| Marker | Purpose | Example |
|---|---|---|
MEMORY | Memory/handle snapshots | MEMORY [sync-start]: WorkingSet=150.2MB... |
TIMING | Command timing | TIMING: browsetracks completed in 234ms |
SEND_TIMING | Network send timing | SEND_TIMING: browsetracks sent in 2ms (156 bytes) |
SYNC_STAGE | Library sync stages | SYNC_STAGE: Tracks completed in 12345ms |
SLOW_COMMAND | Commands >1000ms | SLOW_COMMAND: browsetracks took 2500ms |
PERFORMANCE SUMMARY | Shutdown stats | Per-command aggregates |
Memory Snapshot Format
MEMORY [context]: WorkingSet=150.2MB, Private=180.5MB, GCHeap=45.3MB, Handles=512, Threads=24, GC(Gen0/1/2)=15/3/1
| Field | Description |
|---|---|
| WorkingSet | Physical memory in use by the process |
| Private | Private bytes (committed virtual memory) |
| GCHeap | Managed heap size |
| Handles | Operating system handle count |
| Threads | Active thread count |
| GC(Gen0/1/2) | Garbage collection counts per generation |
Performance Summary (Shutdown)
=== PERFORMANCE SUMMARY === Uptime: 01:23:45 Total Commands Sent: 1,234, Received: 1,230 Total Bytes Sent: 45,678, Received: 12,345,678 CMD [browsetracks]: Count=5, Avg=234.5ms, P95=450ms, Min=120ms, Max=890ms, Errors=0 CMD [browsealbums]: Count=3, Avg=156.2ms, P95=200ms, Min=120ms, Max=210ms, Errors=0 === END PERFORMANCE SUMMARY ===
Library Sync Timing
=== LIBRARY SYNC STARTING (Full) === MEMORY [sync-start]: WorkingSet=95.3MB, Private=120.5MB, GCHeap=35.1MB, Handles=412, Threads=18, GC(Gen0/1/2)=8/2/0 SYNC_STAGE: Genres completed in 234ms SYNC_STAGE: Albums completed in 567ms SYNC_STAGE: Artists completed in 890ms SYNC_STAGE: Tracks completed in 12345ms SYNC_STAGE: Playlists completed in 123ms === LIBRARY SYNC COMPLETED in 14159ms === MEMORY [sync-complete]: WorkingSet=180.2MB, Private=210.5MB, GCHeap=85.3MB, Handles=425, Threads=20, GC(Gen0/1/2)=15/3/1
Enabling Verbose Diagnostics
Enable detailed logging in Settings > General > Enable Logging for:
- Debug-level log output
- All command timing logs
- Periodic memory snapshots (every 60 seconds)
- Full network traffic logging
Log File Location
%PROGRAMFILES%\MBXRemote\logs\tntctl.log
(tntctl = tntctl remote viewer technologies)
Logs are rotated daily with 7-day retention.
Design Philosophy
The "Sandworm" Protocol
The ARiA protocol acts as a transport tunnel that carries action scripts without understanding or interpreting them. Like the sandworms of Arrakis that transport spice harvesters without knowledge of their cargo, the protocol simply moves action scripts from client to server.
This separation allows:
- Client Freedom: Clients can send any action script syntax
- Plugin Control: Plugin decides how to execute received scripts
- Future Extension: New command types without protocol changes
- Clean Architecture: Clear separation between transport and execution
Why SendKeys Instead of API?
MusicBee's MB_InvokeCommand(Command.NavigateTo) didn't work for tab switching. The Command enum only has one value (NavigateTo = 1) with no documentation on parameters. Testing showed no consistent behavior.
SendKeys provides a universal solution that:
- Works with MusicBee's existing hotkey system
- Allows user customization of both client and MusicBee hotkeys
- Can automate any keyboard-driven task
- Evolved from specific (tab navigation) to general-purpose automation
The "Jellybee" Codename
MBXRemote v1.0.26.3 is codenamed "Jellybee" - a portmanteau combining:
- Jelly - from the jellyfish mascot (tntctl 🪼)
- Bee - from MusicBee 🐝
The jellyfish represents tntctl (tntctl remote viewer technologies) - the underlying engine that powers MBXRemote's library sync, offline browsing, and local caching. The name "tntctl" rhymes with "tentacle," fitting the aquatic theme.
PartyMode REST API
PartyMode exposes a REST API for guest access to the MusicBee library. All endpoints except /api/session/validate require a valid session token.
Authentication
| Endpoint | Method | Description |
|---|---|---|
/api/session/validate | POST | Validate PIN and receive session token |
// Request POST /api/session/validate Content-Type: application/json { "pin": "1234" } // Response (200 OK) { "token": "abc123...", "expires_in": 1800 } // Response (401 Unauthorized) { "error": "Invalid PIN" } // Response (429 Too Many Requests) { "error": "Too many attempts. Try again in X seconds" }
Library Endpoints
| Endpoint | Method | Description |
|---|---|---|
/api/library/albums | GET | Browse albums (paginated) |
/api/album/{id}/tracks | GET | Get tracks for an album |
/api/search | GET | Search tracks by title, artist, album |
/api/status | GET | Get now playing and queue status |
Queue Endpoints
| Endpoint | Method | Description |
|---|---|---|
/api/queue/add | POST | Add track to queue (rate limited) |
// Request POST /api/queue/add Authorization: Bearer {token} Content-Type: application/json { "trackId": 123, "requester": "Guest" } // Response (200 OK) { "success": true, "position": 5 } // Response (429 Rate Limited) { "error": "Rate limit exceeded", "retry_after": 30 } // Response (403 Queue Full) { "error": "Max pending requests reached" }
Authorization Header
All authenticated endpoints require the Authorization header:
Authorization: Bearer {token}Rate Limiting
PartyMode implements per-session rate limiting to prevent abuse:
- Requests per minute: 10 (configurable via
PartyModeRateLimitPerMinute) - Max pending per session: 3 (configurable via
PartyModeMaxQueuePerSession) - Session timeout: 30 minutes (configurable via
PartyModeSessionTimeoutMinutes)
PIN Protection & Lockout
PartyMode protects against brute-force PIN guessing with automatic rate limiting and lockout:
| Protection | Threshold | Duration |
|---|---|---|
| Rate limit | 5 failed attempts per minute | Resets after 1 minute |
| Lockout | 10 failed attempts total | 15 minute ban |
How it works:
- Each IP address is tracked separately
- After 5 failed PIN attempts in one minute, further attempts are rejected with "Too many attempts"
- After 10 total failed attempts within 15 minutes, the IP is locked out for 15 minutes
- Lockouts are stored in memory and reset when MBXRemote restarts
- Successful PIN entry does not reset the failed attempt counter
Note: The lockout is per-IP and in-memory only. Restarting MBXRemote clears all lockouts. For persistent bans, use your router's firewall or Windows Firewall rules.
QR Code for PartyMode
MBXRemote can generate a printable QR code that guests scan to join PartyMode instantly - no need to type a URL or PIN.
Using the Built-in QR Code Generator
- Go to Settings > Firewall > PartyMode
- Make sure you have generated a PIN (click "New PIN" if needed)
- Click "Show QR Code"
- Enter your PIN when prompted
- A dialog shows the QR code with options to Print or Copy URL
How It Works
- The QR code embeds your PartyMode URL with the PIN included
- Guests scan the code and go directly to the jukebox - no PIN entry needed
- For manual access (no QR), guests use the base URL and enter the PIN
Tips
- Print it: Use the Print button to create a party-ready handout
- Static IP: Use a static IP or hostname so the QR code doesn't change
- Test first: Scan the QR code yourself to verify it works before the party
- Security: The PIN is cleared from the browser URL after login for security
Manual QR Code Generation
If you prefer to generate QR codes yourself, use any free QR code generator with this URL format:
http://YOUR_IP:8080?pin=YOUR_PIN
Services like qr-code-generator.com or qrcode-monkey.com work well.
Developer Test Mode
MBXRemote includes hidden developer tools for testing, debugging, and documentation. These are accessed via keyboard shortcuts and are intended for developers, testers, and power users.
Developer Test Mode Cheat Sheet
| Hotkey | Tool | What It Tests | Output Location |
|---|---|---|---|
| Ctrl+Shift+Alt+T | Protocol Tester | API endpoints, protocol negotiation, library sync, ARiA | logs/protocol-test-*.txt |
| Ctrl+Shift+Alt+P | PartyMode Tester | Web endpoints, PIN auth, browse pages, queue, admin | logs/partymode-test-*.txt |
| Ctrl+Shift+Alt+U | UI Gallery | Screenshot capture, UI navigation, visual testing | assets/screenshots/*.png |
All test output is automatically persisted to disk. Reports use timestamp-based filenames for history tracking.
Protocol Tester (Ctrl+Shift+Alt+T)
A comprehensive protocol compatibility tester that validates plugin functionality and protocol negotiation.
Access
Press Ctrl+Shift+Alt+T anywhere in MBXRemote to open the Protocol Tester.
Test Categories
| Category | Tests |
|---|---|
| Protocol Negotiation | v4.0/v4.5 handshake, extended metadata fields |
| Playback Control | Play, pause, stop, next, previous, volume, mute, shuffle, repeat |
| Now Playing | Track info, cover art, lyrics, position, rating, love status |
| Queue Operations | List queue, add track, remove track, move, clear |
| Library Editing | Set rating (0-5), set love/ban status |
| Library Subscriptions | Subscribe/unsubscribe to real-time library events |
| Search | Search artists, albums, tracks, playlists |
| Library Navigation | Browse genres, artists, albums, tracks (paginated) |
| Playlists & Podcasts | List playlists, get tracks, podcast feeds |
| ARiA | Initiator action execution test |
| Keepalive | Ping/pong connectivity test |
Output
- Results displayed in scrollable log with pass/fail indicators
- Auto-saves to
logs/protocol-test-YYYYMMDD-HHMMSS.txt - XML/DB comparison saves to
logs/xmldb-compare-YYYYMMDD-HHMMSS.txt - Manual export via Save button
UI Gallery (Ctrl+Shift+Alt+U)
A UI testing and screenshot capture tool for documentation and visual regression testing.
Access
Press Ctrl+Shift+Alt+U anywhere in MBXRemote to open the UI Gallery.
Capabilities
| Feature | Description |
|---|---|
| Tab Navigation | Switch between all main tabs (Now Playing, Library, Playlists, Queue, Settings) |
| Settings Sub-tabs | Navigate all Settings sub-tabs (General, Hotkeys, Appearance, Firewall, Database) |
| Dialog Preview | Open and preview all dialogs (QR Code, Protocol Tester, Favorites, About) |
| Capture All | Automated screenshot capture of all UI elements |
| Test Results | Generates ui-gallery-results.txt with pass/fail report |
Output (Auto-Saved)
Screenshots and results are automatically saved to:
{MBXRemote.exe location}\assets\screenshots\Files are named systematically for documentation use:
Tab-NowPlaying.png,Tab-Library.png, etc.Settings-General.png,Settings-Hotkeys.png, etc.Dialog-QRCode.png,Dialog-Favorites.png, etc.ui-gallery-results.txt- Summary report with pass/fail status
Test Results File
Each capture run generates a results file:
=========================================== MBXRemote UI Gallery Capture Results Captured: 2025-12-26 14:30:00 Version: 1.0.26.3 =========================================== SUMMARY: 13 passed, 0 failed, 13 total --- RESULTS --- [PASS] Tab-NowPlaying [PASS] Tab-Library [PASS] Tab-Playlists ... --- FILES CAPTURED --- Tab-NowPlaying.png Tab-Library.png ... =========================================== End of report
PartyMode Tester (Ctrl+Shift+Alt+P)
A comprehensive HTTP endpoint tester for validating PartyMode web server functionality.
Access
Press Ctrl+Shift+Alt+P anywhere in MBXRemote to open the PartyMode Tester.
Test Categories
| Category | Tests |
|---|---|
| Health Check | /health endpoint availability |
| Login Flow | Home page (/), login page (/login), PIN authentication |
| Browse Pages | Albums (/browse), Artists (/artists), Genres (/genres), Tracks (/tracks) |
| Search | /search with query parameter |
| Queue | /queue pending requests display |
| Admin | /admin login and analytics dashboard |
| Session | Cookie-based session management |
| Pagination | Page navigation on browse pages |
| NowPlaying | Now playing display on all pages |
Output (Auto-Saved)
- Color-coded results: green (pass), red (fail), orange (warning)
- HTTP status codes and response times for each endpoint
- Auto-saves to
logs/partymode-test-YYYYMMDD-HHMMSS.txt - Summary with pass/fail counts and total duration
- Toggle auto-save with checkbox in toolbar
Developer Hotkey Summary
| Hotkey | Tool | Purpose | Output |
|---|---|---|---|
| Ctrl+Shift+Alt+T | Protocol Tester | API compatibility and protocol testing | logs/protocol-test-*.txt |
| Ctrl+Shift+Alt+P | PartyMode Tester | Web server endpoint testing | logs/partymode-test-*.txt |
| Ctrl+Shift+Alt+U | UI Gallery | Screenshot capture and UI review | assets/screenshots/ |
MusicBee ARiA Hotkeys
MBXRemote can automatically configure MusicBee with ARiA-style global hotkeys for tab navigation and visualizer control. These hotkeys work system-wide, even when MusicBee is not focused.
ARiA Hotkey Mappings
The ARiA system uses Ctrl+Alt combined with home row keys (QWERTY left hand: A-L) for tab navigation:
| Hotkey | Key Code | MusicBee Command | Description |
|---|---|---|---|
| Ctrl+Alt+A | 393281 | GeneralGotoTab1 | Navigate to Tab 1 |
| Ctrl+Alt+S | 393299 | GeneralGotoTab2 | Navigate to Tab 2 |
| Ctrl+Alt+D | 393284 | GeneralGotoTab3 | Navigate to Tab 3 |
| Ctrl+Alt+F | 393286 | GeneralGotoTab4 | Navigate to Tab 4 |
| Ctrl+Alt+G | 393287 | GeneralGotoTab5 | Navigate to Tab 5 |
| Ctrl+Alt+H | 393288 | GeneralGotoTab6 | Navigate to Tab 6 |
| Ctrl+Alt+J | 393290 | GeneralGotoTab7 | Navigate to Tab 7 |
| Ctrl+Alt+K | 393291 | GeneralGotoTab8 | Navigate to Tab 8 |
| Ctrl+Alt+L | 393292 | GeneralGotoTab9 | Navigate to Tab 9 |
| Ctrl+Alt+; | 393402 | GeneralGotoTab10 | Navigate to Tab 10 |
Visualizer Hotkeys
Control MusicBee's visualizer remotely using these global hotkeys:
| Hotkey | Key Code | MusicBee Command | Description |
|---|---|---|---|
| Ctrl+Alt+V | 393302 | ViewToggleVisualiser | Toggle visualizer panel |
| Ctrl+Alt+Z | 393306 | ViewVisualiserToggleFullScreen | Toggle visualizer fullscreen |
sndKeys(CTRL ALT V) to toggle the visualizer, or sndKeys(CTRL ALT Z) for fullscreen mode.
Automatic Configuration
MBXRemote can automatically add these hotkeys to your MusicBee settings file:
- Go to Settings > Hotkeys
- Click "MusicBee ARiA Keys"
- MBXRemote will scan for your MusicBee settings file
- Review the current status (which hotkeys are already configured)
- Click Yes to add missing hotkeys
- Restart MusicBee for changes to take effect
MusicBee3Settings.ini.backup_YYYYMMDD_HHMMSS.
Key Code Calculation
MusicBee key codes are calculated as: Modifiers + VirtualKeyCode
| Modifier | Value (Hex) | Value (Decimal) |
|---|---|---|
| Control | 0x20000 | 131072 |
| Alt | 0x40000 | 262144 |
| Shift | 0x10000 | 65536 |
| Ctrl+Alt | 0x60000 | 393216 |
Example: Ctrl+Alt+A = 393216 (Ctrl+Alt) + 65 (A) = 393281
Settings File Location
MusicBee stores hotkey settings in its main configuration file. Common locations:
| Installation Type | Path |
|---|---|
| Standard | %APPDATA%\MusicBee\MusicBee3Settings.ini |
| Portable | <MusicBee Folder>\AppData\MusicBee3Settings.ini |
XML Format
Hotkeys are stored in the <HotKeys> section as <KeyCommandPair> elements:
<HotKeys>
<KeyCommandPair>
<Key>393281</Key>
<Command>GeneralGotoTab1</Command>
<IsGlobal>true</IsGlobal>
</KeyCommandPair>
<KeyCommandPair>
<Key>393302</Key>
<Command>ViewToggleVisualiser</Command>
<IsGlobal>true</IsGlobal>
</KeyCommandPair>
...
</HotKeys>