{% extends "base.html" %} {% block title %}{{ agent_name }} - Help{% endblock %} {% block content %}
oAI-Web (agent name: {{ agent_name }}) is a secure, self-hosted personal AI agent built on the Claude API with full tool-use support. It runs on your home server and exposes a clean web interface for use inside your local network. The agent can read email, browse the web, manage calendar events, read and write files, send push notifications, generate images, and more — all via a structured tool-use loop with optional confirmation prompts before side-effects.
.env.example to .env and set ANTHROPIC_API_KEY (or OPENROUTER_API_KEY), AIDE_DB_URL (PostgreSQL connection string), and DB_MASTER_PASSWORDpython -m uvicorn server.main:app --host 0.0.0.0 --port 8080 --reload/setup to create the first admin accountsystem:users_base_folder in Credentials to enable per-user file storage (e.g. /data/users)system:users_base_folder is set, each user gets a personal folder at {base}/{username}/. Agents and the Files page scope all file access to this folder automatically.Navigate to the Chat page, type a message and press Enter. The agent responds, uses tools as needed (you'll see spinning indicators), and may ask for confirmation before sending email or writing files.
Press Enter to send. Use Shift+Enter for a newline within your message. The Clear History button (✕) in the status bar wipes the in-memory conversation for the current session — the agent starts fresh.
The paperclip button (📎) in the input bar opens a file picker. Only shown when the active model supports vision or documents. Supported formats:
You can also paste images directly from the clipboard (Ctrl/Cmd+V in the chat input). Multiple files can be attached in one message. Remove any attachment by clicking the ✕ on its preview chip.
Attachments are sent inline with the message as base64-encoded data. Large files (especially PDFs) will increase the token count and cost of the request.
The button in the status bar (bottom of the chat area) shows the currently active model. Click it to open a searchable modal listing all available models from all configured providers. Use arrow keys to navigate, Enter to select, Esc to close. Your selection is persisted in localStorage across page loads.
Small badges in the status bar show what the active model supports:
image_gen tool in agents)While the agent is working, small badges appear below each message:
When the agent wants to execute a side-effect tool (send email, write/delete a file, send a push notification), a yellow modal appears showing the tool name and arguments. Click Approve to proceed or Deny to block the action. The agent receives your decision and continues.
The Pause button in the sidebar is a global kill switch. While paused, no agent runs, scheduled tasks, inbox processing, or Telegram responses will execute. The button turns green and shows Resume when paused. Click it again to re-enable everything.
The Files page is a browser for your personal data folder (provisioned automatically when system:users_base_folder is configured by your admin). It lets you navigate, download, and delete files directly from the web UI.
.) are not shown.A red Delete button appears next to downloadable files. Clicking it shows a confirmation dialog before the file is permanently removed. Deletion is instant and cannot be undone.
Protected files: files whose names start with memory_ or reasoning_ cannot be deleted from the UI. These are agent memory and decision logs maintained by email handling agents — deleting them would disrupt the agent's continuity.
If the Files page shows "No files folder configured", ask your administrator to set the system:users_base_folder credential to a base path (e.g. /data/users). Your personal folder at {base}/{username}/ is created automatically.
Agents are headless AI personas with a fixed system prompt, model, and optional cron schedule. Unlike interactive chat, agents run without confirmation modals — their allowed tools are declared at creation time. Results and token usage are logged per-run in the Agents page.
Email handling agents (created automatically by Email Accounts setup) are hidden from the Agents list and Status tab. They are managed exclusively via Settings → Email Accounts.
Click New Agent on the Agents page. Required fields:
Optional fields:
Enter a cron expression in the Schedule field. The format is:
minute hour day-of-month month day-of-week
Examples:
0 8 * * 1-5 — weekdays at 08:00*/15 * * * * — every 15 minutes0 9 * * 1 — every Monday at 09:0030 18 * * * — every day at 18:30Use the Enable / Disable toggle to pause a schedule without deleting the agent. The Run Now button triggers an immediate run regardless of schedule.
Three modes control how the agent prompt is combined with the standard system prompt (SOUL.md + security rules):
Leave Allowed Tools blank to give the agent access to all tools. Select specific tools to restrict — only those tool schemas are sent to the model, making it structurally impossible to use undeclared tools.
MCP server tools appear as a single server-level toggle (e.g. Gitea MCP), which enables all tools from that server. Individual built-in tools are listed separately.
Follow the least-privilege principle: give each agent only the tools it actually needs.
Enable the Sub-agents toggle to give an agent access to the create_subagent tool. This allows the agent to spin up child agents to handle parallel or specialized tasks. Sub-agents run synchronously (the parent waits for the child to finish) and are logged separately in run history with parent_agent_id set.
Agents can generate images using the image_gen tool. Important: the agent model must be a text/tool-use model (e.g. Claude Sonnet), not an image-generation model. The image_gen tool calls the image-gen model internally, saves the result to disk, and returns the file path. The default image-gen model is openrouter:openai/gpt-5-image — override via the system:default_image_gen_model credential.
Generated images are saved to the agent's user folder. The file path is returned as the tool result so the agent can reference it.
MCP (Model Context Protocol) is an open protocol for exposing tools to AI models over a network. oAI-Web can connect to external MCP servers and use their tools exactly like built-in tools. Tool names are namespaced as mcp__{server}__{tool}.
To be compatible with oAI-Web, an MCP server must:
/ssemcp==1.26.*uvicorn.run(mcp.sse_app(), host=..., port=...) — not mcp.run(host=..., port=...) (the latter ignores host/port in mcp 1.26)192.168.x.x): disable DNS rebinding protection:
from mcp.server.transport_security import TransportSecuritySettings
mcp = FastMCP(
"my-server",
transport_security=TransportSecuritySettings(
enable_dns_rebinding_protection=False
),
)
Without this, the server rejects requests with a 421 Misdirected Request error.
http://192.168.1.72:8812/ssesseoAI-Web will immediately attempt to connect and discover tools. The tool count is shown in the server list.
A server named Gitea MCP (slugified: gitea_mcp) exposes tools as mcp__gitea_mcp__list_repos, mcp__gitea_mcp__create_issue, etc.
In the agent tool picker, the entire server appears as a single toggle — enabling it grants access to all of its tools.
Click Refresh on any server in Settings → MCP Servers to re-discover tools without restarting oAI-Web. Useful after adding new tools to an MCP server.
X-Forwarded-For trust (requires restart)system:users_base_folder to an absolute path (e.g. /data/users) to enable per-user file storage. Each user's folder at {base}/{username}/ is created automatically.wikipedia.org covers en.wikipedia.org).
A generic AES-256-GCM encrypted key-value store for API keys and other secrets. Keys use a namespace:key convention. Service-specific credentials (CalDAV, CardDAV, Pushover) are managed in their own dedicated tabs — they do not appear here. See the Credential Key Reference for a full list of system keys.
Configure CalDAV and CardDAV for the admin user. There is no system-wide fallback — every user configures their own credentials independently via this tab (admin) or the CalDAV / CardDAV tab (regular users).
mail.example.com) are accepted — https:// is prepended automatically./SOGo/dav/{user}/Contacts/personal/) is built automatically.Pushover sends push notifications to iOS and Android devices.
The Inbox tab manages trigger rules for the legacy global IMAP/SMTP account. For per-user or multi-account email handling, use the Email Accounts tab instead.
Email Accounts is the main email management area, separate from the legacy Inbox tab. Each account is independently configured with its own IMAP/SMTP credentials and an account type:
For handling accounts, you can also configure:
work) that creates a /work Telegram command. Send /work <message> to interact with the email agent via Telegram. Built-in sub-commands: /work pause, /work resume, /work status/keyword pause command
The handling agent uses memory files (memory_<username>.md) and reasoning logs (reasoning_<username>.md) stored in the user's data folder to maintain continuity across email sessions. These files are visible in the Files page but cannot be deleted there.
Configure your personal CalDAV and CardDAV connection. There is no system-wide fallback — if you don't configure it, the tools are unavailable to you.
https:// is added automatically.Set your personal User Key to receive push notifications on your Pushover-connected devices. Your User Key is shown on your pushover.net dashboard. The App Token (the shared application credential) is managed by the admin — you only need your own User Key.
{% endif %}Inbound webhooks let external services trigger agents via HTTP — useful for iOS Shortcuts, GitHub actions, Home Assistant automations, or any tool that can send an HTTP request.
POST /webhook/{token} with body {"message": "..."}GET /webhook/{token}?q=your+message — useful for iOS Shortcuts URL actionsThe Outbound Targets section (same tab) manages named URLs that agents can send JSON payloads to via the webhook tool.
Available to all users. Contains:
system:users_base_folder). This folder is where the Files page browses and where agent memory files are stored.Edit SOUL.md (agent identity, values, communication style) and USER.md (owner context: name, location, preferences) directly in the browser. Changes take effect immediately — no restart required. Both files are injected into every system prompt in order: SOUL.md → date/time → USER.md → security rules.
Requires PostgreSQL + pgvector (BRAIN_DB_URL env var). When connected, shows connection status, recent captured thoughts, and a manual capture form. The brain MCP server is exposed at /brain-mcp/sse and requires the brain:mcp_key credential for authentication.
Add, edit, remove, enable/disable, and refresh external MCP servers. See the MCP Servers section for full setup details.
{% if current_user and current_user.is_admin %}Five independently toggleable security options:
See the Security Model section for the broader security architecture.
Customize the sidebar brand name (default: {{ agent_name }}) and logo (default: logo.png). Upload a PNG/JPG/GIF/WebP/SVG logo (max 2 MB). Changes take effect immediately. Reset to defaults by clearing the name field or deleting the logo.
Protects the REST API for external programmatic access (scripts, home automations, other services, Swagger). The web UI always works without a key — a signed session cookie is set automatically on login. The API key is only required for:
/api/* directlyThe raw key is shown once at generation time — copy it to your external tool. Only a SHA-256 hash is stored server-side. Regenerating invalidates the previous key immediately.
Use header X-API-Key: <key> or Authorization: Bearer <key> in external requests.
If no key is configured, the API is open (home-network default).
oAI-Web supports multiple users with role-based access. Manage users at Admin → Users.
system:users_base_folder is configured, a personal folder is created automatically at {base}/{username}/Users set up their own TOTP in Settings → Profile → Two-Factor Authentication. As admin, you can clear any user's MFA from the Users page (useful if they lose their authenticator). The Clear MFA button resets their TOTP secret — they must set it up again on next login.
Non-admin users' agents automatically receive a scoped filesystem tool limited to their personal folder ({base}/{username}/). They cannot access paths outside their folder, even if those paths are in the global filesystem whitelist. Admin agents continue to use the global whitelist-based sandbox.
All keys are stored in the encrypted credential store. System keys use the system: prefix.
| Key | Description |
|---|---|
system:paused | Kill switch — set to "1" to pause all agent activity |
system:max_tool_calls | Live override of MAX_TOOL_CALLS env var |
system:max_autonomous_runs_per_hour | Live override of MAX_AUTONOMOUS_RUNS_PER_HOUR |
system:audit_retention_days | Days to keep audit entries (0 = keep forever) |
system:trusted_proxy_ips | Comma-separated IPs for X-Forwarded-For trust (requires restart) |
system:users_base_folder | Base path for per-user folders (e.g. /data/users). Each user's folder is created at {base}/{username}/. |
system:default_image_gen_model | Model used by the image_gen tool (default: openrouter:openai/gpt-5-image) |
system:brand_name | Custom sidebar brand name |
system:brand_logo_filename | Custom sidebar logo filename in /static/ |
system:security_sanitize_enhanced | Option 1: enhanced injection pattern sanitization |
system:security_canary_enabled | Option 2: canary token detection enabled |
system:canary_token | Auto-generated daily canary token (read-only) |
system:canary_rotated_at | Timestamp of last canary rotation (read-only) |
system:security_llm_screen_enabled | Option 3: LLM content screening enabled |
system:security_llm_screen_model | Model for LLM screening (default: google/gemini-flash-1.5) |
system:security_llm_screen_block | Option 3 block mode — block vs flag on UNSAFE verdict |
system:security_output_validation_enabled | Option 4: output validation for inbox sessions |
system:security_truncation_enabled | Option 5: content truncation |
system:security_max_web_chars | Max chars from web fetch (default: 20 000) |
system:security_max_email_chars | Max chars from email body (default: 6 000) |
system:security_max_file_chars | Max chars from file read (default: 20 000) |
system:security_max_subject_chars | Max chars of email subject (default: 200) |
telegram:bot_token | Global Telegram bot API token |
telegram:default_agent_id | UUID of agent for unmatched Telegram messages |
pushover_app_token | Pushover App Token — managed via Settings → Pushover, not this tab |
brain:mcp_key | 2nd Brain MCP authentication key |
system:api_key_hash | SHA-256 hash of the external API key (raw key never stored) |
system:api_key_created_at | Timestamp of last API key generation |
system:session_secret | HMAC secret for signing web UI session cookies (auto-generated) |
All endpoints are prefixed with /api. Responses are JSON.
If an API key is configured (Settings → General → API Key), external requests must include
X-API-Key: <key>. The web UI is exempt via session cookie.
API Explorer: Browse and test endpoints interactively via Swagger UI at
/docs or ReDoc at
/redoc.
Click Authorize in Swagger and enter your API key to make authenticated calls.
| Method | Path | Description |
|---|---|---|
| GET | /api/credentials | List all credential keys (values not returned) |
| POST | /api/credentials | Set a credential {key, value, description} |
| GET | /api/credentials/{key} | Get a single credential value |
| DELETE | /api/credentials/{key} | Delete a credential |
| Method | Path | Description |
|---|---|---|
| GET | /api/audit | Paginated audit log; params: start, end, tool, session_id, task_id, confirmed, page, page_size |
| DELETE | /api/audit | Delete audit entries older than ?older_than_days=N (0 = all) |
| Method | Path | Description |
|---|---|---|
| GET | /api/settings/api-key | Returns {configured: bool, created_at} — never returns the raw key |
| POST | /api/settings/api-key | Generate a new key — returns {key} once only; invalidates previous key |
| DELETE | /api/settings/api-key | Revoke the current key |
| Method | Path | Description |
|---|---|---|
| GET | /api/settings/limits | Current runtime limits |
| POST | /api/settings/limits | Update {max_tool_calls, max_autonomous_runs_per_hour} |
| GET | /api/settings/security | Current security option states |
| POST | /api/settings/security | Update security options |
| GET | /api/settings/branding | Current brand name and logo URL |
| POST | /api/settings/branding | Update {brand_name} |
| POST | /api/settings/branding/logo/upload | Upload a logo file (multipart) |
| DELETE | /api/settings/branding/logo | Reset logo to default |
| GET | /api/settings/audit-retention | Current audit retention setting |
| POST | /api/settings/audit-retention | Update {days} |
| GET | /api/settings/caldav | Admin CalDAV & CardDAV config (same as /api/my/caldav/config) |
| POST | /api/settings/caldav | Save admin CalDAV & CardDAV config |
| GET | /api/settings/pushover | Current Pushover App Token and admin User Key |
| POST | /api/settings/pushover | Save App Token and admin User Key |
| Method | Path | Description |
|---|---|---|
| GET | /api/email-whitelist | List whitelisted email recipients |
| POST | /api/email-whitelist | Add/update {email, daily_limit} |
| DELETE | /api/email-whitelist/{email} | Remove a recipient |
| GET | /api/web-whitelist | List Tier-1 web domains |
| POST | /api/web-whitelist | Add {domain, note} |
| DELETE | /api/web-whitelist/{domain} | Remove a domain |
| GET | /api/filesystem-whitelist | List sandbox directories |
| POST | /api/filesystem-whitelist | Add {path, note} |
| DELETE | /api/filesystem-whitelist/{path} | Remove a directory |
| GET | /api/filesystem-browser | Server-side directory listing; param: ?path= |
| Method | Path | Description |
|---|---|---|
| GET | /api/agents | List agents (excludes email handling agents) |
| POST | /api/agents | Create an agent |
| GET | /api/agents/{id} | Get agent details |
| PUT | /api/agents/{id} | Update agent |
| DELETE | /api/agents/{id} | Delete agent |
| POST | /api/agents/{id}/run | Trigger immediate run |
| POST | /api/agents/{id}/toggle | Enable / disable schedule |
| GET | /api/agents/{id}/runs | List runs for an agent |
| GET | /api/agent-runs | List recent runs across all agents (excludes email handlers) |
| GET | /api/agent-runs/{run_id} | Get a specific run including full result text |
| POST | /api/runs/{run_id}/stop | Stop a running agent |
| Method | Path | Description |
|---|---|---|
| GET | /api/models | Available model IDs + default |
| GET | /api/models/info | Full model metadata: name, context, pricing, capabilities |
| Method | Path | Description |
|---|---|---|
| GET | /api/mcp-servers | List all MCP servers |
| POST | /api/mcp-servers | Add a server |
| PUT | /api/mcp-servers/{id} | Update a server |
| DELETE | /api/mcp-servers/{id} | Remove a server |
| POST | /api/mcp-servers/{id}/toggle | Enable / disable a server |
| POST | /api/mcp-servers/{id}/refresh | Re-discover tools |
| Method | Path | Description |
|---|---|---|
| GET | /api/telegram/config | Global Telegram bot config |
| POST | /api/telegram/config | Save bot token + default agent |
| GET | /api/telegram/whitelist | Chat ID whitelist |
| POST | /api/telegram/whitelist | Add chat ID |
| DELETE | /api/telegram/whitelist/{chat_id} | Remove chat ID |
| GET | /api/telegram/triggers | List trigger rules |
| POST | /api/telegram/triggers | Create trigger rule |
| DELETE | /api/telegram/triggers/{id} | Delete trigger rule |
| GET | /api/inbox/config | Legacy IMAP/SMTP configuration |
| POST | /api/inbox/config | Save legacy IMAP/SMTP credentials |
| GET | /api/inbox/triggers | List email trigger rules |
| POST | /api/inbox/triggers | Create email trigger rule |
| DELETE | /api/inbox/triggers/{id} | Delete email trigger rule |
| GET | /api/inbox/status | Status of all inbox listeners |
| Method | Path | Description |
|---|---|---|
| GET | /api/my/email-accounts | List user's email accounts |
| POST | /api/my/email-accounts | Create an email account |
| PUT | /api/my/email-accounts/{id} | Update email account |
| DELETE | /api/my/email-accounts/{id} | Delete email account |
| POST | /api/my/email-accounts/{id}/pause | Pause a handling account |
| POST | /api/my/email-accounts/{id}/resume | Resume a paused handling account |
| POST | /api/my/email-accounts/list-folders-preview | List IMAP folders using raw credentials (without saving an account) |
| GET | /api/my/email-accounts/available-extra-tools | Which notification tools are available for handling accounts |
| Method | Path | Description |
|---|---|---|
| GET | /api/my/files | List files/folders in the user's data folder; param: ?path= |
| DELETE | /api/my/files | Delete a file; param: ?path=. Protected names (memory_*, reasoning_*) return 403. |
| GET | /api/my/files/download | Download a single file; param: ?path= |
| GET | /api/my/files/download-zip | Download a folder as ZIP; param: ?path= |
| GET | /api/my/data-folder | Return the user's provisioned data folder path |
| Method | Path | Description |
|---|---|---|
| GET | /api/my/profile | Get display name |
| POST | /api/my/profile | Update display name |
| GET | /api/my/theme | Get current theme |
| POST | /api/my/theme | Set theme {theme_id} |
| GET | /api/my/mfa/status | Whether MFA is enabled for the current user |
| POST | /api/my/mfa/setup/begin | Start MFA setup — returns QR code PNG (base64) and provisioning URI |
| POST | /api/my/mfa/setup/confirm | Confirm setup with a valid TOTP code {code} |
| DELETE | /api/my/mfa/disable | Disable MFA for the current user |
| GET | /api/my/caldav/config | Get per-user CalDAV & CardDAV config |
| POST | /api/my/caldav/config | Save per-user CalDAV & CardDAV credentials |
| DELETE | /api/my/caldav/config | Remove per-user CalDAV & CardDAV config |
| POST | /api/my/caldav/test | Test CalDAV connectivity with current saved config |
| POST | /api/my/caldav/test-carddav | Test CardDAV connectivity with current saved config |
| GET | /api/my/pushover | Get current user's Pushover User Key (masked) |
| POST | /api/my/pushover | Save personal User Key {user_key} |
| DELETE | /api/my/pushover | Remove personal User Key |
| GET | /api/my/telegram/whitelisted-chats | List Telegram chat IDs whitelisted for the current user |
| Method | Path | Description |
|---|---|---|
| GET | /api/webhooks | List inbound webhook endpoints (admin) |
| POST | /api/webhooks | Create endpoint — returns token once (admin) |
| PUT | /api/webhooks/{id} | Update name/description/agent/enabled (admin) |
| DELETE | /api/webhooks/{id} | Delete endpoint (admin) |
| POST | /api/webhooks/{id}/rotate | Regenerate token — returns new token once (admin) |
| GET | /api/my/webhooks | List current user's webhook endpoints |
| POST | /api/my/webhooks | Create personal webhook endpoint |
| PUT | /api/my/webhooks/{id} | Update personal webhook endpoint |
| DELETE | /api/my/webhooks/{id} | Delete personal webhook endpoint |
| GET | /webhook/{token} | Trigger via GET — param: ?q=message (no auth) |
| POST | /webhook/{token} | Trigger via POST — body: {"message": "...", "async": true} (no auth) |
| GET | /api/webhook-targets | List outbound webhook targets (admin) |
| POST | /api/webhook-targets | Create outbound target (admin) |
| PUT | /api/webhook-targets/{id} | Update outbound target (admin) |
| DELETE | /api/webhook-targets/{id} | Delete outbound target (admin) |
| Method | Path | Description |
|---|---|---|
| GET | /api/watched-pages | List page-change monitors |
| POST | /api/watched-pages | Create page monitor |
| PUT | /api/watched-pages/{id} | Update page monitor |
| DELETE | /api/watched-pages/{id} | Delete page monitor |
| POST | /api/watched-pages/{id}/check-now | Force an immediate check |
| GET | /api/rss-feeds | List RSS feed monitors |
| POST | /api/rss-feeds | Create RSS feed monitor |
| PUT | /api/rss-feeds/{id} | Update RSS feed monitor |
| DELETE | /api/rss-feeds/{id} | Delete RSS feed monitor |
| POST | /api/rss-feeds/{id}/fetch-now | Force an immediate fetch |
| Method | Path | Description |
|---|---|---|
| GET | /api/users | List all users |
| POST | /api/users | Create a user {username, email, password, role} |
| PUT | /api/users/{id} | Update user (role, active status, etc.) |
| DELETE | /api/users/{id} | Delete a user |
| DELETE | /api/users/{id}/mfa | Clear a user's MFA secret (admin reset) |
| Method | Path | Description |
|---|---|---|
| GET | /api/system-prompt/soul | Read SOUL.md content |
| POST | /api/system-prompt/soul | Save SOUL.md content |
| GET | /api/system-prompt/user | Read USER.md content |
| POST | /api/system-prompt/user | Save USER.md content |
| GET | /api/tools | List all registered tools with schemas |
| POST | /api/pause | Pause all agent activity |
| POST | /api/resume | Resume agent activity |
| GET | /api/status | Pause state + pending confirmations |
| GET | /health | Health check |
External input is data, never instructions. Email body text, calendar content, web page content, and file contents are all passed as tool results — they are never injected into the system prompt where they could alter {{ agent_name }}'s instructions.
Tier 2 web access (any URL) is only available in user-initiated chat sessions, never in autonomous agent runs.
Non-admin users' agents use a scoped filesystem tool restricted to their personal folder ({base}/{username}/). This is enforced at the tool level regardless of what the agent prompt says. Admin agents use the global whitelist-based sandbox as before.
In interactive chat, any tool with side effects (send email, write/delete files, send notifications, create/delete calendar events) triggers a confirmation modal. The agent pauses until you approve or deny. Agents running headlessly skip confirmations — their scope is declared at creation time.
Every tool call — arguments, result summary, confirmation status, session ID, task ID — is written to an append-only audit log. Logs are never auto-deleted unless you configure a retention period. View them at Audit Log.
The Pause button in the sidebar immediately halts all agent activity: no new runs, no inbox processing, no Telegram responses. The system:paused credential stores the state and is checked before every operation. Individual email handling accounts can also be paused independently via their Telegram keyword command or the Email Accounts UI.
API keys, passwords, and tokens are only accessed by the server-side tool implementations. The agent itself never sees a raw credential — it only receives structured results (e.g. a list of calendar events, a fetched page).
oAI-Web connects to Telegram via long-polling (no webhook required). Admin setup:
Non-admin users can also set their own Telegram bot token under Settings → Profile → Telegram Bot Token. This creates a personal bot that routes to agents and email accounts scoped to that user.
Each chat maintains its own conversation history (session ID: telegram:{chat_id}), persisted in memory and reset on server restart.
When an email handling account has a Telegram keyword set (e.g. work), Telegram messages starting with /work are routed directly to that email account's agent. This allows you to interact with the email agent via Telegram without any trigger rules.
Built-in sub-commands (e.g. for keyword work):
/work pause — temporarily pause the email account's listener/work resume — resume the listener/work status — show the account's current status/work <any message> — pass the message to the handling agentOnly the Telegram chat ID associated with the email account can use its keyword commands. Other chat IDs are rejected.
Trigger accounts use IMAP IDLE for instant push notification. When a new email arrives:
Sender whitelist check behavior:
Handling accounts poll every 60 seconds. A dedicated AI agent reads each new email and decides how to handle it. The agent has access to:
memory_<username>.md (persistent notes) and reasoning_<username>.md (append-only decision log) are injected into each run/keyword <reply> footer for easy follow-upBoth Telegram and email inbox use the same trigger-matching algorithm:
URGENT matches urgentdaily report matches "Send me the report for the daily standup" but also "Daily summary report please"