No description
  • C# 98.8%
  • PowerShell 1.2%
Find a file
Cyrus Otter 7eb7b5883c
All checks were successful
Build & Release UdonMQTT-Bridge (.NET 8 framework-dependent) / build (Release, map[display:win-x64 rid:win-x64]) (push) Successful in 39s
Build & Release UdonMQTT-Bridge (.NET 8 framework-dependent) / release (push) Successful in 33s
Switch to v3 actions to support forgejo
2026-04-21 22:51:00 +02:00
.github/workflows Switch to v3 actions to support forgejo 2026-04-21 22:51:00 +02:00
UdonMQTT-Bridge Version 0.1.0 of UdonMQTT-Bridge 2026-04-17 20:55:57 +02:00
.gitignore Version 0.1.0 of UdonMQTT-Bridge 2026-04-17 20:55:57 +02:00
build-publish.ps1 Version 0.1.0 of UdonMQTT-Bridge 2026-04-17 20:55:57 +02:00
LICENSE Version 0.1.0 of UdonMQTT-Bridge 2026-04-17 20:55:57 +02:00
README.md Version 0.1.0 of UdonMQTT-Bridge 2026-04-17 20:55:57 +02:00
UdonMQTT-Bridge.sln Version 0.1.0 of UdonMQTT-Bridge 2026-04-17 20:55:57 +02:00

UdonMQTT-Bridge

UdonMQTT is a bidirectional MQTT bridge for VRChat worlds, enabling real-time communication between in-world UdonSharp behaviours and external MQTT brokers. This is the desktop release — the same bridge engine with a WPF interface instead of a console window.


Overview

Because VRChat's Udon runtime is heavily sandboxed (no sockets, no HTTP), UdonMQTT uses two OS-level channels to move data in and out of the game:

  • Ingress (External → VRChat): Win32 keyboard events via PostMessage(WM_CHAR)
  • Egress (VRChat → External): VRChat log file tailing (Debug.Log as a write-only serial port)

UdonMQTT-Bridge adds:

  • One-click start/stop with a live status indicator
  • Live status dashboard showing connection states and message counters
  • Settings editor for all configuration options (no manual JSON editing)
  • Persistent console log with timestamps, auto-scroll, and log rotation
  • Prometheus metrics polling for real-time observability

Requirements

  • Windows 10/11
  • .NET 8.0 Runtime (Desktop)
  • VRChat running locally (for log parsing and keyboard events)
  • An accessible MQTT broker

Getting Started

  1. Download the latest release and run UdonMQTT-Bridge.exe.
  2. Open the Settings tab and configure your MQTT broker address, port, credentials, and topics.
  3. Click Save, then switch to the Status tab and click Start.
  4. The status cards update every 2 seconds. Console output appears in the log panel below.

Configuration is stored at %LOCALAPPDATA%\UdonMQTT\mqtt_config.json and is created automatically with defaults on first run.


Features

Status Tab

The status tab shows the live state of UdonMQTT after t is started.

Connection status cards:

Card Description
MQTT Broker Whether the MQTT client is connected to the broker
VRChat Process Whether VRChat.exe is running
VRChat Window Whether the VRChat window is in the foreground
Log File Whether the VRChat log file is being actively parsed
Udon World Whether the current VRChat world has loaded an Udon script
Active Subscriptions Number of active MQTT topic subscriptions

Counter cards: Messages Published, Messages Received, Keyboard Strings Sent, Log Lines Parsed, Errors, Dropped Messages, Reconnects, and Uptime.

Metrics are fetched from the Prometheus endpoint exposed by UdonMQTT (configurable host/port). A banner is shown when metrics are unavailable. The Refresh button forces an immediate update.

Console log: Timestamped output from UdonMQTT, capped at 500 lines. Auto-scroll can be toggled. Logs are saved to %LOCALAPPDATA%\UdonMQTT\UdonMQTT_*.log with rotation (max 5 files).

Settings Tab

All settings are edited in-app. Changes are not applied until Save is clicked. Unsaved changes are indicated in the status bar.

Group Settings
MQTT Broker address, port, username, password, TLS toggle, allow untrusted certs, ignore cert errors, base topic, join-world topic, auto-start on launch
Rate Limiting Max chars/sec, burst size, min newline interval (ms), chunk size (chars)
Timing Log parser interval (ms), chunk send interval (ms), key rotation interval (min), key grace period (min), log search timeout (sec)
Messages & Monitoring Max message size (bytes), Prometheus host, Prometheus port
Debug Debug mode toggle

Reset Defaults restores all fields to built-in defaults without saving. Reload discards unsaved edits and reloads from disk.


Security

  • Connection key rotation: UdonMQTT generates a random 4-character alphanumeric key, rotated on a configurable interval with a grace period for the old key. Log commands must include the current key to be processed, preventing stale log replay.
  • Topic restriction: All MQTT operations are restricted to the configured BaseTopic prefix. Publishing or subscribing to topics outside this prefix (or under the reserved bridge/ subtopic) is rejected.
  • User whitelist: The in-world UdonSharp behaviour only activates for players listed in whitelistedUsers. For all other players, the GameObject is disabled entirely.

Monitoring

UdonMQTT exposes Prometheus metrics at http://127.0.0.1:9100/metrics (configurable via PrometheusMetricsHost and PrometheusMetricsPort).

Key metrics: udonmqtt_mqtt_messages_published_total, udonmqtt_mqtt_messages_received_total, udonmqtt_mqtt_connected, udonmqtt_world_connected, udonmqtt_window_found, udonmqtt_logfile_found, udonmqtt_keyboard_strings_sent_total, udonmqtt_errors_total, udonmqtt_process_uptime_seconds.


