Reviewed-on: #6
Furumi-ng
A music platform consisting of a remote filesystem, an AI-powered metadata agent, and a database-backed web player.
Components
furumi-server gRPC remote filesystem with TLS and auth
furumi-client-core Cross-platform gRPC client library
furumi-mount-linux FUSE mount for Linux
furumi-mount-macos NFS mount for macOS
furumi-agent AI metadata agent (LLM-powered ingest pipeline + admin UI)
furumi-web-player Database-backed web music player with OIDC auth
furumi-server
Exposes a local directory over encrypted gRPC. Supports Bearer token auth, OIDC/SSO, Prometheus metrics, and a built-in web player for direct filesystem browsing.
furumi-agent
Background service that watches an inbox folder for new music files, extracts metadata, normalizes it using a local LLM (via Ollama), and stores canonical metadata in PostgreSQL. Features:
- Automatic metadata extraction (Symphonia) and file path parsing
- LLM normalization with RAG (queries existing artists/albums in DB for consistency)
- Featured artist detection (
feat.,п.у.,&, etc.) - Album cover image processing
- Auto-approval for high-confidence results, review queue for uncertain ones
- Admin web UI with batch operations, inline editing, album grouping
- Organized file storage (
Artist/Album/Track.ext) - Configurable system prompt (built-in default or external file)
- Database migrations via sqlx
furumi-web-player
Web music player that reads exclusively from the database populated by the agent. Features:
- Browse by Artists, Albums, Tracks
- Full-text search across the library
- Audio streaming with HTTP Range request support
- Album cover art (from DB or embedded in audio files)
- Queue management with shuffle, repeat, drag-and-drop reorder
- Media Session API (hardware controls, lock screen integration)
- OIDC/SSO authentication
- Deep linking (
?t=<track_slug>) - Relative URL paths (works behind any reverse proxy prefix)
Architecture
┌─────────────────┐
│ Ollama (LLM) │
└────────┬────────┘
│
┌──────────┐ ┌────────────┴────────────┐ ┌──────────────────┐
│ Inbox │───→│ furumi-agent │───→│ Storage (files) │
│ folder │ │ (ingest + admin UI) │ └────────┬─────────┘
└──────────┘ └────────────┬────────────┘ │
│ │
┌──────┴──────┐ ┌───────┴────────┐
│ PostgreSQL │←──────────│ furumi-web- │
│ (metadata) │ │ player │
└─────────────┘ └────────────────┘
Quick Start
Remote Filesystem (FUSE/NFS mount)
cargo build --release --workspace
# Server
./target/release/furumi-server \
--root /path/to/media \
--token mysecrettoken
# Client (Linux)
./target/release/furumi-mount-linux \
--server server-ip:50051 \
--token mysecrettoken \
--mount /mnt/remote
Music Platform (Agent + Player)
Requires PostgreSQL with pg_trgm extension and Ollama for LLM.
# 1. Start PostgreSQL
docker run -d --name furumi-pg \
-e POSTGRES_DB=furumi -e POSTGRES_USER=furumi -e POSTGRES_PASSWORD=furumi \
-p 5432:5432 postgres:17
# 2. Create directories
mkdir -p /music/inbox /music/storage
# 3. Start the agent (runs migrations automatically)
./target/release/furumi-agent \
--inbox-dir /music/inbox \
--storage-dir /music/storage \
--database-url "postgres://furumi:furumi@localhost:5432/furumi" \
--ollama-url "http://localhost:11434" \
--ollama-model "qwen3:14b"
# 4. Start the web player
./target/release/furumi-web-player \
--storage-dir /music/storage \
--database-url "postgres://furumi:furumi@localhost:5432/furumi"
# 5. Drop music files into /music/inbox — agent processes them automatically
# 6. Open http://localhost:8080 to play music
# 7. Open http://localhost:8090 for the agent admin UI
Configuration
All options can be set via CLI flags or environment variables.
Server
| Flag | Env | Default | Description |
|---|---|---|---|
--bind |
FURUMI_BIND |
0.0.0.0:50051 |
gRPC listen address |
--root |
FURUMI_ROOT |
. |
Directory to expose |
--token |
FURUMI_TOKEN |
(empty, auth off) | Bearer token |
--metrics-bind |
FURUMI_METRICS_BIND |
0.0.0.0:9090 |
Prometheus endpoint |
--web-bind |
FURUMI_WEB_BIND |
0.0.0.0:8080 |
Built-in web player |
--no-web |
— | false |
Disable built-in web player |
--no-tls |
— | false |
Disable TLS |
Client (Linux / macOS)
| Flag | Env | Default | Description |
|---|---|---|---|
--server |
FURUMI_SERVER |
0.0.0.0:50051 |
Server address |
--token |
FURUMI_TOKEN |
(empty) | Bearer token |
--mount |
FURUMI_MOUNT |
— | Mount point directory |
--no-tls |
— | false |
Disable TLS |
Metadata Agent
| Flag | Env | Default | Description |
|---|---|---|---|
--bind |
FURUMI_AGENT_BIND |
0.0.0.0:8090 |
Admin UI address |
--inbox-dir |
FURUMI_AGENT_INBOX_DIR |
— | Watch folder for new files |
--storage-dir |
FURUMI_AGENT_STORAGE_DIR |
— | Permanent storage folder |
--database-url |
FURUMI_AGENT_DATABASE_URL |
— | PostgreSQL URL |
--ollama-url |
FURUMI_AGENT_OLLAMA_URL |
http://localhost:11434 |
Ollama API endpoint |
--ollama-model |
FURUMI_AGENT_OLLAMA_MODEL |
qwen3:14b |
LLM model name |
--poll-interval-secs |
FURUMI_AGENT_POLL_INTERVAL_SECS |
30 |
Inbox scan interval |
--confidence-threshold |
FURUMI_AGENT_CONFIDENCE_THRESHOLD |
0.85 |
Auto-approve threshold |
--system-prompt-file |
FURUMI_AGENT_SYSTEM_PROMPT_FILE |
(built-in) | Custom LLM prompt |
Web Player
| Flag | Env | Default | Description |
|---|---|---|---|
--bind |
FURUMI_PLAYER_BIND |
0.0.0.0:8080 |
Player address |
--database-url |
FURUMI_PLAYER_DATABASE_URL |
— | PostgreSQL URL |
--storage-dir |
FURUMI_PLAYER_STORAGE_DIR |
— | Storage folder (for streaming) |
--oidc-issuer-url |
FURUMI_PLAYER_OIDC_ISSUER_URL |
(disabled) | OIDC issuer |
--oidc-client-id |
FURUMI_PLAYER_OIDC_CLIENT_ID |
— | OIDC client ID |
--oidc-client-secret |
FURUMI_PLAYER_OIDC_CLIENT_SECRET |
— | OIDC client secret |
--oidc-redirect-url |
FURUMI_PLAYER_OIDC_REDIRECT_URL |
— | OIDC redirect URL |
--oidc-session-secret |
FURUMI_PLAYER_OIDC_SESSION_SECRET |
(random) | Session HMAC secret |
Docker Compose
The easiest way to run the entire backend stack (PostgreSQL, Agent, Web Player, and gRPC Server) is using Docker Compose.
Quick Start
- Prepare directories:
mkdir -p inbox storage - Start the services:
docker compose up -d - Check logs:
docker compose logs -f
The following services will be available:
- Web Player: http://localhost:8085
- Agent Admin UI: http://localhost:8090
- Metrics: http://localhost:9090/metrics
Note
The Agent expects Ollama to be running. By default, it tries to connect to the host at
http://localhost:11434.
Reference Commands
- Start:
docker compose up -d - Stop:
docker compose stop - Stop and remove containers:
docker compose down - Clear database and storage:
docker compose down -v
Environment Variables
To configure the Agent (especially for remote Ollama or private models) and database, create an .env file in the root directory:
# Database
POSTGRES_PASSWORD=secure-password
# LLM (Ollama)
OLLAMA_URL=http://your-ollama-host:11434
OLLAMA_AUTH="Bearer your-token"
# Server Security
FURUMI_TOKEN=secure-server-token
For more options, refer to the Configuration section.
Docker
Pre-built images are available on Docker Hub:
docker pull <user>/furumi-server
docker pull <user>/furumi-web-player
docker pull <user>/furumi-metadata-agent
Prometheus Metrics
Available at http://<metrics-bind>/metrics (server only):
furumi_grpc_requests_total— request count by method and statusfurumi_grpc_request_duration_seconds— request latency histogramfurumi_bytes_read_total— total bytes streamedfurumi_active_streams— current streaming connections
Requirements
- Rust 2024 edition
- PostgreSQL 14+ with
pg_trgmextension (for agent and web player) - Ollama with a local LLM (for agent)
- Linux with
libfuse3-dev(for FUSE client only)
License
MIT