Lucia (pronounced LOO-sha) is an open-source, privacy-focused AI assistant that serves as a complete replacement for Amazon Alexa and Google Home. Built on the Microsoft Agent Framework with a multi-agent architecture, Lucia provides autonomous whole-home automation management through deep integration with Home Assistant. A full-featured React dashboard lets you manage agents, inspect traces, tune configuration, and export training dataβall from a single UI.
Lucia is named after Lucia, the ancient Nordic sun goddess associated with light, wisdom, and bringing illumination during the darkest time of year. In Norse mythology, Lucia represents the return of light and the power to guide through darknessβa fitting name for an AI assistant that brings intelligent automation and insight to your home.
The name is pronounced LOO-sha (or LOO-thee-ah in traditional Nordic pronunciation), with the emphasis on the first syllable.
- π€ Multi-Agent Orchestration β Router, dispatcher, and result aggregator executors coordinate specialized agents end-to-end using the A2A (Agent-to-Agent) protocol
- π§ Semantic Understanding β Natural language processing using embeddings and semantic searchβno rigid command structures required
- π HybridEntityMatcher β Multi-weighted entity search combining Levenshtein distance, Jaro-Winkler similarity, phonetic matching (Soundex/Metaphone), alias resolution, and embedding similarityβall tunable per-search
- π Privacy First β Fully local operation with optional cloud LLM support; your data stays yours
- π Deep Home Assistant Integration β Native integration via custom component with agent selection, conversation API, JSON-RPC communication, and WebSocket entity registry access
- ποΈ Entity Visibility Filtering β Control which Home Assistant entities Lucia can see via dashboard UI or by pulling the HA exposed-entity list over WebSocket
- π Live Activity Dashboard β Real-time agent mesh visualization with SSE-powered event streaming, summary metrics, and activity timeline
- π Management Dashboard β React-based dark-themed dashboard with 20+ pages for agent management, trace inspection, configuration, entity management, and dataset exports
- π§ Guided Setup Wizard β Multi-step onboarding with AI provider configuration, live connectivity tests, agent health gate, and Home Assistant plugin connection
- π¦ Kubernetes Ready β Cloud-native deployment with .NET Aspire, Helm charts, and K8s manifests
- β° Alarm Clock System β CRON-scheduled alarms with volume ramping, voice dismissal/snooze, presence-based speaker routing, and sound library with file upload
- π‘ Presence Detection β Auto-discovered motion/occupancy/mmWave sensors with room-level confidence scoring for context-aware automations
- π Scheduled Task System β Extensible CRON-based scheduler with MongoDB persistence supporting alarms, timers, and deferred agent actions
- π Extensible β Script-based plugin system for adding capabilities without recompiling. Plugin repository for discovery and one-click install.
- π οΈ Runtime Agent Builder β Create custom agents via the dashboard with MCP tool integrationβno code required
- π Model Provider System β Configure 6+ LLM backends (OpenAI, Azure OpenAI, Azure AI Inference, Ollama, Anthropic, Google Gemini) from the dashboard with per-agent model assignment
- π§ General Knowledge Fallback β Built-in
general-assistanthandles open-ended requests when no specialist is a clean match - π Dynamic Agent Selection β Switch between specialized agents (light control, climate, scenes, music, timers, lists, etc.) without reconfiguring
- π¬ Conversation Threading β Context-aware conversations with proper message threading support
- β‘ Two-Tier Prompt Caching β Independent routing and chat caches with semantic similarity matching, hot-reloadable thresholds, and infinite retention
| Platform | Status |
|---|---|
| Azure OpenAI / AI Foundry | β Supported |
| OpenAI | β Supported |
| Ollama | β Supported |
| Anthropic (Claude) | β Supported |
| Google Gemini | β Supported |
| Azure AI Inference | β Supported |
| OpenAI-compatible (Open Router, etc.) | β Supported |
| GitHub Copilot SDK | π§ͺ Experimental |
| ONNX | β No function calling support |
- Docker and Docker Compose
- Home Assistant instance (2024.12 or later)
- An LLM provider API key (Azure AI Foundry, OpenAI, Ollama, etc.)
-
Create a
docker-compose.ymlanywhere on your machine:services: lucia-redis: image: redis:8.2-alpine container_name: lucia-redis networks: [lucia-network] ports: ["127.0.0.1:6379:6379"] command: > redis-server --appendonly yes --maxmemory 256mb --maxmemory-policy allkeys-lru volumes: [lucia-redis-data:/data] healthcheck: test: ["CMD", "redis-cli", "PING"] interval: 30s timeout: 10s retries: 3 restart: unless-stopped lucia-mongo: image: mongo:8.0 container_name: lucia-mongo networks: [lucia-network] ports: ["127.0.0.1:27017:27017"] volumes: [lucia-mongo-data:/data/db] healthcheck: test: ["CMD", "mongosh", "--eval", "db.runCommand('ping').ok"] interval: 30s timeout: 10s retries: 3 restart: unless-stopped lucia: image: seiggy/lucia-agenthost:latest container_name: lucia depends_on: lucia-redis: { condition: service_healthy } lucia-mongo: { condition: service_healthy } networks: [lucia-network] ports: ["7233:8080"] environment: - ASPNETCORE_ENVIRONMENT=Production - ASPNETCORE_URLS=http://+:8080 - ConnectionStrings__luciatraces=mongodb://lucia-mongo:27017/luciatraces - ConnectionStrings__luciaconfig=mongodb://lucia-mongo:27017/luciaconfig - ConnectionStrings__luciatasks=mongodb://lucia-mongo:27017/luciatasks - ConnectionStrings__redis=lucia-redis:6379 - DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=false - DOTNET_RUNNING_IN_CONTAINER=true healthcheck: test: ["CMD-SHELL", "wget -qO- http://localhost:8080/health || exit 1"] interval: 30s timeout: 10s retries: 3 restart: unless-stopped networks: lucia-network: driver: bridge volumes: lucia-redis-data: lucia-mongo-data:
-
Start the stack
docker compose up -d
| Image Tag | GPU | Size | Use Case |
|---|---|---|---|
seiggy/lucia-agenthost:latest |
None | ~250MB | Base orchestration (no voice) |
seiggy/lucia-agenthost:voice |
NVIDIA CUDA 12.8 | ~3GB | Voice + NVIDIA GPU acceleration |
seiggy/lucia-agenthost:voice-cpu |
None | ~3GB | Voice with CPU-only inference |
seiggy/lucia-agenthost:ha-mono |
None | ~350MB | Home Assistant add-on (mono-container, no Redis/MongoDB) |
| Self-build only | AMD ROCm 6.4 | ~25GB | Voice + AMD GPU acceleration |
Note: The ROCm image is not published to Docker Hub due to its ~25GB size exceeding CI storage limits. AMD GPU users can build it locally:
docker build -t lucia:voice-rocm -f infra/docker/Dockerfile.voice-rocm .The image is large because AMD's ROCm runtime (~20GB) is much less modular than NVIDIA's CUDA runtime (~1.5GB). This is an upstream constraint. If disk space is a concern, the
voice-cpuimage provides CPU-only inference that is still fast enough for real-time voice processing on modern hardware.
To use the voice variants, change the image in your docker-compose.yml:
# NVIDIA GPU (requires nvidia-container-toolkit)
image: seiggy/lucia-agenthost:voice
# AMD GPU (requires ROCm kernel driver + --device /dev/kfd --device /dev/dri)
image: seiggy/lucia-agenthost:voice-rocm
# CPU only (no GPU requirements)
image: seiggy/lucia-agenthost:voice-cpuThe ha image variant runs Lucia as a single container with no external dependencies β no Redis, no MongoDB. It uses in-memory caching and SQLite for persistence, making it ideal for Home Assistant add-on deployments or resource-constrained devices.
docker build -f infra/docker/Dockerfile.ha -t lucia:ha .
docker run -d \
--name lucia \
--network host \
-v lucia-data:/data \
-v lucia-models:/app/models \
-v lucia-plugins:/app/plugins \
lucia:ha| Mount Point | Purpose | Required |
|---|---|---|
/data |
SQLite database (lucia.db) β all configuration, traces, tasks, and user data |
Yes β data persists across restarts |
/app/models |
Wyoming voice models (STT, VAD, wake word, speaker embedding) | Recommended β avoids re-downloading models |
/app/plugins |
Lua/script plugins | Optional |
| Port | Protocol | Purpose |
|---|---|---|
| 8099 | HTTP | Web dashboard and REST API |
| 10400 | TCP | Wyoming voice protocol |
| Variable | Default | Description |
|---|---|---|
DataProvider__Cache |
InMemory |
Cache backend (InMemory or Redis) |
DataProvider__Store |
SQLite |
Persistence backend (SQLite or MongoDB) |
DataProvider__SqlitePath |
/data/lucia.db |
SQLite database file path |
HomeAssistant__BaseUrl |
β | Home Assistant URL (e.g. http://homeassistant.local:8123) |
HomeAssistant__AccessToken |
β | Home Assistant long-lived access token |
Lucia supports pluggable data providers, letting you choose between full-scale (Redis + MongoDB) and lightweight (InMemory + SQLite) backends:
| Configuration | Cache | Store | Use Case |
|---|---|---|---|
| Default | Redis | MongoDB | Full deployment with dedicated infrastructure |
| Lightweight | InMemory | SQLite | Home Assistant add-on, single-container, resource-constrained |
| Hybrid | InMemory | MongoDB | Reduce infrastructure while keeping durable document store |
| Hybrid | Redis | SQLite | Shared cache with embedded persistence |
To switch providers on any deployment, set the environment variables:
# Lightweight mode (no external dependencies)
-e DataProvider__Cache=InMemory
-e DataProvider__Store=SQLite
# Default mode (requires Redis + MongoDB)
-e DataProvider__Cache=Redis
-e DataProvider__Store=MongoDBNote: The HA image (
Dockerfile.ha) defaults to InMemory + SQLite. The standard images (Dockerfile,Dockerfile.voice*) default to Redis + MongoDB.
-
Open the Lucia Dashboard
Navigate to
http://localhost:7233. On first launch, the setup wizard guides you through configuration:Step 1 β Welcome: Overview of what the wizard will configure.
Step 2 β Configure: Generate a Dashboard API key and connect to your Home Assistant instance by entering its URL and a long-lived access token.
Step 3 β Connect HA Plugin: Generate an API key for the Home Assistant custom component, configure it in HA, and wait for the plugin to connect back to Lucia.
Step 4 β Done: Setup is complete. You'll use the generated API key to sign in.
-
Sign in to the Dashboard
Enter the API key generated during setup to access the full dashboard.
-
Install the Home Assistant Integration
Option A: HACS (Recommended)
- Go to HACS β Integrations β three-dot menu β Custom repositories
- Add repository URL:
https://github.com/seiggy/lucia-dotnet - Select category: Integration β Click "Add"
- Find "Lucia" in HACS and click "Download"
- Restart Home Assistant
- Add integration: Settings β Devices & Services β Add Integration β Lucia
Option B: Manual Installation
cp -r custom_components/lucia /path/to/homeassistant/custom_components/ # Restart Home Assistant, then add the integration via UI
Lucia includes a full-featured React dashboard for managing your agent platform. Built with React 19, Vite 7, TanStack Query, and Tailwind CSS, it runs as part of the Aspire-orchestrated development stack.
The default landing page shows real-time platform metrics and a live agent mesh visualization. Summary cards display total requests, error rate, cache hit rate, and task completion. The interactive mesh graph (powered by React Flow) shows the orchestrator, agents, and tools with animated connections during active requests. A live activity feed streams SSE events as they happenβrouting decisions, tool calls, agent completions, and errorsβall in real time.
Monitor every conversation passing through the orchestrator. Filter by label, agent, and date range. View stats at a glance with color-coded counters for positive, negative, unlabeled, and errored traces. Click any trace to see the full routing decision, agent execution details, and tool calls.
View all registered agents with their capabilities, skills, and connection status. Register new A2A agents, refresh agent metadata, and send test messages directly from the dashboard. Each agent card shows its version, endpoint URL, supported capabilities (Push, Streaming, History), and associated skills.
Create and manage custom agents at runtimeβno code changes required. Each agent definition includes a name, system prompt, optional model connection override, and a granular MCP tool picker. Tags indicate system vs. user-defined agents. Changes take effect immediately; agents are loaded from MongoDB on each invocation.
Manage LLM provider connections across the platform. Configure Azure AI Foundry, OpenAI, Ollama, and other OpenAI-compatible endpoints. Each provider card shows the model name, endpoint URL, and deployment type. Copilot-connected models display a badge.
Register and manage MCP (Model Context Protocol) tool servers. Add stdio-based local tools (e.g., dnx .NET tools) or remote HTTP/SSE servers. Connect servers to discover available tools, view connection status, and manage environment variables and authentication headers.
Schema-driven configuration editor with categorized settings. Manage Home Assistant connection details, orchestration parameters (RouterExecutor, AgentInvoker, ResultAggregator), Redis/MongoDB connection strings, Music Assistant integration, trace capture settings, and agent definitionsβall from one page. Sensitive values are masked with a "Show secrets" toggle. Mobile-friendly with a dropdown category selector on small screens.
Export labeled conversation traces as training datasets. Filter by label, date range, and agent. Optionally include human corrections for RLHF-style fine-tuning. View export history and re-download previous exports.
Monitor the routing prompt cache that accelerates repeated queries. View cache statistics (total entries, hit rate, hits vs misses), browse cached entries with their routed agents and confidence scores, and clear the cache when needed. Tabbed view separates Router and Agent cache namespaces with independent stats.
Track active and archived tasks with status counters (Active, Completed, Failed, Cancelled). Switch between Active Tasks and Task History views to monitor ongoing work and review completed operations.
Manage the Home Assistant entity hierarchy β floors, areas, and entities β with visibility controls. Toggle entity visibility to control which devices Lucia agents can see. Pull the HA exposed-entity list over WebSocket for pre-filtered entity management. Search and filter entities by area, domain, or name.
Interactive testing page for the HybridEntityMatcher. Enter a search query and see scored results with per-signal breakdowns (Levenshtein, Jaro-Winkler, phonetic, embedding similarity, alias match). Useful for tuning match weights and diagnosing entity resolution issues.
Lucia uses the A2A (Agent-to-Agent) Protocol with JSON-RPC 2.0 for agent communication. The orchestrator routes incoming requests to the best-fit specialized agent, with results aggregated and returned to Home Assistant.
graph TB
HA[Home Assistant] <-->|Conversation API| HP[Lucia Custom Component]
HP <-->|JSON-RPC| AH[AgentHost]
AH <--> O[Orchestrator]
O <--> Router[RouterExecutor]
O <--> Dispatch[AgentDispatchExecutor]
O <--> Agg[ResultAggregatorExecutor]
Dispatch <--> LA[LightAgent]
Dispatch <--> CA[ClimateAgent]
Dispatch <--> SA[SceneAgent]
Dispatch <--> LiA[ListsAgent]
Dispatch <--> GA[GeneralAgent]
Dispatch <-->|A2A| A2A[A2AHost]
A2A <--> MA[MusicAgent]
A2A <--> TA[TimerAgent]
AH <--> DB[(MongoDB)]
AH <--> Cache[(Redis)]
AH <--> Dashboard[React Dashboard]
subgraph "LLM Providers"
Azure[Azure AI Foundry]
OAI[OpenAI]
Ollama[Ollama]
Anthropic[Anthropic]
Gemini[Google Gemini]
end
Router -.-> Azure
LA -.-> Azure
GA -.-> OAI
MA -.-> Azure
- User Input β Home Assistant receives a voice or text command
- Conversation API β Lucia custom component sends the message via JSON-RPC
- Orchestrator β RouterExecutor selects the best agent using semantic matching and prompt caching
- Agent Dispatch β AgentDispatchExecutor forwards the request (in-process or via A2A)
- LLM Processing β The selected agent calls its LLM with domain-specific tools
- Result Aggregation β ResultAggregatorExecutor formats the final response
- Response β JSON-RPC response returned to Home Assistant for speech output
| Component | Description |
|---|---|
AgentHost (lucia.AgentHost) |
Main API server hosting the orchestrator, agents, auth, configuration, and dashboard proxy |
A2AHost (lucia.A2AHost) |
Satellite host for running agents as separate processes (MusicAgent, TimerAgent) |
Orchestrator (lucia.Agents/Orchestration) |
Router β Dispatch β Aggregator pipeline for multi-agent coordination |
Dashboard (lucia-dashboard) |
React 19 SPA with 20+ pages for management, traces, entity control, exports, and configuration |
Home Assistant Integration (custom_components/lucia) |
Python custom component with conversation platform |
HomeAssistant Client (lucia.HomeAssistant) |
Strongly-typed .NET client for the HA REST and WebSocket APIs |
Entity Location Service (lucia.Agents/Services) |
Centralized entity resolution with hierarchical floor/area/entity search and Redis caching |
HybridEntityMatcher (lucia.Agents/Models) |
Multi-weighted entity matching engine (Levenshtein, Jaro-Winkler, phonetic, embeddings, aliases) |
Model Provider System (lucia.Agents/Services) |
Configurable LLM backend management with per-agent model assignment and connection testing |
Plugin System (lucia.Agents/Extensions) |
Roslyn script plugin engine with four-hook lifecycle, repository management, and dashboard UI |
Alarm Clock System (lucia.Agents/Alarms) |
CRON-scheduled alarms with volume ramping, sound library, and voice dismissal |
Presence Detection (lucia.Agents/Services) |
Auto-discovered room-level presence with confidence-weighted sensor fusion |
lucia-dotnet/
βββ lucia.AppHost/ # .NET Aspire orchestrator (recommended dev entrypoint)
βββ lucia.AgentHost/ # ASP.NET Core API host
β βββ Auth/ # API key authentication and session management
β βββ Extensions/ # Setup, Configuration, A2A, Plugin, and Auth API endpoints
β βββ plugins/ # Agent Framework plugins
βββ lucia.A2AHost/ # A2A satellite agent host
β βββ AgentRegistry/ # Agent card registration
β βββ Extensions/ # A2A endpoint mapping
β βββ Services/ # Agent initialization
βββ lucia.Agents/ # Shared agent implementations and orchestration
β βββ Abstractions/ # ILuciaPlugin, IWebSearchSkill, IEntityLocationService, IHybridEntityMatcher
β βββ Agents/ # GeneralAgent, LightAgent, ClimateAgent, SceneAgent, ListsAgent, OrchestratorAgent
β βββ Configuration/ # Plugin, repository, and manifest models
β βββ Extensions/ # PluginLoader, PluginScriptHost, service registrations
β βββ Integration/ # SearchTermCache, SearchTermNormalizer
β βββ Models/ # HybridEntityMatcher, HomeAssistantEntity, HybridMatchOptions
β βββ Orchestration/ # RouterExecutor, AgentDispatchExecutor, etc.
β βββ Registry/ # Agent discovery and registration
β βββ Services/ # EntityLocationService, PresenceDetection, PluginManagement, ModelProviders
β βββ Skills/ # LightControlSkill, ClimateControlSkill, FanControlSkill, SceneControlSkill, ListSkill
β βββ Training/ # Trace capture and export
βββ lucia.MusicAgent/ # Music Assistant playback agent (A2AHost)
βββ lucia.TimerAgent/ # Timer and reminder agent (A2AHost)
βββ lucia.Data/ # Lightweight data providers (InMemory cache + SQLite repositories)
βββ lucia.HomeAssistant/ # Strongly-typed HA REST API client
β βββ Models/ # Entity, state, and service models
β βββ Services/ # IHomeAssistantClient implementation
β βββ Configuration/ # Client settings
βββ lucia-dashboard/ # React 19 + Vite 7 management dashboard
β βββ src/
β βββ pages/ # Activity, Traces, Agents, AgentDefs, ModelProviders, McpServers, Config, Exports, Cache, Tasks, Alarms, Presence, Plugins, EntityLocation, MatcherDebug, SkillOptimizer, Lists
β βββ components/ # MeshGraph, PluginRepoDialog, RestartBanner, shared UI
β βββ hooks/ # useActivityStream and custom React hooks
β βββ context/ # Auth context and providers
β βββ api.ts # API client functions
βββ plugins/ # Plugin scripts (each subfolder = one plugin)
β βββ metamcp/plugin.cs # MetaMCP tool aggregation bridge
β βββ searxng/plugin.cs # SearXNG web search skill
βββ lucia-plugins.json # Official plugin repository manifest
βββ lucia.ServiceDefaults/ # OpenTelemetry, health checks, resilience
βββ lucia.Tests/ # xUnit tests (unit, integration, eval, plugin system)
βββ custom_components/lucia/ # Home Assistant Python custom component
β βββ conversation.py # JSON-RPC conversation platform
β βββ config_flow.py # HA configuration UI with agent selection
β βββ translations/ # Multi-language UI strings
βββ infra/ # Deployment infrastructure
βββ docker/ # Dockerfiles and docker-compose.yml
βββ kubernetes/
β βββ manifests/ # K8s YAML manifests
β βββ helm/ # Helm chart
βββ systemd/ # systemd service units
Lucia uses a schema-driven configuration system stored in MongoDB. On first run, the setup wizard guides you through the essential settings. After setup, all configuration can be managed through the dashboard's Configuration page.
When deploying with Docker or automation, you can skip the setup wizard by providing all required values via environment variables. If both a dashboard API key and a Home Assistant connection are present (in the config store or seeded from env), Lucia marks setup complete and the wizard is not shown.
| Variable | Purpose |
|---|---|
DASHBOARD_API_KEY |
Dashboard login key (e.g. lk_...). Used to seed the Dashboard API key. |
HOMEASSISTANT__BASEURL |
Home Assistant instance URL (e.g. http://homeassistant.local:8123). |
HOMEASSISTANT__ACCESSTOKEN |
Long-lived access token from HA (Profile β Long-Lived Access Tokens). |
LUCIA_HA_API_KEY |
Optional: API key for the Home Assistant integration (same as shown in the wizard). |
MUSICASSISTANT__INTEGRATIONID |
Optional: HA Music Assistant config entry ID for the music agent. |
The Docker image includes the official plugins (MetaMCP, SearXNG) under /app/plugins. To register tools from env without using the dashboard:
| Variable | Purpose |
|---|---|
SEARXNG_URL |
When set, the General Agent gets a web_search tool (SearXNG instance URL). |
METAMCP_URL |
When set, MetaMCP is seeded as an MCP tool server (full URL to SSE or MCP endpoint). |
METAMCP_API_KEY |
Optional: Bearer token for MetaMCP (e.g. from Open Web UI Dashboard β Keys). |
See infra/docker/.env.lucia.example for a full template. ComfyUI, Whisper, Piper, and Wyoming env vars are not used by Lucia (they may be used by other stacks such as Open Web UI).
| Section | Description |
|---|---|
| HomeAssistant | Base URL, access token, API timeout, SSL validation |
| RouterExecutor | Agent routing model, semantic similarity threshold |
| AgentInvoker | Agent execution timeout settings |
| ResultAggregator | Response aggregation settings |
| Redis | Connection string and task persistence TTL |
| MusicAssistant | Music Assistant integration settings |
| TraceCapture | Conversation trace storage settings |
| ConnectionStrings | AI Foundry, MongoDB, and Redis connection details |
| Agents | Agent definitions and registration |
| ModelProviders | LLM backend configurations (per-agent model assignment) |
| PromptCache | Routing and chat cache thresholds (hot-reloadable) |
After installing the custom component:
- Go to Settings β Devices & Services β Add Integration β Lucia
- Enter your Agent Repository URL (e.g.,
https://localhost:7235) - Add the API Key generated during dashboard setup
- Configure agent selection β choose from discovered agents in the dropdown
- Set as your conversation agent under Settings β Voice Assistants β Assist
Agents communicate via the A2A Protocol with JSON-RPC 2.0. The AgentHost runs in-process agents (LightAgent, ClimateAgent, SceneAgent, ListsAgent, GeneralAgent, Orchestrator) while the A2AHost runs satellite agents (MusicAgent, TimerAgent) as separate processes.
# List all registered agents
curl http://localhost:5151/agentscurl -X POST http://localhost:5151/a2a/light-agent \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "message/send",
"params": {
"message": {
"kind": "message",
"role": "user",
"parts": [{"kind": "text", "text": "Turn on the living room lights"}],
"messageId": "550e8400-e29b-41d4-a716-446655440000",
"contextId": "550e8400-e29b-41d4-a716-446655440001"
}
},
"id": 1
}'Lucia supports creating agents at runtime through the dashboard UI. Custom agents are stored in MongoDB and loaded dynamicallyβno code changes or restarts required.
1. Register MCP Tool Servers
Navigate to MCP Servers in the dashboard and add your tool servers:
- stdio transports β local processes (e.g.,
dnx my-tool,npx @scope/tool). The container ships with the .NET SDK, sodnxtools work out of the box. Fornpx,python, or other runtimes, extend the container image. - HTTP/SSE transports β remote MCP servers accessible via URL.
After adding a server, click Connect then Discover Tools to see available tools.
2. Define an Agent
Navigate to Agent Definitions and click New Agent:
| Field | Description |
|---|---|
| Name | Unique agent identifier (e.g., research-agent) |
| Display Name | Human-readable name for the dashboard |
| Instructions | System prompt that defines the agent's behavior |
| Model Connection | Optional override (blank = default model) |
| MCP Tools | Select individual tools from registered MCP servers |
3. Use the Agent
Once saved, the agent is immediately available to the orchestrator's router. The router considers the agent's description and tool capabilities when making routing decisions. No reload requiredβagents are loaded from MongoDB on each invocation.
Extending the container for non-.NET runtimes:
# Example: Add Node.js for npx-based MCP tools
FROM ghcr.io/seiggy/lucia-dotnet:latest
RUN apt-get update && apt-get install -y nodejs npmLucia features a script-based plugin system powered by Roslyn CSharpScript. Plugins are plain C# files β no project files, no separate DLLs, no compilation step. Drop a folder with a plugin.cs into the plugins/ directory and Lucia loads it at startup.
Plugins implement the ILuciaPlugin interface and participate in four lifecycle hooks, called in order:
| Hook | When | Use Case |
|---|---|---|
ConfigureServices(IHostApplicationBuilder) |
Before app is built | Register DI services (e.g., IWebSearchSkill) |
ExecuteAsync(IServiceProvider, CancellationToken) |
After app is built, before HTTP starts | Run initialization, seed data |
MapEndpoints(WebApplication) |
During endpoint registration | Add custom HTTP endpoints |
OnSystemReadyAsync(IServiceProvider, CancellationToken) |
After all agents are online | Logic that depends on agents or Home Assistant |
All hooks have default no-op implementations β only override what you need.
1. Create a folder under plugins/ with your plugin's ID:
plugins/
βββ my-plugin/
βββ plugin.cs
2. Write your plugin.cs β the script must define a class implementing ILuciaPlugin and end with an expression that returns an instance of it:
// plugins/my-plugin/plugin.cs
using lucia.Agents.Abstractions;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
public class MyPlugin : ILuciaPlugin
{
public string PluginId => "my-plugin";
public void ConfigureServices(IHostApplicationBuilder builder)
{
// Register services into the DI container before the app is built
builder.Services.AddSingleton<IMyService, MyServiceImpl>();
}
public async Task ExecuteAsync(IServiceProvider services, CancellationToken ct = default)
{
var logger = services.GetRequiredService<ILoggerFactory>().CreateLogger("MyPlugin");
logger.LogInformation("My plugin initialized.");
}
public async Task OnSystemReadyAsync(IServiceProvider services, CancellationToken ct = default)
{
// Agents and Home Assistant are fully available here
var logger = services.GetRequiredService<ILoggerFactory>().CreateLogger("MyPlugin");
logger.LogInformation("System ready β all agents online.");
}
}
// The last expression MUST return an ILuciaPlugin instance
new MyPlugin()3. That's it. Restart Lucia and your plugin will be discovered and loaded automatically.
Plugin scripts run in a sandboxed Roslyn environment with a curated set of assemblies and auto-imported namespaces. You do not need using directives for these β they are pre-imported:
Auto-imported namespaces:
| Namespace | Description |
|---|---|
System |
Core .NET types |
System.Collections.Generic |
Lists, dictionaries, etc. |
System.Linq |
LINQ query operators |
System.Threading |
CancellationToken, synchronization |
System.Threading.Tasks |
Task, ValueTask, async patterns |
System.Net.Http |
HttpClient, IHttpClientFactory |
lucia.Agents.Abstractions |
ILuciaPlugin, IWebSearchSkill, etc. |
Microsoft.Extensions.DependencyInjection |
IServiceCollection, AddSingleton, etc. |
Microsoft.Extensions.Hosting |
IHostApplicationBuilder, BackgroundService |
Microsoft.Extensions.Logging |
ILogger, ILoggerFactory |
Microsoft.Extensions.Configuration |
IConfiguration |
Microsoft.Extensions.AI |
AITool, AIFunctionFactory |
Additional assemblies available (require explicit using in your script):
| Assembly | Key Types |
|---|---|
System.Text.Json |
JsonSerializer, JsonSerializerOptions |
System.ComponentModel.Primitives |
DescriptionAttribute |
System.Diagnostics.DiagnosticSource |
ActivitySource, Meter, Counter<T>, Histogram<T> |
Microsoft.AspNetCore |
WebApplication, IEndpointRouteBuilder |
Note: If you need an assembly that isn't listed above, the plugin won't compile. File an issue or PR to add it to the host's reference set in
PluginScriptHost.cs.
MetaMCP Bridge (plugins/metamcp/) β Seeds a MetaMCP tool server into the agent registry when METAMCP_URL (and optionally METAMCP_API_KEY) are set. The plugin runs in OnSystemReadyAsync so the host invokes it after agents and HA are ready.
SearXNG Web Search (plugins/searxng/) β Registers IWebSearchSkill so the GeneralAgent gains web search:
public sealed class SearXngPlugin : ILuciaPlugin
{
public string PluginId => "searxng";
public void ConfigureServices(IHostApplicationBuilder builder)
{
var url = builder.Configuration["SearXng:BaseUrl"];
if (!string.IsNullOrWhiteSpace(url))
{
builder.Services.AddSingleton<IWebSearchSkill>(sp =>
new SearXngWebSearchSkill(
sp.GetRequiredService<IHttpClientFactory>(),
url,
sp.GetRequiredService<ILoggerFactory>().CreateLogger<SearXngWebSearchSkill>()));
}
}
}
// ... skill class, then:
new SearXngPlugin()Plugins can be discovered, installed, and managed through the dashboard's Plugins page. Repositories are remote or local sources that provide a manifest of available plugins.
Every repository is defined by a lucia-plugins.json manifest file:
{
"id": "lucia-official",
"name": "Lucia Official Plugins",
"plugins": [
{
"id": "metamcp",
"name": "MetaMCP Bridge",
"description": "Bridges MetaMCP tool aggregation into Lucia agents.",
"version": "1.0.0",
"path": "plugins/metamcp"
},
{
"id": "searxng",
"name": "SearXNG Web Search",
"description": "Privacy-respecting web search via SearXNG.",
"version": "1.0.0",
"path": "plugins/searxng"
}
]
}| Field | Required | Description |
|---|---|---|
id |
β | Unique repository identifier |
name |
β | Human-readable repository name |
plugins |
β | Array of plugin entries |
plugins[].id |
β | Unique plugin identifier |
plugins[].name |
β | Display name |
plugins[].description |
β | Short description |
plugins[].version |
β | SemVer version string |
plugins[].path |
β | Path to the plugin folder, relative to the repo root |
plugins[].author |
β | Author name |
plugins[].tags |
β | Array of tags for categorization |
To publish your own plugins as a repository:
- Create a GitHub repository with your plugins under a
plugins/directory - Add a
lucia-plugins.jsonat the repo root with your manifest - Each plugin must have a
plugin.csentry point in its folder - Add the repo in Lucia β go to Plugins β Repositories β Add Repository, enter your GitHub URL and branch
When adding a Git-based repository, the blobSource field controls how plugin archives are downloaded:
| Strategy | Behavior |
|---|---|
release (default) |
Fetches the latest GitHub Release. Looks for a {pluginId}.zip asset first, falls back to the release zipball, then to a branch archive. Best for production repositories. |
tag |
Downloads the archive at a specific tag (Branch field = tag name). Useful for pinning to a known version. |
branch |
Downloads the archive at branch HEAD. Best for development or bleeding-edge tracking. |
The release strategy is recommended for production use β publish per-plugin zip files as GitHub Release assets for the fastest, most targeted downloads.
The Plugins page has three tabs:
- Installed β View, enable/disable, and uninstall plugins. Changes require an app restart (a banner will prompt you).
- Store β Browse available plugins from all configured repositories. One-click install.
- Repositories β Add, remove, and sync plugin repositories. Supports both local (development) and Git (production) sources.
- .NET 10 SDK or later
- Node.js 22+ (for the dashboard)
- Docker (required for Redis and MongoDB via Aspire)
# Build the entire solution
dotnet build lucia-dotnet.slnx
# Run via Aspire (recommended β starts all services in mesh mode)
dotnet run --project lucia.AppHost
# Run tests (excludes slow eval tests)
dotnet test --filter 'Category!=Eval'
# Run all tests including LLM-based evals
dotnet test
# Run AgentHost directly (without Aspire)
dotnet run --project lucia.AgentHost
# Dashboard dev server (standalone)
cd lucia-dashboard && npm install && npm run devWhen running via Aspire AppHost:
| Service | HTTP | HTTPS |
|---|---|---|
| AgentHost API | http://localhost:5151 |
https://localhost:7235 |
| Dashboard | Assigned by Aspire | β |
| Aspire Dashboard | β | https://localhost:17274 |
| API Documentation (Scalar) | β | https://localhost:7235/scalar |
| Health Check | http://localhost:5151/health |
β |
To build from source instead of using the pre-built image:
git clone https://github.com/seiggy/lucia-dotnet.git
cd lucia-dotnet/infra/docker
docker compose up -dThe docker-compose.yml in the repo builds the image from the local Dockerfile. See infra/docker/DEPLOYMENT.md for the full deployment guide.
Lucia supports two deployment topologies controlled by the Deployment__Mode environment variable:
| Mode | Value | Description |
|---|---|---|
| Standalone (default) | standalone |
All agents (Music, Timer, etc.) run embedded in the main AgentHost process. Simplest setup β single container plus Redis and MongoDB, or zero-dependency with the HA image (InMemory + SQLite). Recommended for most users. |
| Mesh | mesh |
Agents run as separate A2A containers that register with the AgentHost over the network. Used for Kubernetes deployments, horizontal scaling, or multi-node distribution. |
β οΈ Single-Instance Constraint: The AgentHost must run as a single instance (no horizontal scaling via replicas). The in-memoryScheduledTaskStoreandActiveTimerStorehold active alarms and timers β running multiple replicas would split scheduled task state across instances. For high availability, use a single replica with fast restart policies rather than multiple replicas behind a load balancer. This constraint applies to both standalone and mesh modes (the AgentHost itself must be single-instance; mesh agents can scale independently).
When to use each mode:
- Standalone β Home lab, single-server, Docker Compose, or any deployment where simplicity matters. External A2A agents can still connect to a standalone AgentHost.
- Mesh β Kubernetes clusters, multi-node setups, or when you want to scale individual agents independently. The Helm chart and K8s manifests default to mesh mode.
To switch modes, add the environment variable to your docker-compose.yml:
environment:
- Deployment__Mode=mesh# Using manifests
kubectl apply -f infra/kubernetes/manifests/
# Using Helm
helm install lucia infra/kubernetes/helm/lucia-helm \
--namespace lucia --create-namespaceThe Kubernetes deployment runs in mesh mode by default, with Music Agent and Timer Agent as separate pods. See infra/kubernetes/ for manifests and Helm chart documentation.
For bare-metal or VM deployments, systemd service units are provided in infra/systemd/.
Lucia can run as a Home Assistant add-on using the mono-container image:
- Build:
docker build -f infra/docker/Dockerfile.ha -t lucia:ha . - The add-on configuration is in
ha-addon/withconfig.yamlfor the HA Supervisor - All data persists in
/data/lucia.db(SQLite) β back up this single file to preserve your configuration, traces, and scheduled tasks
See Home Assistant Add-on (Mono-Container) for full setup details.
Lucia includes OpenTelemetry instrumentation out of the box via the lucia.ServiceDefaults project:
- Traces β Distributed tracing across orchestrator, agents, and Home Assistant API calls
- Metrics β Request rates, agent execution duration, LLM token usage
- Logs β Structured logging with correlation IDs and agent-specific filtering
The Aspire Dashboard provides built-in log aggregation, trace visualization, and metrics during development. Lucia's own Activity Dashboard shows a live agent mesh graph and real-time event stream. For production, export to Prometheus, Grafana, Jaeger, or any OTLP-compatible backend.
- Multi-agent orchestration with Router β Dispatch β Aggregator pipeline
- LightAgent with semantic entity search
- ClimateAgent with HVAC and fan control
- SceneAgent for scene activation and management
- ListsAgent for todo and reminder list management
- MusicAgent for Music Assistant playback
- TimerAgent with background timer lifecycle and satellite announce
- Entity Location Service with floor/area/alias/feature resolution
- HybridEntityMatcher with multi-weighted search (Levenshtein, Jaro-Winkler, phonetic, embeddings, aliases)
- Unified entity architecture with
HomeAssistantEntitybase class and domain subtypes - Entity visibility filtering with dashboard controls and HA exposed-entity WebSocket support
- Model Provider system with 6+ LLM backends configurable from the dashboard
- Runtime MCP tool server registration and dynamic agent definitions with hot-reload
- A2A Protocol (JSON-RPC 2.0) implementation
- Home Assistant custom component with agent selection
- Guided setup wizard with AI provider configuration, agent health gate, and resume flow
- React management dashboard (20+ pages) with traces, entity management, exports, configuration
- Live Activity Dashboard with real-time agent mesh visualization
- Full OpenTelemetry coverage for LLM calls (gen_ai.* spans)
- Per-agent error rate metrics and observability
- Two-tier prompt caching (routing + chat) with semantic similarity and hot-reloadable thresholds
- Helm charts and Kubernetes manifests
- Multi-LLM support (Azure AI Foundry, OpenAI, Ollama, Anthropic, Google Gemini, Azure AI Inference)
- Dataset export for fine-tuning workflows
- Schema-driven configuration system
- Playwright E2E tests for all agent routing modes
- Scheduled Task System with CRON scheduling and MongoDB persistence
- Alarm Clock System with volume ramping and voice dismissal
- Presence Detection Service with auto-discovered sensors and confidence levels
- Alarm Clocks dashboard page with CRON builder and sound management
- Presence Detection dashboard page with sensor management
- Alarm sound file upload with HA media library integration
- Mesh mode deployment hardening (conditional service registration, URL resolution, endpoint deduplication)
- Script-based plugin system with Roslyn CSharpScript, four-hook lifecycle, and plugin repository management
- Plugin dashboard with store, install/uninstall, enable/disable, and repository management
- Internal token authentication for service-to-service A2A communication
- SemVer versioning with preview release support in CI/CD
- Matcher debug API and dashboard page for testing entity search queries
- Pluggable data providers (InMemory + SQLite) for mono-container deployment
- Home Assistant add-on Dockerfile with CPU-only ONNX
- Unified entity search pipeline (replacing per-skill entity lookups with HybridEntityMatcher)
- WebSocket real-time event streaming from Home Assistant (persistent connection)
- HACS store listing for one-click installation
- CalendarAgent (calendar management and scheduling)
- SecurityAgent (security monitoring and alerts)
- Pattern recognition and automation suggestions
- Local LLM optimization (Ollama performance tuning, edge deployment)
- Voice integration (local STT/TTS)
- GitHub Copilot SDK as a first-class LLM provider
- Mobile companion app
See .docs/product/roadmap.md for the detailed roadmap.
We welcome contributions! Whether you're fixing bugs, adding agents, or improving documentation.
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Make your changes following existing code style and conventions
- Add tests for new functionality
- Commit using conventional commits:
git commit -m 'feat: add amazing feature' - Push and open a Pull Request
- π€ New specialized agents (security, calendar, media, etc.)
- π Community plugins (search providers, notification services, calendar integrations)
- π§ Additional LLM provider integrations
- π Enhanced Home Assistant integrations
- π Dashboard features and improvements
- π Documentation
- π§ͺ Test coverage
- π Translations for the Home Assistant custom component
This project is licensed under the MIT License β see the LICENSE file for details.
- Microsoft Agent Framework β AI orchestration framework powering our agents
- Home Assistant β Open-source home automation platform
- .NET Aspire β Cloud-native app development stack
- A2A Protocol β Standardized agent communication protocol
- Music Assistant β Universal music library and playback system
- π Bug Reports: GitHub Issues
- π¬ Discussions: GitHub Discussions
- π Home Assistant: Community Forum
Built with β€οΈ for the Home Assistant community















