Skip to content
 
 

Repository files navigation

macrdp

Latest release License Ko-fi

A native RDP server for macOS, written in Rust on top of IronRDP. Connect from mstsc, Microsoft Remote Desktop, or FreeRDP to drive your Mac desktop with keyboard, mouse, real-cursor-shape forwarding, text + image clipboard sync, Mac↔Windows file copy, read-write drive redirection (mount the client's drives in Finder), smart-card redirection (use the client's smart card from macOS apps), system audio forwarding, and optional H.264 video (EGFX/AVC420, hardware-encoded). NLA/CredSSP is supported. Authenticates against your local Mac account via PAM.

This is the macOS equivalent of xrdp. Not a client, not a VNC bridge.

Status

v0 — daily-driver usable on a trusted LAN, and usable over the internet (VPN / ZeroTier / high-latency links, including mobile). Latest release: v0.8.26 — the roaming-client release: the server now measures each connection's round-trip time and configures itself per link — slow links get a gentle starting bitrate and are never offered the UDP transport, fast links get everything — so one config works whether you connect from the same WiFi or from a phone hotspot across the country.

Full per-release notes (what shipped, what was verified live, and the war stories): docs/release-history.md.

Production readiness

Short version: a polished v0 daily-driver for trusted LANs and your own VPN — not an enterprise RDP server. Use it to reach your own Mac over a network you control; don't put it on a public IP or treat it as multi-user/critical infrastructure.

Solid (verified on real mstsc / Microsoft Remote Desktop / FreeRDP): TLS + NLA/CredSSP auth against your Mac account (Keychain-backed, real CA certs supported, per-IP rate-limiting + lockout + audit log); the full daily workflow (display, input incl. non-US layouts, clipboard/files both ways, audio, drive + smart-card redirection, headless virtual displays); H.264 with congestion-responsive rate control that degrades gracefully instead of freezing; signed/notarized packaging with a LaunchAgent, menu-bar controller, and a health-check watchdog; 160+ tests in CI.

Know before relying on it: single session/single user; no multi-monitor or printer redirection; DRM video and password-manager windows capture black (macOS policy, not fixable); synthetic input can't reach the login window/secure fields (same); reconnecting mstsc can show a blank screen (client quirk — auto-recovery is built in, --fork-workers is the strong fix); the UDP paths are opt-in and newer than the TCP core; it's a solo v0 on vendored IronRDP forks, no SLA. Never expose any RDP server on a raw public IP — reach it over a VPN or RD Gateway.

Details and the path to closing the gaps: docs/production-readiness-roadmap.md.

Quick start

cargo build --release
codesign -s - --force target/release/macrdp   # ad-hoc sign so TCC grants persist
./target/release/macrdp

First run will prompt for:

  1. Screen Recording permission (System Settings → Privacy & Security → Screen Recording → enable macrdp → restart it).
  2. Accessibility permission (same path, "Accessibility" — required to forward keyboard and mouse).
  3. Your Mac password at the terminal — validated against your local account via PAM checkpw, then used as the RDP credential.

Then connect from a client to <your-mac-ip>:3390 with your Mac username and password. mstsc will prompt for credentials in its own NLA dialog — no need to pre-type the username.

Common flags to try next (full reference: docs/configuration.md):

./macrdp --enable-h264                      # H.264 video — crisper AND lighter than the default bitmaps
./macrdp --enable-h264 --adaptive-bitrate   # + congestion-responsive rate control (recommended off-LAN)
./macrdp --bind 0.0.0.0:3390                # accept LAN connections (keep it OFF public IPs)
./macrdp --virtual-display --width 2560 --height 1440   # headless second desktop; local screen untouched
./macrdp --map-ctrl-to-cmd                  # Windows Ctrl+C/V/X muscle memory drives macOS copy/paste

Auto-start at login (launchd)

dist/install.sh

Builds + signs + installs to ~/.local/bin/macrdp, stores your Mac password in the macOS Keychain under service macrdp, drops a launchd plist at ~/Library/LaunchAgents/com.user.macrdp.plist, and loads it. macrdp will start on every login and restart if it crashes. Re-run the script after cargo build --release to refresh the installed binary.

