agentlytics
Comprehensive analytics dashboard for AI coding agents — Cursor, Windsurf, Claude Code, VS Code Copilot, Zed, Antigravi…
DLNA Media Server written in Rust, x64/ARM, Linux, Mac, Windows and Docker support
A cross-platform DLNA/UPnP media server written in Rust. Streams video, audio, and images to any DLNA-compatible device (smart TVs, receivers, game consoles). Less than 8Mb of RAM needed
Built with Tokio, Axum, and Redb for high performance and reliability.
Supported platforms: Windows, Linux, macOS, Docker (x64 and ARM64)
You can install VuIO using our official Homebrew Tap:
brew tap vuiodev/vuio brew install vuio
Once installed, start the server using:
vuio /path/to/media
For a detailed guide on all HTTP, REST, UPnP, and MCP endpoints, see the API Reference.
VuIO features a built-in web dashboard at http://<server-ip>:<port> (default: http://localhost:8080):
# Run with default settings (scans ~/Videos, ~/Music, ~/Pictures) ./vuio # Specify media directory ./vuio /path/to/media # Custom port and name ./vuio -p 9090 -n "My Media Server" /path/to/media # Multiple directories (using -m or --media-dir) ./vuio /movies -m /music -m /photos
Usage: vuio [OPTIONS] [MEDIA_DIR]
Arguments:
[MEDIA_DIR] Directory containing media files
Options:
-p, --port <PORT> Port to listen on [default: 8080]
-n, --name <NAME> DLNA server name
-c, --config <CONFIG> Path to config file
-m, --media-dir <DIR> Additional media directories
--debug Enable debug logging
--log-file <PATH> Path to custom log file
--log-level <LEVEL> Set log level (off, error, warn, info, debug, trace)
--update Update binary to the latest version from GitHub
--auth Enable administrative authentication
-h, --help Print help
-V, --version Print version
You can automatically update your installed binary to the latest release on GitHub at any time:
vuio --update
Docker does not work on macOS due to multicast limitations.
git clone https://github.com/vuiodev/vuio.git cd vuio docker-compose -f docker-compose.yml up
services:
vuio:
image: vuio:latest
container_name: vuio-server
restart: unless-stopped
network_mode: host # Required for DLNA multicast
cap_add:
- NET_ADMIN
- NET_RAW
volumes:
- ./vuio-config:/config
- /path/to/media:/media:ro
environment:
- VUIO_IP=192.168.1.100 # Your host IP (required)
- VUIO_PORT=8080
- VUIO_MEDIA_DIRS=/media
- VUIO_SERVER_NAME=VuIO
- VUIO_DB_PATH=/data/vuio.redb
Single directory:
volumes: - ./vuio-config:/config - /path/to/media:/media:ro
Multiple directories:
volumes: - ./vuio-config:/config - /home/user/Movies:/media/movies:ro - /home/user/Music:/media/music:ro - /home/user/Pictures:/media/pictures:ro - /mnt/nas/media:/media/nas:ro environment: - VUIO_MEDIA_DIRS=/media/movies,/media/music,/media/pictures,/media/nas
Network storage (NFS/SMB):
volumes:
- type: bind
source: /mnt/nas/media
target: /media
read_only: true
docker run -d \ --name vuio-server \ --restart unless-stopped \ --network host \ --cap-add NET_ADMIN \ --cap-add NET_RAW \ -v /path/to/media:/media:ro \ -v ./vuio-config:/config \ -e VUIO_IP=192.168.1.100 \ -e VUIO_PORT=8080 \ -e VUIO_MEDIA_DIRS=/media \ -e VUIO_DB_PATH=/data/vuio.redb \ vuio:latest
| Variable | Default | Description |
|---|---|---|
VUIO_IP |
- | Required. Host IP for DLNA announcements |
VUIO_PORT |
8080 | HTTP server port |
VUIO_SERVER_NAME |
VuIO | DLNA server name |
VUIO_UUID |
random | Device UUID (set for persistence) |
VUIO_MEDIA_DIRS |
/media | Comma-separated media paths |
VUIO_SCAN_ON_STARTUP |
true | Scan media on startup |
VUIO_WATCH_CHANGES |
true | Monitor for file changes |
VUIO_CLEANUP_DELETED |
true | Remove deleted files from DB |
VUIO_SCAN_PLAYLISTS |
true | Import M3U/PLS playlists |
VUIO_DB_PATH |
/data/vuio.redb | Database file path |
VUIO_MULTICAST_TTL |
4 | Multicast TTL |
VUIO_ANNOUNCE_INTERVAL |
30 | SSDP announce interval (seconds) |
VUIO_AUTH |
false | Enable administrative/management authentication |
VUIO_ADMIN_TOKEN |
- | Pre-configured admin password token for sign in |
Find your host IP:
# Linux ip route get 1.1.1.1 | grep -oP 'src \K[0-9.]+' # macOS ipconfig getifaddr en0 # Windows ipconfig | findstr "IPv4"
Generate UUID for multiple instances:
uuidgen # Linux/macOS [System.Guid]::NewGuid() # Windows PowerShell
You can deploy VuIO to a Kubernetes cluster using the provided Helm chart.
You can install the chart directly from GitHub Container Registry without cloning the repository:
helm install vuio oci://ghcr.io/vuiodev/charts/vuio --version 0.0.35
If you have cloned the repository, you can install the chart locally:
# From the repository root directory helm install vuio ./helm/vuio
For SSDP/UPnP multicast auto-discovery to work natively on your local area network (LAN), the container needs to bind directly to the host's networking. The Helm chart is configured to use host networking by default:
hostNetwork: true
Note: On platforms like macOS, multicast routing restrictions in the hypervisor layer prevent SSDP from working. If you are deploying locally on macOS Kubernetes or do not require LAN discovery, you should disable host networking in your values.yaml or overrides:
helm install vuio ./helm/vuio --set hostNetwork=false
The Helm chart supports configuring a Persistent Volume Claim (PVC) to retain the database and generated configuration across restarts. Additionally, you can configure your media volume mounts directly under media values:
# Mount your local media library directory into the container
media:
volumeMounts:
- name: media
mountPath: /media
readOnly: true
volumes:
- name: media
hostPath:
path: /Users/random/test-media # Path to media on your host machine
type: Directory
Refer to the default values.yaml file for a complete list of parameters, including resource constraints, service configurations, and Ingress routing rules.
VuIO uses TOML configuration files on native platforms. Config location: ./config/config.toml
Server:
port - HTTP server portinterface - Network interface to bind (0.0.0.0 for all)name - DLNA server friendly nameuuid - Device UUID (auto-generated if not set)ip - Specific IP for DLNA announcements (optional)Network:
interface_selection - "Auto", "All", or specific interface namemulticast_ttl - Multicast time-to-liveannounce_interval_seconds - SSDP announcement intervalMedia:
scan_on_startup - Scan directories on startupwatch_for_changes - Real-time file monitoringcleanup_deleted_files - Auto-remove deleted files from databasescan_playlists - Import M3U/PLS playlist filessupported_extensions - Global list of media extensionsMedia Directories:
path - Directory pathrecursive - Scan subdirectoriesextensions - Override extensions for this directoryexclude_patterns - Patterns to exclude (e.g., ".tmp", ".")validation_mode - Path validation: "Strict" (fail if missing), "Warn" (log warning), "Skip" (no validation)case_sensitive - Optional per-root override; omit it to detect the filesystem behavior automaticallyDatabase:
path - Database file locationvacuum_on_startup - Compact database on startupbackup_enabled - Enable automatic backupsVuIO automatically extracts metadata from audio files:
VuIO automatically discovers and imports playlist files:
Playlists are scanned from media directories on startup and made available to DLNA clients.
Configure: scan_playlists = true or VUIO_SCAN_PLAYLISTS=true
Recommended directory structure:
/music/
├── Artist Name/
│ └── Album Name (Year)/
│ ├── 01 - Track.flac
│ └── folder.jpg
└── playlists/
├── favorites.m3u
└── workout.pls
VuIO uses Redb, an embedded ACID-compliant database.
| Platform | Default Path |
|---|---|
| Windows | [exe dir]\config\database\media.redb |
| Linux | ~/.local/share/vuio/media.redb |
| macOS | ~/Library/Application Support/vuio/media.redb |
| Docker | /data/vuio.redb (or VUIO_DB_PATH) |
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Web Server │ │ SSDP Service │ │ File Watcher │
│ (Axum/HTTP) │ │ (Discovery) │ │ (Real-time) │
└────────┬────────┘ └────────┬────────┘ └────────┬────────┘
│ │ │
└──────────────────────┼──────────────────────┘
│
┌──────────────────────┴──────────────────────┐
│ Application Core │
│ ┌─────────┐ ┌─────────┐ ┌─────────────┐ │
│ │ Config │ │ Database│ │ Platform │ │
│ │ Manager │ │ (Redb) │ │ Abstraction │ │
│ └─────────┘ └─────────┘ └─────────────┘ │
└──────────────────────┬──────────────────────┘
│
┌──────────────────────┴──────────────────────┐
│ Platform Layer │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ Windows │ │ macOS │ │ Linux │ │
│ └─────────┘ └─────────┘ └─────────┘ │
└─────────────────────────────────────────────┘
VuIO is designed to run cleanly by default. Standard startup displays a clean, visual card containing crucial server information, while silencing verbose background execution traces.
By default, all detailed logs (INFO level and below) are automatically recorded to a rolling background log file so that troubleshooting info is always preserved.
Default Log Path:
[exe dir]\config\logs\vuio.log[exe dir]/config/logs/vuio.log (Native) or platform cache path[exe dir]/config/logs/vuio.log/data/logs/vuio.logIf you want to view verbose background logs directly on the console, you can use either of the following approaches:
Command Line Flag:
Run with --debug to enable verbose debug logs on the terminal:
./vuio --debug
Environment Variable:
Set RUST_LOG env variable:
RUST_LOG=info ./vuio RUST_LOG=debug ./vuio
You can fully control where logs are written and their severity level using command line options:
./vuio --log-file /path/to/my-custom.log
./vuio --log-level debug ./vuio --log-level warn
VuIO contains built-in endpoints optimized for Kubernetes orchestration and observability via Grafana, Prometheus, and Loki.
/healthz): A lightweight endpoint indicating that the web server is running.
200 OK with JSON {"status": "healthy"}/readyz): Verifies database connectivity and readiness to serve requests.
200 OK with JSON {"status": "ready"} if healthy, or 503 Service Unavailable if database access fails.To monitor the server health, cache efficiency, and indexing status, you can query the metrics endpoints:
/metrics): Returns raw metrics formatted for Prometheus.
curl http://localhost:8080/metrics200 OK with text/plain Prometheus exposition format./metrics/json): Returns JSON telemetry.
curl http://localhost:8080/metrics/json200 OK with JSON structure like:
{
"web_handler_metrics": {
"browse_requests": 12,
"cache_hits": 9,
"cache_misses": 3,
"cache_hit_rate_percent": 75.0,
"average_response_time_ms": 12,
"gigabytes_transferred": 0.25,
"redb_database": "active"
}
}
To support instant directory listings for directories containing 1000+ files, VuIO implements an automatic, thread-safe SOAP response cache:
(ObjectID, StartingIndex, RequestedCount, ClientProfile, UpdateID). Subsequent scrolls or refreshes from the TV/client are served in sub-milliseconds without hitting the database, resolving paths, or performing memory cloning.UpdateID counter, ensuring no stale data is ever served./logs): Stream the last N log entries (default 100, max 5000) dynamically over HTTP. Useful for pull-based logs scraping.
curl http://localhost:8080/logs?limit=50200 OK with raw plaintext log lines.VuIO supports the Model Context Protocol (MCP), allowing AI agents (like voice assistants, chatbots, and autonomous agents) to interact with your media library and control playback on smart TVs on the local network.
The MCP server is served over SSE (Server-Sent Events) on the existing HTTP port:
GET http://localhost:8080/sse
endpoint event containing the POST message target, e.g. data: /mcp/message?client_id=<uuid>POST http://localhost:8080/mcp/message?client_id=<uuid>
| Tool Name | Parameters | Description |
|---|---|---|
search_media |
query (string) |
Search media files by keyword matching filenames or tags |
browse_folder |
path (string), category (optional string) |
Browse files and directories in a specific folder path |
get_media_info |
file_id (integer) |
Fetch detailed metadata for a file by its ID |
get_server_stats |
None | Retrieve media counts, library size, and server URL info |
list_renderers |
None | List DLNA/UPnP MediaRenderers with stable IDs |
cast_media_to_renderer |
file_id (integer), renderer_id (string) |
Start playing a media file on a discovered renderer |
control_renderer |
renderer_id (string), action ("play"|"pause"|"stop") |
Send playback control commands to a renderer |
list_media |
category (optional string), limit (optional integer) |
Retrieve a flat list of indexed media files (all, audio, video, image) |
list_playlists |
None | List all playlists stored on the server |
create_playlist |
name (string), description (optional string) |
Create a new media playlist |
delete_playlist |
playlist_id (integer) |
Delete a playlist by ID |
add_to_playlist |
playlist_id (integer), media_file_ids (integer[]) |
Add multiple tracks in bulk to a playlist |
remove_from_playlist |
playlist_id (integer), media_file_id (integer) |
Remove a specific track from a playlist |
get_playlist_tracks |
playlist_id (integer) |
Retrieve all media files/tracks in a specific playlist |
cast_playlist_to_renderer |
playlist_id (integer), renderer_id (string) |
Cast a playlist to a local renderer and start playing it |
Discover TVs:
curl -X POST "http://localhost:8080/mcp/message?client_id=agent-1" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"tools/call","id":1,"params":{"name":"list_renderers","arguments":{}}}'
Search for Media:
curl -X POST "http://localhost:8080/mcp/message?client_id=agent-1" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"tools/call","id":2,"params":{"name":"search_media","arguments":{"query":"matrix"}}}'
By default, the web interface and management endpoints run without authentication for easy local usage.
To enable administrative/management authentication, start VuIO with either:
--auth command-line optionVUIO_AUTH=true environment variableWhen enabled:
On startup, if no pre-defined token is found, VuIO generates a random cryptographically secure token and writes it to a file named admin.token in the configuration directory (e.g. ./admin.token). Keep this file private.
You can also set a pre-defined administration token via the VUIO_ADMIN_TOKEN environment variable:
export VUIO_ADMIN_TOKEN="your-custom-secure-token"
Contributions welcome! Please ensure cross-platform compatibility is maintained. Input license = output license
more like this
Comprehensive analytics dashboard for AI coding agents — Cursor, Windsurf, Claude Code, VS Code Copilot, Zed, Antigravi…
Free open-source Cloudflare R2 desktop client and S3 GUI for macOS, Windows, and Linux. Manage Cloudflare R2, AWS S3, M…
search projects, people, and tags