Munin technical overview
Munin is a Flutter application for a private on-device assistant. The product is structured around local inference, durable local storage, optional web access, and explicit tool routing. The website documentation is generated from markdown files in website/content/docs.
Application shape
The Flutter app lives under munin/lib. It uses Riverpod for state management, GoRouter for navigation, SQLite for chat persistence, SharedPreferences for settings and small durable state, and local application documents folders for generated workspace artifacts and attached images.
The app has four primary layers:
- UI pages and widgets under
features/*/pagesandfeatures/*/widgets. - Feature controllers under
features/*/controller. - Core services under
core/services. - Native Android integration through platform channels and Android services.
Main capabilities
- Chat with an on-device Gemma model through
GemmaModelService. - Store conversations and messages in SQLite through
ChatDbandChatRepository. - Recall prior messages by embedding them into a local SQLite vector index through
MemoryService. - Maintain durable user facts in SharedPreferences through
MemoryProfileService. - Search the web only when enabled or routed as necessary through
WebSearchService. - Execute native device actions through
DeviceActions. - Load skills, custom
SKILL.mdfiles, and MCP server tools throughAgentService. - Run multi-step workspaces through
WorkspaceController,WorkspaceAgent, andWorkspaceStore. - Use voice mode through local recording, Whisper transcription, chat streaming, and text to speech.
Core design rules
- The assistant model runs locally.
- Chat history is not sent to a search provider.
- Web search sends only search query text.
- Memory embeddings and vector search run locally.
- Device actions are routed through platform APIs and should open system confirmation surfaces when a user must send or confirm content.
- MCP tools require explicit configuration and per-tool enablement.
- Workspace files are normal local files so outputs are inspectable.
Boot path
Startup begins in main.dart. The app configures edge-to-edge UI, initializes SharedPreferences, configures model download notifications, starts engine bootstrap in the background, creates AgentService, and runs MuninApp inside a ProviderScope.
MuninApp wires app-level listeners:
- Share intents are started through
shareIntentServiceProvider. - Memory is warmed after the first frame.
- The model performance profile is applied after device system information is read.
- The native assist channel can route to voice mode.
- The native workspace notification channel can open and run a scheduled workspace.
Routing
Routes are declared in core/router/routes.dart and bound in core/router/app_router.dart. The route table is explicit and uses fade transitions for each page. Startup gating is handled outside the router by the splash page and startup providers.
Key app routes:
/resolves through the splash screen./onboardingintroduces the product./downloadinstalls the local model bundle./chatis the primary assistant surface./settingsmanages defaults, memory, permissions, model fit, MCP, and skills./voiceopens hands-free conversation mode./workspacesmanages autonomous workspaces.
Where to read next
Start with the startup and model runtime pages if you need the lifecycle. Use the chat pipeline, memory, search, agent tools, and workspaces pages for behavior. Use storage and privacy for data boundaries.