Opens a larger view. Escape closes it.

riyaz-companion

c723e3e

README.md

llm stack — Ollama + Open WebUI + Music MCP

Local LLM stack: Ollama with gemma4:31b on AMD RX 9070 XT (ROCm), Open WebUI frontend, SearXNG web search, and a music personality MCP server.

Services

ServicePortPurpose
Ollama11434LLM inference — gemma4:31b via ROCm, 16GB VRAM
Open WebUI3100Chat frontend (http://owui.bazzite)
SearXNG8888Web search engine (connected to OWUI)
music-mcp8765Music personality MCP server + raga KB RAG

Models (in Open WebUI)

Model IDNameThinking
gemma4-31b-fastGemma 4 31Boff — direct responses
gemma4-31b-thinkGemma 4 31B (Thinking)on — reasoning trace before answer

Both models are vanilla — no system prompt set on the model itself. Personality and tools come entirely from the music-mcp server.

music-mcp — MCP + OpenAPI personality server

Container built from music-mcp-Dockerfile + music-mcp-server.py. Exposes:

EndpointProtocolPurpose
/mcpMCP streamable-http (2025-06-18)Direct MCP client access (Conduit, future)
/openapi.jsonOpenAPI 3.1OWUI tool server schema
/searchOpenAPI POSTsearch_music_knowledge(query) — BM25 search over 166 raga articles
/ragaOpenAPI POSTget_raga_info(raga_name) — exact raga article lookup
/api/configGET{"features": {"system": true}} — signals personality available
/systemGET{"prompt": "..."} — Hindustani music riyaz companion personality

Personality injection (automatic)

OWUI fetches /api/config on startup. If features.system == true, it fetches /system and injects the personality as a system prompt on every chat — without it being set on the model. Swap personality = swap MCP server.

Raga knowledge base

166 Wikipedia articles on Hindustani ragas, thaats, talas, gharanas, and music theory. Mounted from /path/to/home/raga_kb into both open-webui and music-mcp containers. BM25 search, top-3 results.

GPU / KV cache

  • KV cache: q8_0 (8-bit, requires flash_attn=auto — enforced by llama.cpp)
  • GPU: ROCm, RX 9070 XT, 16GB VRAM — 43–48/61 layers on GPU (vision projector OOMs → CPU)
  • Embedding (BGE-M3 in OWUI): DEVICE_TYPE=cpu — runs on CPU, no GPU competition
  • Power: ~90–200W during inference depending on load

Post-deploy OWUI configuration (required after fresh install)

After the containers start, two config rows must be set in OWUI’s SQLite DB. These are not in the compose — they are runtime state in /path/to/home/llm/open-webui/webui.db.

sudo docker exec open-webui python3 << 'PYEOF'
import sqlite3, json, time

db = sqlite3.connect("/app/backend/data/webui.db")
now = int(time.time())

# 1. Register music-mcp as OpenAPI tool server (exposes search + raga tools)
tool_server = [{
    "url": "http://music-mcp:8765",
    "type": "openapi",
    "key": "",
    "auth_type": "none",
    "spec_type": "url",
    "path": "openapi.json",
    "info": {
        "id": "music-knowledge",
        "name": "Music Knowledge",
        "description": "Hindustani classical music knowledge base"
    },
    "config": {
        "enable": True,
        "name": "Music Knowledge",
        "description": "Hindustani classical music knowledge base"
    }
}]
db.execute("UPDATE config SET value=?, updated_at=? WHERE key='tool_server.connections'",
           (json.dumps(tool_server), now))

# 2. Register music-mcp as terminal server (OWUI auto-fetches /system for personality)
terminal_server = [{
    "id": "music-mcp",
    "url": "http://music-mcp:8765",
    "key": "",
    "auth_type": "none",
    "config": {
        "enable": True,
        "name": "Music Personality",
        "description": "Hindustani classical music riyaz companion"
    }
}]
db.execute("UPDATE config SET value=?, updated_at=? WHERE key='terminal_server.connections'",
           (json.dumps(terminal_server), now))

db.commit()
db.close()
print("Done — restart open-webui to apply")
PYEOF

sudo docker restart open-webui

Rebuilding music-mcp image

The music-mcp:latest image is local (not in a registry). After a fresh OS install:

sudo docker build -t music-mcp:latest /path/to/home/llm/music-mcp/

The Dockerfile and server code are in this repo (music-mcp-Dockerfile, music-mcp-server.py). Copy them to /path/to/home/llm/music-mcp/ before building.