World Join Tracking

The log parser detects VRChat's [Behaviour] Joining wrld_ log lines and publishes structured world join events to JoinWorldTopic as retained MQTT messages — including world ID, instance ID, group info, region, and age gate status. No Udon involvement required.


Configuration Reference

Defaults written on first run:

Setting Default Description
BrokerAddress localhost MQTT broker hostname
Port 1883 MQTT broker port
Username udonmqtt Broker username
Password udonmqtt Broker password
UseTLS false Enable TLS
AllowUntrustedCert false Accept untrusted certificates
IgnoreCertErrors false Ignore all certificate errors
BaseTopic udonmqtt Topic prefix restriction
JoinWorldTopic udonmqtt/bridge/joinworld Topic for world join events
MaxCharsPerSecond 400 Token bucket rate limit
MinNewlineIntervalMs 800 Minimum gap between message submits
MaxBurstChars 800 Token bucket burst size
ChunkSize 128 Characters per keyboard chunk
ChunkIntervalMS 16 Pause between chunks (ms)
LogparserIntervalMS 50 Log file poll interval (ms)
KeyUpdateIntervalMinutes 1 Connection key rotation interval
KeyGracePeriodMinutes 1 Old key acceptance window
LogSearchTimeoutSeconds 30 Timeout when searching for log file
MinVrcProcessSeconds 20 Minimum seconds VRChat must have been running before its log is picked up
PrometheusMetricsHost 127.0.0.1 Metrics bind address
PrometheusMetricsPort 9100 Metrics port
MaxMessageSizeBytes 4096 Maximum inbound message size
DebugMode false Enable verbose debug output
AutoStartOnLaunch false Start bridge automatically on app launch

Building from Source

git clone https://github.com/eurofurence/UdonMQTT-Bridge
cd UdonMQTT-Bridge
dotnet build

Requires the .NET 8.0 SDK. The project targets net8.0-windows (WPF).

To produce a self-contained executable:

dotnet publish -c Release -r win-x64 --self-contained true -p:PublishSingleFile=true

Project Structure

UdonMQTT-Bridge/
├── Core/               # UdonMQTT engine (MQTT, keyboard injection, log parser, Prometheus)
├── Services/           # Bridge lifecycle, config I/O, metrics fetching, console capture
├── ViewModels/         # MVVM view models (MainViewModel, SettingsViewModel, DebugViewModel)
├── Converters/         # WPF value converters (bool → color/visibility, uptime formatting)
├── MainWindow.xaml     # Two-tab UI (Status + Settings)
└── App.xaml            # Application entry point and theme resources

VRChat TOS Compliance

UdonMQTT-Bridge is not a mod, not a cheat, and does not modify VRChat in any way.

VRChat's Community Guidelines prohibit reverse engineering and modifying VRChat applications, including code injection, sideloading, exploiting, and circumventing anti-tamper software. The TOS (Section 13) further prohibits decompiling, reverse engineering, or making modifications to any portion of the Platform.

UdonMQTT-Bridge adheres to all of these rules. It follows the same approach used by other well-established, community-accepted VRChat companion tools — such as ToNSaveManager, VRCX, VRCLogParser, and others — which read VRChat's output log files as their primary data source.

What UdonMQTT Does — And Does Not Do

No client modification. UdonMQTT is a standalone external .NET application that runs alongside VRChat as a separate process. It does not modify, patch, inject into, or interact with VRChat's process memory. It does not use DLL injection, function hooking, or any technique that alters VRChat's executable or runtime behaviour.

Log file reading (egress). Like ToNSaveManager, VRCX, and other companion tools, UdonMQTT reads VRChat's output_log_*.txt files from %AppData%Low\VRChat\VRChat\. These are plain text files that Unity writes as part of its standard logging pipeline. UdonMQTT opens them read-only with FileShare.ReadWrite, never locking or interfering with VRChat's ability to write to them. Debug.Log() is a standard Unity method that VRChat's own Udon debugging documentation encourages world creators to use.

Keyboard input (ingress). UdonMQTT uses PostMessage(WM_CHAR), a standard Windows API, to send characters to VRChat's window — functionally identical to a user typing on their keyboard. On the receiving side, Input.inputString is explicitly listed as an available API in VRChat's official Udon Input Events documentation.

No network interception. UdonMQTT does not inspect, intercept, modify, or decrypt any VRChat network traffic. Its MQTT communication is entirely separate — connecting to a user-configured broker with no relationship to VRChat's infrastructure.

Concern UdonMQTT's Approach
Client modification No — standalone external process, VRChat binary untouched
Code injection No — no DLL injection, hooking, or memory access
Reverse engineering No — no decompilation or inspection of VRChat code
Anti-cheat circumvention No — does not interact with EAC or any anti-tamper system
Log file reading Read-only, same approach as ToNSaveManager / VRCX / other community tools
Input method Input.inputStringofficially documented Udon API
Output method Debug.Log()officially documented for Udon debugging
Network interception No — MQTT traffic is entirely separate from VRChat's servers

⚠️ Important — Do not use UdonMQTT to collect user data against users' will. UdonMQTT is a transport layer. World creators building on top of it are responsible for what data they publish via MQTT. VRChat's SDK License prohibits content from sending data collected from users to external servers without authorization, and Section 8.10 of the TOS prohibits worlds from collecting information that provides the real identity of users. Do not use Udon APIs (such as VRCPlayerApi) to harvest other players' display names, positions, or other personal information and publish it to MQTT without those players' informed consent.

Note: This section reflects our understanding of VRChat's Terms of Service and Community Guidelines as of March 2026. TOS interpretation is ultimately at VRChat's discretion.


License

See LICENSE for details.