# oAI-Web - Personal AI Agent A secure, self-hosted personal AI agent. Handles calendar, email, files, web research, and Telegram - controlled by you, running on your own hardware. ## Features - **Chat interface** - conversational UI via browser, with model selector - **CalDAV** - read and write calendar events (per-user credentials, configured in Settings) - **CardDAV / Contacts** - search and manage contacts from your CardDAV server - **Email** - read inbox, send replies (whitelist-managed recipients) - **Filesystem** - read/write files in your personal data folder - **Web access** - tiered: whitelisted domains always allowed, others on request - **Push notifications** - Pushover for iOS/Android (set your own User Key in Settings) - **Telegram** - send and receive messages via your own bot - **Webhooks** - trigger agents from external services (iOS Shortcuts, GitHub, Home Assistant, etc.) - **Monitors** - page-change and RSS feed monitors that dispatch agents automatically - **Scheduled tasks** - cron-based autonomous tasks with declared permission scopes - **Agents** - goal-oriented runs with model selection and full run history - **Audit log** - every tool call logged, append-only - **Multi-user** - each user has their own credentials and settings --- ## Requirements - Docker and Docker Compose - An API key from [Anthropic](https://console.anthropic.com) and/or [OpenRouter](https://openrouter.ai) and/or [OpenAI](https://openai.com) - A PostgreSQL-compatible host (included in the compose file) --- ## Installation ### 1. Get the files Download or copy these files into a directory on your server: - `docker-compose.example.yml` - rename to `docker-compose.yml` - `.env.example` - rename to `.env` - `SOUL.md.example` - rename to `SOUL.md` - `USER.md.example` - rename to `USER.md` ```bash cp docker-compose.example.yml docker-compose.yml cp .env.example .env cp SOUL.md.example SOUL.md cp USER.md.example USER.md ``` ### 2. Create the data directory ```bash mkdir -p data ``` ### 3. Configure the environment Edit `.env` - see the [Environment Variables](#environment-variables) section below. ### 4. Pull and start ```bash docker compose pull docker compose up -d ``` Open `http://:8080` in your browser. On first run you will be taken through a short setup wizard to create your admin account. --- ## Environment Variables Open `.env` and fill in the values. Required fields are marked with `*`. ### AI Provider ```env # Which provider to use as default: anthropic | openrouter | openai DEFAULT_PROVIDER=anthropic # Override the default model (leave empty to use the provider's default) # DEFAULT_MODEL=claude-sonnet-4-6 # Model pre-selected in the chat UI (leave empty to use provider default) # DEFAULT_CHAT_MODEL=claude-sonnet-4-6 ``` Your actual API keys are **not** set here - they are entered via the web UI under **Settings - Credentials** and stored encrypted in the database. --- ### Security * ```env # Master password for the encrypted credential store. # All your API keys, passwords, and secrets are encrypted with this. # Choose a strong passphrase and keep it safe - if lost, credentials cannot be recovered. DB_MASTER_PASSWORD=change-me-to-a-strong-passphrase ``` --- ### Server ```env # Port the web interface listens on (default: 8080) PORT=8080 # Timezone for display - dates are stored internally as UTC TIMEZONE=Europe/Oslo ``` --- ### Agent Limits ```env # Maximum number of tool calls per agent run MAX_TOOL_CALLS=20 # Maximum number of autonomous (scheduled/agent) runs per hour MAX_AUTONOMOUS_RUNS_PER_HOUR=10 ``` Both values can also be changed live from **Settings - General** without restarting. --- ### Database * ```env # Main application database AIDE_DB_URL=postgresql://aide:change-me@postgres:5432/aide # 2nd Brain database password (pgvector) BRAIN_DB_PASSWORD=change-me-to-a-strong-passphrase # Brain connection string - defaults to the bundled postgres service BRAIN_DB_URL=postgresql://brain:${BRAIN_DB_PASSWORD}@postgres:5432/brain # Access key for the Brain MCP endpoint (generate with: openssl rand -hex 32) BRAIN_MCP_KEY= ``` Change the `change-me` passwords in `AIDE_DB_URL` and `BRAIN_DB_PASSWORD` to something strong. They must match - if you change `BRAIN_DB_PASSWORD`, the same value is substituted into `BRAIN_DB_URL` automatically. --- ## Personalising the Agent ### SOUL.md - Agent identity and personality `SOUL.md` defines who your agent is. The name is extracted automatically from the first line matching `You are **Name**`. Key sections to edit: **Name** - change `Jarvis` to whatever you want your agent to be called: ```markdown You are **Jarvis**, a personal AI assistant... ``` **Character** - describe how you want the agent to behave. Be specific. Examples: - "You are concise and avoid unnecessary commentary." - "You are proactive - if you notice something relevant while completing a task, mention it briefly." - "You never use bullet points unless explicitly asked." **Values** - define what the agent should prioritise: - Privacy, minimal footprint, and transparency are good defaults. - Add domain-specific values if relevant (e.g. "always prefer open-source tools when suggesting options"). **Language** - specify language behaviour explicitly: - "Always respond in the same language the user wrote in." - "Default to Norwegian unless the message is in another language." **Communication style** - tune the tone: - Formal vs. casual, verbose vs. terse, proactive vs. reactive. - You can ban specific phrases: "Never start a response with 'Certainly!' or 'Of course!'." The file is mounted read-only into the container. Changes take effect on the next `docker compose restart`. --- ### USER.md - Context about you `USER.md` gives the agent background knowledge about you. It is injected into every system prompt, so keep it factual and relevant - not a biography. **Identity** - name, location, timezone. These help the agent interpret time references and address you correctly. ```markdown ## Identity - **Name**: Jane - **Location**: Oslo, Norway - **Timezone**: Europe/Oslo ``` **Language preferences** - if you want to override SOUL.md language rules for your specific case: ```markdown ## Language - Respond in the exact language the user's message is written in. - Do not assume Norwegian because of my location. ``` **Professional context** - role and responsibilities the agent should be aware of: ```markdown ## Context and background - Works as a software architect - Primarily works with Python and Kubernetes - Manages a small team of three developers ``` **People** - names and relationships. Helps the agent interpret messages like "send this to my manager": ```markdown ## People - [Alice Smith] - Manager - [Bob Jones] - Colleague, backend team - [Sara Lee] - Partner ``` **Recurring tasks and routines** - anything time-sensitive the agent should know about: ```markdown ## Recurring tasks and routines - Weekly team standup every Monday at 09:00 - Monthly report due on the last Friday of each month ``` **Hobbies and interests** - optional, but helps the agent contextualise requests: ```markdown ## Hobbies and Interests - Photography - Self-hosting and home lab - Cycling in summer ``` The file is mounted read-only into the container. Changes take effect on the next `docker compose restart`. --- ## Your Settings After logging in, go to **Settings** to configure your personal services. Each user has their own credentials — nothing is shared with other users. ### CalDAV / CardDAV Set up your personal calendar and contacts server under **Settings → CalDAV / CardDAV**: - Enter your server URL (e.g. `mail.example.com`), username, and password - Optionally specify a calendar name (leave blank for the default calendar) - For CardDAV (contacts): tick *Same server as CalDAV* to reuse your credentials, or enter separate details - Use the **Test** buttons to verify your connection before saving - Enable **Allow contact writes** if you want agents to be able to create and update contacts There is no system-wide fallback — if you don't configure it, calendar and contacts tools won't be available to your agents. ### Pushover To receive push notifications on your iOS or Android device: 1. Create a free account at [pushover.net](https://pushover.net) 2. Copy your **User Key** from the dashboard 3. Go to **Settings → Pushover** and save your User Key The app is already registered by your admin — you only need your own User Key. ### Webhooks Create inbound webhooks under **Settings → Webhooks** to trigger your agents from external services: - Assign a name and target agent, then copy the secret token shown at creation (it's shown only once) - **POST trigger**: send `{"message": "your message"}` to `/webhook/{token}` - **GET trigger**: visit `/webhook/{token}?q=your+message` — ideal for iOS Shortcuts URL actions - Enable or disable webhooks without deleting them ### Telegram Set your personal bot token under **Settings → Telegram** (or **Settings → Profile → Telegram Bot Token**) if you want your own Telegram bot. Your chat ID must be whitelisted by the admin before messages are processed. ### Email Accounts Set up your own email accounts under **Settings → Email Accounts**: - **Trigger account** — dispatches agents based on keyword rules in incoming emails - **Handling account** — a dedicated AI agent reads and handles each incoming email --- ## Updating ```bash docker compose pull docker compose up -d ``` --- ## Pages | URL | Description | |-----|-------------| | `/` | Chat - send messages, select model, view tool activity | | `/tasks` | Scheduled tasks - cron-based autonomous tasks | | `/agents` | Agents - goal-oriented runs with model selection and run history | | `/monitors` | Monitors - page-change watchers and RSS feed monitors | | `/files` | Files - browse, download, and manage your personal data folder | | `/audit` | Audit log - filterable view of every tool call | | `/settings` | Your personal settings: CalDAV, CardDAV, Pushover, Webhooks, Telegram, Email Accounts, and more | --- ## License oAI is free software licensed under the **GNU Affero General Public License v3.0 (AGPL-3.0)**. This means you are free to use, study, modify, and distribute oAI, but any modified version you run as a network service must also be made available as free software under the same license. See [LICENSE](LICENSE) for the full license text, or visit [gnu.org/licenses/agpl-3.0](https://www.gnu.org/licenses/agpl-3.0.html). ## Author **Rune Olsen** - Website: https://jarvis.pm - Blog: [https://blog.rune.pm](https://blog.rune.pm) - Gitlab.pm: [@rune](https://gitlab.pm/rune) ## Contributing Contributions are welcome! --- **⭐ Star this project if you find it useful!** **🐛 Found a bug?** [Open an issue](https://gitlab.pm/rune/oai-web/issues/new)