# dockndevai/otto-assist architecture

> Architecture diagram of the GitHub repository dockndevai/otto-assist, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-11-14). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/dockndevai/otto-assist
- Repository: https://github.com/dockndevai/otto-assist

## Overview

Orrin is a macOS voice-and-dashboard interface around the user’s existing Claude Code setup. The main path is user input (wake word, Talk, or dashboard) → the always-on orchestrator → Claude → spoken response and live dashboard updates. Separate branches provide persistent memory, project/chat switching, timers, background research and opt-in autonomous work, MCP access, and a token-secured mobile remote. Relationships are grounded in the excerpts, SOURCE INDEX references, or README; some capabilities are documented but their detailed implementations were not sampled.

Main entry points: [`otto/orchestrator.py`](https://github.com/dockndevai/otto-assist/blob/main/otto/orchestrator.py) (Turn orchestrator), [`otto/server/app.py`](https://github.com/dockndevai/otto-assist/blob/main/otto/server/app.py) (Dashboard and API), [`otto/menubar.py`](https://github.com/dockndevai/otto-assist/blob/main/otto/menubar.py) (Menu bar app), [`otto/voice/native_ears.py`](https://github.com/dockndevai/otto-assist/blob/main/otto/voice/native_ears.py) (Native microphone)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_app["App and control"]
  node_menubar["Menu bar app<br/>[menubar.py]"]
  node_config["Settings<br/>[config.py]"]
  node_preflight["Readiness checks<br/>[preflight.py]"]
  node_orchestrator["Turn orchestrator<br/>[orchestrator.py]"]
end

subgraph group_voice["Voice interaction"]
  node_ears["Native microphone<br/>[native_ears.py]"]
  node_stt["Speech recognition<br/>[stt.py]"]
  node_speaker["Voice enrollment<br/>[speaker.py]"]
  node_tts["Speech output<br/>[tts.py]"]
end

subgraph group_assistant["Claude and context"]
  node_brain["Claude agent<br/>[agent.py]"]
  node_memory[("Persistent memory<br/>[memory.py]")]
  node_local_actions["Local actions<br/>[local_actions.py]"]
  node_projects["Project discovery<br/>[projects.py]"]
  node_sessions["Chat sessions<br/>[sessions.py]"]
end

subgraph group_background["Background services"]
  node_scheduler["Timers and reminders<br/>[scheduler.py]"]
  node_steward["Research and teammate<br/>[steward.py]"]
  node_store[("Conversation store<br/>[store.py]")]
end

subgraph group_interfaces["Remote and dashboard"]
  node_events["Event bus<br/>[events.py]"]
  node_server["Dashboard and API<br/>[app.py]"]
  node_dashboard["Dashboard UI<br/>[app.js]"]
  node_mcp["MCP interface<br/>[mcpserver.py]"]
  node_mobile["Mobile remote"]
end

node_user(("User"))

node_user -->|"starts and controls"| node_menubar
node_menubar -->|"starts"| node_orchestrator
node_menubar -->|"serves dashboard"| node_server
node_menubar -->|"loads settings"| node_config
node_menubar -->|"runs readiness checks"| node_preflight
node_orchestrator -->|"starts microphone"| node_ears
node_ears -->|"transcribes audio"| node_stt
node_orchestrator -->|"runs turns"| node_brain
node_brain -->|"reads and writes context"| node_memory
node_orchestrator -->|"speaks replies"| node_tts
node_orchestrator -.->|"checks enrolled voices"| node_speaker
node_orchestrator -->|"dispatches actions"| node_local_actions
node_orchestrator -->|"publishes turn events"| node_events
node_server -->|"routes user requests"| node_orchestrator
node_server -->|"streams events"| node_events
node_dashboard -.->|"uses dashboard API"| node_server
node_server -->|"switches projects"| node_projects
node_server -->|"supports chat switching"| node_sessions
node_orchestrator -->|"manages active project"| node_projects
node_orchestrator -->|"switches chats"| node_sessions
node_orchestrator -->|"runs scheduled reminders"| node_scheduler
node_orchestrator -.->|"coordinates background work"| node_steward
node_orchestrator -->|"persists conversation data"| node_store
node_server -->|"mounts MCP endpoint"| node_mcp
node_user -->|"checks in remotely"| node_mobile
node_mobile -.->|"connects over secure link"| node_server

click node_menubar "https://github.com/dockndevai/otto-assist/blob/main/otto/menubar.py"
click node_config "https://github.com/dockndevai/otto-assist/blob/main/otto/config.py"
click node_preflight "https://github.com/dockndevai/otto-assist/blob/main/otto/preflight.py"
click node_orchestrator "https://github.com/dockndevai/otto-assist/blob/main/otto/orchestrator.py"
click node_ears "https://github.com/dockndevai/otto-assist/blob/main/otto/voice/native_ears.py"
click node_stt "https://github.com/dockndevai/otto-assist/blob/main/otto/voice/stt.py"
click node_speaker "https://github.com/dockndevai/otto-assist/blob/main/otto/voice/speaker.py"
click node_tts "https://github.com/dockndevai/otto-assist/blob/main/otto/voice/tts.py"
click node_brain "https://github.com/dockndevai/otto-assist/blob/main/otto/brain/agent.py"
click node_memory "https://github.com/dockndevai/otto-assist/blob/main/otto/memory.py"
click node_local_actions "https://github.com/dockndevai/otto-assist/blob/main/otto/local_actions.py"
click node_projects "https://github.com/dockndevai/otto-assist/blob/main/otto/projects.py"
click node_sessions "https://github.com/dockndevai/otto-assist/blob/main/otto/sessions.py"
click node_scheduler "https://github.com/dockndevai/otto-assist/blob/main/otto/scheduler.py"
click node_steward "https://github.com/dockndevai/otto-assist/blob/main/otto/steward.py"
click node_store "https://github.com/dockndevai/otto-assist/blob/main/otto/store.py"
click node_events "https://github.com/dockndevai/otto-assist/blob/main/otto/server/events.py"
click node_server "https://github.com/dockndevai/otto-assist/blob/main/otto/server/app.py"
click node_dashboard "https://github.com/dockndevai/otto-assist/blob/main/otto/server/web/app.js"
click node_mcp "https://github.com/dockndevai/otto-assist/blob/main/otto/mcpserver.py"
click node_mobile "https://github.com/dockndevai/otto-assist/tree/main/mobile"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_menubar,node_config,node_preflight,node_orchestrator,node_user toneBlue
class node_ears,node_stt,node_speaker,node_tts toneAmber
class node_brain,node_memory,node_local_actions,node_projects,node_sessions toneMint
class node_scheduler,node_steward,node_store toneRose
class node_events,node_server,node_dashboard,node_mcp,node_mobile toneIndigo
```

## Components

### App and control

- [Menu bar app](https://github.com/dockndevai/otto-assist/blob/main/otto/menubar.py): `otto/menubar.py`
- [Settings](https://github.com/dockndevai/otto-assist/blob/main/otto/config.py): `otto/config.py`
- [Readiness checks](https://github.com/dockndevai/otto-assist/blob/main/otto/preflight.py): `otto/preflight.py`
- [Turn orchestrator](https://github.com/dockndevai/otto-assist/blob/main/otto/orchestrator.py): `otto/orchestrator.py`

### Voice interaction

- [Native microphone](https://github.com/dockndevai/otto-assist/blob/main/otto/voice/native_ears.py): `otto/voice/native_ears.py`
- [Speech recognition](https://github.com/dockndevai/otto-assist/blob/main/otto/voice/stt.py): `otto/voice/stt.py`
- [Voice enrollment](https://github.com/dockndevai/otto-assist/blob/main/otto/voice/speaker.py): `otto/voice/speaker.py`
- [Speech output](https://github.com/dockndevai/otto-assist/blob/main/otto/voice/tts.py): `otto/voice/tts.py`

### Claude and context

- [Claude agent](https://github.com/dockndevai/otto-assist/blob/main/otto/brain/agent.py): `otto/brain/agent.py`
- [Persistent memory](https://github.com/dockndevai/otto-assist/blob/main/otto/memory.py): `otto/memory.py`
- [Local actions](https://github.com/dockndevai/otto-assist/blob/main/otto/local_actions.py): `otto/local_actions.py`
- [Project discovery](https://github.com/dockndevai/otto-assist/blob/main/otto/projects.py): `otto/projects.py`
- [Chat sessions](https://github.com/dockndevai/otto-assist/blob/main/otto/sessions.py): `otto/sessions.py`

### Background services

- [Timers and reminders](https://github.com/dockndevai/otto-assist/blob/main/otto/scheduler.py): `otto/scheduler.py`
- [Research and teammate](https://github.com/dockndevai/otto-assist/blob/main/otto/steward.py): `otto/steward.py`
- [Conversation store](https://github.com/dockndevai/otto-assist/blob/main/otto/store.py): `otto/store.py`

### Remote and dashboard

- [Event bus](https://github.com/dockndevai/otto-assist/blob/main/otto/server/events.py): `otto/server/events.py`
- [Dashboard and API](https://github.com/dockndevai/otto-assist/blob/main/otto/server/app.py): `otto/server/app.py`
- [Dashboard UI](https://github.com/dockndevai/otto-assist/blob/main/otto/server/web/app.js): `otto/server/web/app.js`
- [MCP interface](https://github.com/dockndevai/otto-assist/blob/main/otto/mcpserver.py): `otto/mcpserver.py`
- [Mobile remote](https://github.com/dockndevai/otto-assist/tree/main/mobile): `mobile`

### Other components

- **User**

## Connections

- User → Menu bar app: starts and controls
- Menu bar app → Turn orchestrator: starts (evidence: `otto/menubar.py`)
- Menu bar app → Dashboard and API: serves dashboard (evidence: `otto/menubar.py`)
- Menu bar app → Settings: loads settings (evidence: `otto/menubar.py`)
- Menu bar app → Readiness checks: runs readiness checks (evidence: `otto/menubar.py`)
- Turn orchestrator → Native microphone: starts microphone (evidence: `otto/orchestrator.py`)
- Native microphone → Speech recognition: transcribes audio (evidence: `otto/voice/native_ears.py`)
- Turn orchestrator → Claude agent: runs turns (evidence: `otto/orchestrator.py`)
- Claude agent → Persistent memory: reads and writes context (evidence: `otto/brain/agent.py`)
- Turn orchestrator → Speech output: speaks replies (evidence: `otto/orchestrator.py`)
- Turn orchestrator → Voice enrollment: checks enrolled voices (evidence: `otto/orchestrator.py`)
- Turn orchestrator → Local actions: dispatches actions (evidence: `otto/local_actions.py`)
- Turn orchestrator → Event bus: publishes turn events (evidence: `otto/orchestrator.py`)
- Dashboard and API → Turn orchestrator: routes user requests (evidence: `otto/server/app.py`)
- Dashboard and API → Event bus: streams events (evidence: `otto/server/app.py`)
- Dashboard UI → Dashboard and API: uses dashboard API
- Dashboard and API → Project discovery: switches projects (evidence: `otto/server/app.py`)
- Dashboard and API → Chat sessions: supports chat switching (evidence: `otto/server/app.py`)
- Turn orchestrator → Project discovery: manages active project (evidence: `otto/orchestrator.py`)
- Turn orchestrator → Chat sessions: switches chats (evidence: `otto/orchestrator.py`)
- Turn orchestrator → Timers and reminders: runs scheduled reminders (evidence: `otto/orchestrator.py`)
- Turn orchestrator → Research and teammate: coordinates background work (evidence: `otto/orchestrator.py`)
- Turn orchestrator → Conversation store: persists conversation data (evidence: `otto/orchestrator.py`)
- Dashboard and API → MCP interface: mounts MCP endpoint (evidence: `otto/server/app.py`)
- User → Mobile remote: checks in remotely
- Mobile remote → Dashboard and API: connects over secure link