launchctl print gui/$UID/com.user.macrdp | head    # status
launchctl kickstart -k gui/$UID/com.user.macrdp    # restart
launchctl bootout gui/$UID/com.user.macrdp         # stop / uninstall

Building the full app

dist/install.sh installs a bare binary. For a proper signed macrdp.app — stable bundle identity (TCC grants survive rebuilds), background-agent behavior, the embedded smart-card IFD handler, optional notarization, the menu-bar controller app, and a distributable DMG:

packaging/make-app.sh                                 # build + sign + install to /Applications
security add-generic-password -s macrdp -a "$(id -un)" -w 'YOUR_PASSWORD'
packaging/install-launchagent.sh                      # load LaunchAgent (label com.clintcan.macrdp)

Feature toggles, bind address, and extra flags live in ~/Library/Application Support/macrdp/config.env — outside the bundle, so edits never disturb the signature or TCC grants. The full packaging guide (Developer-ID signing, notarization, the DMG, the controller app, icons, TCC notes): packaging/README.md.

Release artifacts

Pushing a v* tag runs the release workflow, which builds on an Apple-Silicon runner and attaches these to a draft GitHub Release (Apple Silicon / aarch64-apple-darwin only):

File What it is
macrdp-<ver>-aarch64-apple-darwin.tar.gz the bare CLI binary + LICENSE/README
macrdp-<ver>-aarch64-apple-darwin-app.zip the full macrdp.app, with the embedded smart-card IFD handler + installer — the only artifact that carries everything --enable-smartcard-redirection needs
SHA256SUMS checksums for both

Both are ad-hoc signed, not notarized — open the app once via right-click → Open (or xattr -dr com.apple.quarantine macrdp.app). For a Developer-ID-signed + notarized build, or the menu-bar controller app (neither is produced in CI), build locally with packaging/make-app.sh.

Documentation

Guide What's in it
Configuration & CLI Every flag, the auth-hardening environment variables (rate-limit/lockout/audit), headless mode (--virtual-display, --detach-primary/--capture-primary), and a full set of example invocations.
Video The H.264/EGFX pipeline, Retina capture (--hidpi), client-resolution auto-adopt and letterboxing, bitrate/keyframe tuning, the mstsc reconnect-blank quirk and its fixes (--fork-workers, auto-recovery), and the vImage color-conversion benchmarks.
Audio RDPSND PCM, opt-in AAC compression (--enable-aac), the self-healing capture stream, and mute-on-minimize.
File copy Mac↔Windows clipboard file copy (files and folder trees), lazy vs eager paste, and the two Windows-side gotchas (Explorer folder-copy, archive shell extensions).
Drive redirection Mounting the client's drives as read-write Finder volumes (--enable-drive-redirection) — how the in-process NFS bridge works and what to expect from permissions.
Smart-card redirection Using the client's smart card from macOS apps (--enable-smartcard-redirection) — one-time IFD-handler install, the USB-trigger caveat, upgrade/reload notes, and why it's a user-space handler rather than USB passthrough.
Release history Per-release narrative of what shipped and what was live-verified.
CLAUDE.md Developer/agent reference — architecture, feature status, macOS gotchas, known quirks.

Why this was made

This was done to scratch an itch. There are practically no active open source RDP servers for macOS. The closest project with this functionality is xrdp; however it only runs on Linux/Unix machines and has no homebrew equivalent on Macs. The initial POC was done in a few hours with the help of Claude and ran pretty well from the start. Additional combing through pcap files and documentation, and debugging each mstsc/FreeRDP connect, is what makes this work tedious yet rewarding when it finally works. Multi-monitor support is on the list for when I'm bored or need a distraction from real life.

Support this project

macrdp is free and open source. If it's helped you out, you can buy me a coffee to help me get through the bumps — totally optional, no pressure.

License

Licensed under either of MIT or Apache-2.0 at your option. Being permissively licensed, a productized/notarized build may be sold commercially with support — that's selling the product, not a license exemption.

About

A native RDP server for macOS, written in Rust on top of IronRDP.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages