Configuration
TOML config with sensible defaults — credentials in muninn.toml.local (gitignored)
Config Precedence
1. MUNINN_CONFIG env var → path to config file
2. Falls back to muninn.toml in working directory
3. muninn.toml.local is gitignored — used for real credentials
4. Systemd service sets MUNINN_CONFIG=muninn.toml.local
[matrix]
| Key | Type | Description |
homeserver | String | Matrix homeserver URL |
user_id | String | Bot's Matrix user ID |
password | String | Bot's password |
store_path | String? | E2EE crypto store path |
sync_timeout | u64? | Sync timeout in seconds (default: 10) |
allowed_users | [String]? | Whitelist of user IDs (empty = allow all) |
[llm]
| Key | Type | Description |
api_url | String | OpenAI-compatible API endpoint (e.g. the GPU server :30123) |
model | String? | Model name (default: "default") |
classifier_url / classifier_model | String? | Secondary endpoint for short latency-sensitive prompts (topic classifier, profile slicer). Defaults to api_url/model. |
system_prompt | String? | Inline base prompt (legacy). Overridden by workspace files. |
workspace_path | String? | Dir of prompt markdown (IDENTITY/SOUL/RULES/USER/TOOLS). Default ~/.config/muninn/workspace. |
max_tokens | u32? | Max response tokens (default: 2048) |
temperature | f64? | Sampling temperature (Qwen: 0.6, Gemma: 1.0) |
top_p | f64? | Nucleus sampling (default: 0.95) |
top_k | u32? | Top-k sampling (Qwen: 20, Gemma: 64) |
presence_penalty | f64? | Presence penalty for repetition control |
reasoning_budget | i32? | Per-request thinking budget (llama.cpp). 0 = off. |
enable_thinking | bool? | Thinking toggle (vLLM/Qwen chat_template_kwargs). |
log_tool_results | bool? | Include tool args/results in data/logs/ dumps (default false — privacy). |
replay_capture | bool? | Write replayable JSONL per session to data/logs/replay/, last 5 per channel (default true). |
LLM Model Notes
| Model | temp | top_k | reasoning | Notes |
| Qwen3.6 27B | 0.6 | 20 | off |
Thinking breaks tool calls (llama.cpp #20837). --jinja required. |
| Gemma 4 31B | 1.0 | 64 | on (budget 128) |
Google recommends thinking for tool accuracy. --jinja required. |
[memory]
| Key | Default | Description |
db_path | ./data/muninn.db | SQLite database path |
recent_messages | 10 | Messages in context window |
max_memories | 5 | Memories injected per query |
extraction_enabled | true | Background fact extraction |
consolidation_enabled | true | Background maintenance (episodes, decay, merge) |
consolidation_interval_secs | 1800 | Maintenance cycle interval (30 min) |
decay_half_life_days | 14.0 | Ebbinghaus decay half-life |
decay_threshold | 0.1 | Archive memories below this strength |
episode_window_minutes | 60 | Time window for grouping episodes |
ollama_url | None | Ollama API URL (enables embeddings) |
ollama_model | nomic-embed-text | Ollama embedding model |
skill_extraction_enabled | true | Distil successful sub-agent trajectories into skills |
skill_curator_enabled + skill_archive_unused_after_days / skill_archive_idle_after_days / skill_min_uses_for_quality_check / skill_min_success_rate | true / 30 / 90 / 5 / 0.3 | Skill janitor: archive unused/idle/low-success skills (v0.12) |
profile_enabled + profile_min_memories / profile_max_chars / profile_refresh_after_hours | true / 10 / 1500 / 24 | Per-user dialectic profile (Honcho-lite, v0.12) |
profile_slicer_enabled + profile_slice_max_chars | false / 400 | Query-aware profile slicing on the hot path (extra LLM call/turn) |
dream_enabled + dream_interval_hours / dream_max_messages | false / 24 / 120 | Opt-in nightly reflective consolidation pass (v24) |
peer_db_path | None | Read-only peer DB for shared-memory lookup (TUI surface) |
[tools]
| Key | Type | Description |
searxng_url | String? | SearXNG URL for web search tool |
search_max_results | usize? | Max search results (default: 5) |
shell_enabled | bool? | Enable shell tool (default: false — opt-in only) |
shell_timeout_secs | u64? | Shell command timeout (default: 30) |
shell_ssh_remote_allowlist | [String]? | Hosts the shell tool may SSH to (empty = all outbound denied) |
shell_sandbox_hosts | [String]? | SSH targets that skip safety gates (sandbox) |
calculate_enabled | bool? | Enable calculate tool (default: true) |
calculate_timeout_secs | u64? | Calculate timeout (default: 10) |
ha_url | String? | Home Assistant URL (enables weather, home, camera, music tools) |
ha_token | String? | HA long-lived access token |
ha_allowed_users | [String]? | Matrix IDs allowed HA tools (AND-ed with role gate; empty = all) |
music_assistant_config_entry_id | String? | HA Music Assistant entry id — enables library search + "play some music" |
music_default_player | String? | Fallback media_player when no player named and room has no audio_out |
comfy_url | String? | ComfyUI URL for image generation (enables imagine tool) |
voice_server_url | String? | Kai voice server URL (enables speak tool) |
stt_url / stt_token / stt_language | String? | STT endpoint (enables transcribe tool) |
sandbox_path | String? | Dev-tools sandbox dir (default: /tmp/muninn/sandbox) |
[[tools.mcp_servers]] | table[] | MCP servers — kind = "stdio" (command/args/env) or "http" (url/headers). Admin-gated. |
Page fetch is no longer a native tool — the removed web_fetch/firecrawl_url are replaced by the muninn-fetch HTTP MCP server.
[tools.email]
Enables the email tool (admin-only). Master enabled toggle plus one
[[tools.email.accounts]] block per mailbox. Defaults suit Mailcow: IMAP 993 implicit-TLS,
SMTP 587 STARTTLS. Credentials live in muninn.toml.local.
| Key | Type | Description |
enabled | bool? | Master toggle. Absent/false → tool not registered. |
[[tools.email.accounts]] | table[] | One per mailbox. Fields below. |
↳ id / name / default / enabled | String / String? / bool? / bool? | Selector the LLM names; label; default account; per-account toggle |
↳ imap_host / imap_port / imap_security | String / u16? / String? | IMAP host; port (993); ssl|starttls|none |
↳ smtp_host / smtp_port / smtp_security | String? / u16? / String? | Defaults to imap_host; port (587); starttls|ssl|none |
↳ user / password | String / String | Login for BOTH IMAP and SMTP |
↳ from_address / from_name / archive_folder / trash_folder | String? | From (defaults to user); display name; Archive; Trash |
[tools.calendar]
Enables the calendar tool + reminder worker (admin-only). One shared calendar; events
stored locally and best-effort mirrored to SOGo CalDAV. Recurring events supported.
| Key | Type | Description |
enabled | bool? | Master toggle (gates the tool AND the reminder worker). |
default_reminders | [String]? | Lead times when the user doesn't specify (default ["1 day", "1 hour"]). Each is "<N> minute|hour|day|week". |
[[tools.calendar.accounts]] | table[] | One per calendar. Fields below. |
↳ id / name / default / enabled | String / String? / bool? / bool? | Selector; label; default; per-account toggle |
↳ caldav_url / user / password | String | CalDAV collection URL (e.g. …/SOGo/dav/<user>/Calendar/personal/) + basic-auth creds |
[tools.contacts]
Enables the contacts tool (admin-only) — CardDAV name→email/phone lookup over a single
address book (e.g. SOGo's Personal Address Book; reuses the mailbox creds).
| Key | Type | Description |
enabled | bool? | Master toggle. Absent/false → tool not registered. |
carddav_url | String | CardDAV collection URL, e.g. …/SOGo/dav/<user>/Contacts/personal/ |
user / password | String | Basic-auth credentials (muninn.toml.local) |
[tools.youtube]
Enables the youtube tool (admin/adult) — transcript→summary via yt-dlp.
Requires the yt-dlp binary on the host.
| Key | Type | Description |
enabled | bool? | Master toggle. Absent/false → tool not registered. |
binary | String? | Path to yt-dlp (default: resolved via PATH). |
default_lang | String? | Preferred caption language (default en). |
[tools.research]
Enables the research tool (admin/adult) — deep plan→search→fetch→synthesize
into a cited brief, over the top-level [tools] searxng_url. Slow → run backgrounded (!bg).
| Key | Type | Description |
enabled | bool? | Master toggle. Absent/false → tool not registered. |
max_subquestions | usize? | Sub-questions the planner expands into (default 3, max 6). |
results_per_search | usize? | Results fetched per sub-question (default 4, max 10). |
max_page_chars | usize? | Per-page text cap fed to synthesis (default 4000). |
fetch_pages | bool? | Fetch + read result pages (default true); false = snippets only. |
[docs]
| Key | Default | Description |
port | 7790 | Port for the embedded docs web server |